2012-08-03 21 views
6

C'è un modo per acquisire CAEmitterCells (generato utilizzando un CAEmitterLayer) quando si cattura lo schermo del dispositivo ios?
UIGetScreenImage() funziona, ma poiché è un metodo privato non mi è consentito utilizzarlo.
UIGraphicsBeginImageContext non sembra funzionare, le particelle vengono semplicemente omesse dall'immagine risultante.iOS: acquisizione di particelle CAEmitterLayer sullo schermo

MODIFICA: Ecco il codice che sto attualmente utilizzando per acquisire la vista. In realtà sto registrando un video di 30 secondi sullo schermo, usando il codice fornito da aroth allo here. Funziona registrando 25 immagini di se stesso (è una sottoclasse UIView) e le sue sottoview (nel nostro caso include UIView il cui layer è CAEmitterLayer) al secondo e utilizza AVAssetWriter per comporre la registrazione.
È piuttosto un boccone, quindi inserirò solo le righe pertinenti qui: Ho ARC-ed il codice utilizzando lo strumento ARC in XCode, quindi il codice potrebbe essere un po 'diverso gestione della memoria saggio.

- (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]; 
} 

Spero davvero che questo aiuti. Grazie per il vostro sostegno!

+0

BTW - puoi passare NULL per il parametro __data__ di 'CGBitmapContextCreate()', nel qual caso i dati verranno allocati/dealloc'd automaticamente da CG – nielsbot

+0

inoltre, non vedo il tuo codice di rendering in questo frammento? – nielsbot

+0

Sei riuscito a risolvere questo problema? –

risposta

0

Hai provato a utilizzare -[CALayer renderInContext:]?

+0

Penso che voglia l'intera immagine dello schermo. Ah, quindi forse intendi rendere la vista che vuole (che probabilmente contiene CAEmitterLayer). Sembra promettente. –

+0

@DavidH esattamente ... – nielsbot

+0

a pensarci meglio, 'UIWindow' è anche un' UIView', e quindi ha un livello di supporto - potresti renderlo forse. – nielsbot