如何获取显示的IKImageBrowserView的NSBitmapImageRep?

时间:2012-03-31 02:21:57

标签: cocoa ikimagebrowserview nsbitmapimagerep

我有一个双窗格 NSSplitView ,其中一个子视图是 IKImageBrowserView 。在使用 CATransition 为NSSplitView设置动画之前,我需要捕获它的位图以进行交换。

使用cacheDisplayInRect不会捕获 IKImageBrowserView 内容,但会捕获其他窗格的内容。我认为这可能与 IKImageBrowserView 拥有自己的图层树有关。

有人可以确认这是真的吗?

NSBitmapImageRep *imageRep = [self.imagesSplitView bitmapImageRepForCachingDisplayInRect:visibleRect];
        [self.imagesSplitView cacheDisplayInRect:visibleRect toBitmapImageRep:rep];
        NSImage *tempImage = [[NSImage alloc] initWithCGImage:[imageRep CGImage] size:visibleRect.size];
        [self.tempView setImage:tempImage];
        [self.holdingView replaceSubview:self.imagesSplitView with:self.tempView];

有关于如何获取视图内容的位图副本的任何建议吗?

renderInContext不会帮助我,我不这么认为,因为 IKImageBrowserView 没有显示引用其presentationLayer的方法 - 如果它甚至有一个。

我认为 ImageKit CALayers / CAOpenGLLayers 炼金术的组合。

感谢。

1 个答案:

答案 0 :(得分:0)

此处未收到任何确认,且无法使用cacheDisplayInRect方法;我发现使用Quartz Window Services API有效。

似乎使用replaceSubView需要延迟,所以我用一个块做了这个并且成功捕获了位图。

这是适合我的代码,以防其他人:

NSScrollView *sc = [self.browserView enclosingScrollView]; // i need the scrollView in the image
NSRect viewRect = [sc visibleRect];
NSRect transRect = [[self.window contentView] convertRect:viewRect fromView:sc];

CGWindowID windowID = (CGWindowID)[self.window windowNumber];
CGWindowListOption singleWindowOptions = kCGWindowListOptionIncludingWindow;
CGImageRef windowImage = CGWindowListCreateImage( CGRectNull, singleWindowOptions, windowID, kCGWindowImageBoundsIgnoreFraming);
CGImageRef viewImage = CGImageCreateWithImageInRect(windowImage, NSRectToCGRect(transRect));
NSBitmapImageRep *bitMapRep = [[NSBitmapImageRep alloc] initWithCGImage:viewImage];
NSImage *image = [[NSImage alloc] init];
[image addRepresentation:bitMapRep];
NSImageView *iv = [[NSImageView alloc] initWithFrame:transRect]; 
[iv setImage: image];

double delayInSeconds = 0.01;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC);
dispatch_after(popTime, dispatch_get_main_queue(), ^(void) {

    [[self.window contentView] replaceSubview:sc with:iv];
    });