我正在使用一个 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
然而,当我使用这段代码时,核心动画层没有被渲染。
我研究了CARenderer
,因为它似乎可以做我需要的事情,但是我无法让它渲染我的现有层树。我尝试了以下方法:
NSOpenGLPixelFormatAttribute att[] =
{
NSOpenGLPFAWindow,
NSOpenGLPFADoubleBuffer,
NSOpenGLPFAColorSize, 24,
NSOpenGLPFAAlphaSize, 8,
NSOpenGLPFADepthSize, 24,
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 -- layer <CALayer: 0x1092ea0> is already attached to a context
我猜测这是因为图层树托管在我的NSView
中,因此已经附加到其上下文中。我不知道如何将图层树从NSView
中分离出来以便将其渲染到位图中,而且在这种情况下创建重复的图层树并不容易。
是否有其他方法可以使CALayer
渲染到位图中?实际上我找不到任何关于这样做的示例代码,事实上我找不到任何与CARenderer
相关的示例代码。
-renderInContext:
方法,而不是被CARenderer
误导。 - Rob Keniger