2012-08-03 21 views
6

¿Hay alguna forma de capturar CAEmitterCells (generado mediante CAEmitterLayer) al capturar la pantalla del dispositivo ios?
UIGetScreenImage() funciona, pero dado que es un método privado, no tengo permiso para usarlo.
UIGraphicsBeginImageContext parece no funcionar, las partículas simplemente se omiten de la imagen resultante.iOS: capturando partículas CAEmitterLayer en la pantalla

EDITAR: Aquí está el código que estoy utilizando actualmente para capturar la vista. De hecho, estoy grabando un video de 30 segundos de la pantalla, usando el código proporcionado por aroth al here. Funciona registrando 25 imágenes de sí mismo (es una subclase UIView) y sus subvistas (en nuestro caso, incluida la UIView cuya capa es CAEmitterLayer) por segundo y utiliza AVAssetWriter para componer la grabación.

Es un buen bocado, así que simplemente coloque las líneas correspondientes aquí: I ARC-ed el código utilizando la herramienta ARC en XCode, por lo que el código podría ser un poco diferente gestión de memoria.

- (CGContextRef) createBitmapContextOfSize:(CGSize) size { 
    CGContextRef context = NULL; 
    CGColorSpaceRef colorSpace; 
    int    bitmapByteCount; 
    int    bitmapBytesPerRow; 

    bitmapBytesPerRow = (size.width * 4); 
    bitmapByteCount  = (bitmapBytesPerRow * size.height); 
    colorSpace = CGColorSpaceCreateDeviceRGB(); 
    if (bitmapData != NULL) { 
     free(bitmapData); 
    } 
    bitmapData = malloc(bitmapByteCount); 
    if (bitmapData == NULL) { 
     fprintf (stderr, "Memory not allocated!"); 
     return NULL; 
    } 

    context = CGBitmapContextCreate (bitmapData, 
            size.width, 
            size.height, 
            8,  // bits per component 
            bitmapBytesPerRow, 
            colorSpace, 
            kCGImageAlphaNoneSkipFirst); 

    CGContextSetAllowsAntialiasing(context,NO); 
    if (context== NULL) { 
     free (bitmapData); 
     fprintf (stderr, "Context not created!"); 
     return NULL; 
    } 
    CGColorSpaceRelease(colorSpace); 

    return context; 
} 

//static int frameCount = 0;   //debugging 
- (void) drawRect:(CGRect)rect { 
    NSDate* start = [NSDate date]; 
    CGContextRef context = [self createBitmapContextOfSize:self.frame.size]; 

    //not sure why this is necessary...image renders upside-down and mirrored 
    CGAffineTransform flipVertical = CGAffineTransformMake(1, 0, 0, -1, 0, self.frame.size.height); 
    CGContextConcatCTM(context, flipVertical); 

    [self.layer renderInContext:context]; 

    CGImageRef cgImage = CGBitmapContextCreateImage(context); 
    UIImage* background = [UIImage imageWithCGImage: cgImage]; 
    CGImageRelease(cgImage); 

    self.currentScreen = background; 

    //debugging 
    //if (frameCount < 40) { 
    //  NSString* filename = [NSString stringWithFormat:@"Documents/frame_%d.png", frameCount]; 
    //  NSString* pngPath = [NSHomeDirectory() stringByAppendingPathComponent:filename]; 
    //  [UIImagePNGRepresentation(self.currentScreen) writeToFile: pngPath atomically: YES]; 
    //  frameCount++; 
    //} 

    //NOTE: to record a scrollview while it is scrolling you need to implement your UIScrollViewDelegate such that it calls 
    //  'setNeedsDisplay' on the ScreenCaptureView. 
    if (_recording) { 
     float millisElapsed = [[NSDate date] timeIntervalSinceDate:startedAt] * 1000.0; 
     [self writeVideoFrameAtTime:CMTimeMake((int)millisElapsed, 1000)]; 
    } 

    float processingSeconds = [[NSDate date] timeIntervalSinceDate:start]; 
    float delayRemaining = (1.0/self.frameRate) - processingSeconds; 

    CGContextRelease(context); 

    //redraw at the specified framerate 
    [self performSelector:@selector(setNeedsDisplay) withObject:nil afterDelay:delayRemaining > 0.0 ? delayRemaining : 0.01]; 
} 

Realmente espero que esto ayude. ¡Gracias por su apoyo!

+0

BTW - puede pasar NULL para el parámetro __data__ de 'CGBitmapContextCreate()', en cuyo caso los datos serán asignados/tratados automáticamente por CG – nielsbot

+0

también, no veo su código de renderizado en este fragmento? – nielsbot

+0

¿Pudo resolver este problema? –

Respuesta

0

¿Intentaste usar -[CALayer renderInContext:]?

+0

Creo que quiere toda la imagen de la pantalla. Ah, entonces quizás quieras mostrar la vista que quiere (que probablemente contenga el CAEmitterLayer). Eso suena prometedor –

+0

@DavidH exactamente ... – nielsbot

+0

pensando aún más, 'UIWindow' también es un' UIView', y por lo tanto tiene una capa de respaldo, podrías renderizar eso tal vez. – nielsbot

Cuestiones relacionadas