我正在使用NSView托管几个Core Animation CALayer对象.我想要做的是将视图的当前状态的快照作为位图图像.
这是相对简单的一个正常的NSView使用这样的东西:
void ClearBitmapImageRep(NSBitmapImageRep* bitmap) { unsigned char* bitmapData = [bitmap bitmapData]; if (bitmapData != NULL) bzero(bitmapData,[bitmap bytesPerRow] * [bitmap pixelsHigh]); } @implementation NSView (Additions) - (NSBitmapImageRep*)bitmapImageRepInRect:(NSRect)rect { NSBitmapImageRep* imageRep = [self bitmapImageRepForCachingDisplayInRect:rect]; ClearBitmapImageRep(imageRep); [self cacheDisplayInRect:rect toBitmapImageRep:imageRep]; return imageRep; } @end
但是,当我使用这个代码时,Core Animation层没有渲染.
我已经调查了CARenderer,因为它似乎是我需要的,但是我无法得到它来渲染我现有的图层树.我试过以下:
NSOpenGLPixelFormatAttribute att[] = { NSOpenGLPFAWindow,NSOpenGLPFADoubleBuffer,NSOpenGLPFAColorSize,24,NSOpenGLPFAAlphaSize,8,NSOpenGLPFADepthSize,NSOpenGLPFANoRecovery,NSOpenGLPFAAccelerated,0 }; NSOpenGLPixelFormat *pixelFormat = [[NSOpenGLPixelFormat alloc] initWithAttributes:att]; NSOpenGLView* openGLView = [[NSOpenGLView alloc] initWithFrame:[self frame] pixelFormat:pixelFormat]; NSOpenGLContext* oglctx = [openGLView openGLContext]; CARenderer* renderer = [CARenderer rendererWithCGLContext:[oglctx CGLContextObj] options:nil]; renderer.layer = myContentLayer; [renderer render]; NSBitmapImageRep* bitmap = [oglView bitmapImageRepInRect:[oglView bounds]];
但是,当我这样做我会得到一个例外:
CAContextInvalidLayer – 层< CALayer:0x1092ea0>已经附加到上下文中
我猜这是因为层树托管在我的NSView中,因此附加到它的上下文.我不明白如何从NSView中分离图层树,以便将其渲染为位图,在这种情况下,创建一个重复的图层树是不平凡的.
有没有其他方法可以让CALayers渲染到一个位图?我在任何地方找不到任何示例代码,实际上我找不到任何CARenderer的示例代码.
解决方法
关于录制核心动画的“Cocoa是我的女朋友”有一个很棒的帖子.作者将整个动画捕获到一部电影中,但您可以使用他抓住单个框架的部分.
跳转到本文中的“获取当前帧”部分:
http://www.cimgf.com/2009/02/03/record-your-core-animation-animation/
跳转到本文中的“获取当前帧”部分:
http://www.cimgf.com/2009/02/03/record-your-core-animation-animation/
基本思路是:
>创建一个CGContext
>使用CALayer’s renderInContext:
>从中创建NSBitmapImageRep
上下文(使用)
CGBitmapContextCreateImage和
NSBitmapImageRep的initWithCGImage)
更新:
我刚刚看到,renderInContext:方法不支持Mac OS X 10.5中的各种图层.
它不适用于以下图层类:
> QCCompositionLayer> CAOpenGLLayer> QTMovieLayer