2012-08-03 11 views
6

क्या आईओएस डिवाइस स्क्रीन को कैप्चर करते समय CAEmitterCells (CAEmitterLayer का उपयोग करके जेनरेट किया गया) कैप्चर करने का कोई तरीका है?
UIGetScreenImage() काम करता है, लेकिन चूंकि यह एक निजी विधि है जिसका उपयोग करने की अनुमति नहीं है।
UIGraphicsBeginImageContext काम नहीं कर रहा है, कणों को परिणामस्वरूप छवि से बस छोड़ा जाता है।आईओएस: स्क्रीन पर CAEmitterLayer कणों को कैप्चर करना

संपादित करें: यहां कोड है जिसे मैं वर्तमान में दृश्य को कैप्चर करने के लिए उपयोग कर रहा हूं। मैं वास्तव में here पर अरोथ द्वारा प्रदान किए गए कोड का उपयोग करके, स्क्रीन के 30-सेकंड-लंबे वीडियो को रिकॉर्ड कर रहा हूं। यह प्रति सेकंड की 25 छवियों (इसके एक यूआईवीव सबक्लास) और इसके सबव्यूज़ (हमारे मामले में UIView सहित, जिसका परत CAEmitterLayer है) रिकॉर्डिंग द्वारा काम करता है और रिकॉर्डिंग लिखने के लिए AVAssetWriter का उपयोग करता है।

यह काफी मुट्ठी भर है, इसलिए मैं यहां प्रासंगिक लाइनें रखूंगा: मैं एक्सकोड में एआरसी उपकरण का उपयोग कर कोड एआरसी-एड करता हूं, इसलिए कोड थोड़ा अलग स्मृति प्रबंधन के अनुसार हो सकता है।

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

वास्तव में उम्मीद है कि इससे मदद मिलती है। आपके समर्थन के लिए धन्यवाद!

+0

बीटीडब्ल्यू - आप 'CGBitmapContextCreate()' के __data__ परम के लिए NULL पास कर सकते हैं, इस मामले में डेटा को CG – nielsbot

+0

द्वारा स्वचालित रूप से आवंटित/dealloc'd किया जाएगा, मुझे आपका रेंडर कोड नहीं दिखाई देता है यह स्निपेट? – nielsbot

+0

क्या आप इस मुद्दे को हल करने में सक्षम थे? –

उत्तर

0

क्या आपने -[CALayer renderInContext:] का उपयोग करने का प्रयास किया था?

+0

मुझे लगता है कि वह पूरी स्क्रीन छवि चाहता है। आह, तो शायद आप उस दृष्टिकोण को प्रस्तुत करना चाहते हैं जो वह चाहता है (जिसमें शायद सीएइमिटरलेयर शामिल है)। यह वादा करता है। –

+0

@ डेविड एचडी ... – nielsbot

+0

इसके बारे में सोचते हुए, 'UIWindow' भी' UIView' है, और इसलिए बैकिंग लेयर है - आप शायद इसे प्रस्तुत कर सकते हैं। – nielsbot

संबंधित मुद्दे