Sto utilizzando uno NSView
per ospitare diversi oggetti Core Animation CALayer
. Quello che voglio essere in grado di fare è catturare un'istantanea dello stato attuale della vista come un'immagine bitmap.Come si esegue il rendering di una vista che contiene i livelli dell'anima core in una bitmap?
Questo è relativamente semplice, con una normale NSView
utilizzando qualcosa di simile:
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
Tuttavia, quando uso questo codice, gli strati Core Animation non sono resi.
Ho studiato CARenderer
, poiché sembra che faccia ciò di cui ho bisogno, tuttavia non riesco a ottenere il rendering del mio albero di livelli esistente. Ho provato quanto segue:
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]];
Tuttavia, quando faccio questo ottengo un'eccezione:
CAContextInvalidLayer -- layer <CALayer: 0x1092ea0> is already attached to a context
Sto indovinando che questo deve essere perché l'albero strato è ospitato nel mio NSView
e quindi attaccato al suo contesto. Non capisco come posso staccare l'albero dei livelli dallo NSView
per renderlo in una bitmap, ed in questo caso non è banale creare un albero dei livelli duplicato.
C'è un altro modo per ottenere il CALayer
s per il rendering in un bitmap? Non riesco a trovare alcun codice di esempio da nessuna parte per fare questo, in effetti non riesco a trovare alcun codice di esempio per CARenderer
affatto.
Mille grazie, questo è esattamente ciò di cui avevo bisogno e funziona perfettamente. Vorrei aver notato il metodo '-renderInContext:' prima, 'CARenderer' mi ha guidato lungo il sentiero del giardino. –
Questo lavoro per gli elementi è offscreen? Per esempio. il mio CALayer contiene alcuni elementi che non sono ancora nella cornice della vista, ma ho bisogno di scorrere per vederli. – Tudorizer
Qualcuno ha ottenuto che funzioni con un'animazione iniziata con [UIView animateWithDuration: ...]? Non ha funzionato per me. – Isak