Я использую 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, 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
.