2013-10-11 40 views
7

Pracuję z AVCaptureVideoDataOutput i chcę przekonwertować CMSampleBufferRef na UIImage. Wiele odpowiedzi są takie same, jak ten UIImage created from CMSampleBufferRef not displayed in UIImageView? i AVCaptureSession with multiple previewsKonwertuj CMSampleBufferRef na UIImage z przestrzenią kolorów YUV?

To działa dobrze, jeśli mogę ustawić VideoDataOutput przestrzeń kolorów do BGRA (dobro tej odpowiedzi CGBitmapContextCreateImage error)

NSString* key = (NSString*)kCVPixelBufferPixelFormatTypeKey; 
NSNumber* value = [NSNumber numberWithUnsignedInt:kCVPixelFormatType_32BGRA]; 
NSDictionary* videoSettings = [NSDictionary dictionaryWithObject:value forKey:key]; 
[dataOutput setVideoSettings:videoSettings]; 

bez powyższych videoSettings będę otrzymać następujące błędy

CGBitmapContextCreate: invalid data bytes/row: should be at least 2560 for 8 integer bits/component, 3 components, kCGImageAlphaPremultipliedFirst. 
<Error>: CGBitmapContextCreateImage: invalid context 0x0 

Praca z BGRA nie jest dobrym wyborem, ponieważ nie ma nad głową konwersja z YUV (domyślna przestrzeń kolorów AVCaptureSession) do BGRA, jak stwierdził Brad i Codo í n How to get the Y component from CMSampleBuffer resulted from the AVCaptureSession?

Więc czy istnieje sposób przekonwertowania CMSampleBufferRef na UIImage i pracę z przestrzenią kolorów YUV?

+0

Każde rozwiązanie tego problemu? –

+0

@AdarshVC dlaczego nie zagłosujesz na pytanie, aby uczynić je bardziej zauważalnym? – onmyway133

+0

sprawdź to pytanie http://stackoverflow.com/questions/3305862/uiimage-created-from-cmsamplebuffreref-niewyświetlane-w-imageview –

Odpowiedz

7

Po wykonaniu wielu badań i przeczytaniu dokumentacji Apple i wikipedis. Wyjaśniałem odpowiedź i działa to idealnie dla mnie. Więc dla przyszłych czytelników Im dzielenie kodu do konwertowania CMSampleBufferRef do UIImage gdy typ pikseli wideo jest ustawiony jako kCVPixelFormatType_420YpCbCr8BiPlanarFullRange

// Create a UIImage from sample buffer data 
// Works only if pixel format is kCVPixelFormatType_420YpCbCr8BiPlanarFullRange 
-(UIImage *) imageFromSamplePlanerPixelBuffer:(CMSampleBufferRef) sampleBuffer{ 

    @autoreleasepool { 
     // Get a CMSampleBuffer's Core Video image buffer for the media data 
     CVImageBufferRef imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer); 
     // Lock the base address of the pixel buffer 
     CVPixelBufferLockBaseAddress(imageBuffer, 0); 

     // Get the number of bytes per row for the plane pixel buffer 
     void *baseAddress = CVPixelBufferGetBaseAddressOfPlane(imageBuffer, 0); 

     // Get the number of bytes per row for the plane pixel buffer 
     size_t bytesPerRow = CVPixelBufferGetBytesPerRowOfPlane(imageBuffer,0); 
     // Get the pixel buffer width and height 
     size_t width = CVPixelBufferGetWidth(imageBuffer); 
     size_t height = CVPixelBufferGetHeight(imageBuffer); 

     // Create a device-dependent gray color space 
     CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceGray(); 

     // Create a bitmap graphics context with the sample buffer data 
     CGContextRef context = CGBitmapContextCreate(baseAddress, width, height, 8, 
                bytesPerRow, colorSpace, kCGImageAlphaNone); 
     // Create a Quartz image from the pixel data in the bitmap graphics context 
     CGImageRef quartzImage = CGBitmapContextCreateImage(context); 
     // Unlock the pixel buffer 
     CVPixelBufferUnlockBaseAddress(imageBuffer,0); 

     // Free up the context and color space 
     CGContextRelease(context); 
     CGColorSpaceRelease(colorSpace); 

     // Create an image object from the Quartz image 
     UIImage *image = [UIImage imageWithCGImage:quartzImage]; 

     // Release the Quartz image 
     CGImageRelease(quartzImage); 

     return (image); 
    } 
} 
+0

Zwróć uwagę, że obraz wyjściowy będzie w skali szarości. – Bluewings

+0

co z innymi kolorami? – JULIIncognito

+0

@JULIIncognito chnage przestrzeń kolorów do rgb – Bluewings