tab launchscreen icon bar apple app iphone uiimage

iphone - launchscreen - cómo convertir un CVImageBufferRef a UIImage



splash screen ios (4)

Benjamin Loulier escribió una muy buena publicación sobre la salida de un CVImageBufferRef bajo la consideración de la velocidad con múltiples enfoques.

También puede encontrar un ejemplo de trabajo en github;)

¿Qué hay de vuelta en el tiempo? ;) Aquí tienes: http://web.archive.org/web/20140426162537/http://www.benjaminloulier.com/posts/ios4-and-direct-access-to-the-camera

Estoy tratando de capturar el video de una cámara. He obtenido la captureOutput:didOutputSampleBuffer: devolución de llamada para activar y me da un búfer de muestra que luego convierto a un CVImageBufferRef . Luego intento convertir esa imagen a un UIImage que luego puedo ver en mi aplicación.

- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection { CVImageBufferRef imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer); /*Lock the image buffer*/ CVPixelBufferLockBaseAddress(imageBuffer,0); /*Get information about the image*/ uint8_t *baseAddress = (uint8_t *)CVPixelBufferGetBaseAddress(imageBuffer); size_t bytesPerRow = CVPixelBufferGetBytesPerRow(imageBuffer); size_t width = CVPixelBufferGetWidth(imageBuffer); size_t height = CVPixelBufferGetHeight(imageBuffer); /*We unlock the image buffer*/ CVPixelBufferUnlockBaseAddress(imageBuffer,0); /*Create a CGImageRef from the CVImageBufferRef*/ CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); CGContextRef newContext = CGBitmapContextCreate(baseAddress, width, height, 8, bytesPerRow, colorSpace, kCGBitmapByteOrder32Little | kCGImageAlphaPremultipliedFirst); CGImageRef newImage = CGBitmapContextCreateImage(newContext); /*We release some components*/ CGContextRelease(newContext); CGColorSpaceRelease(colorSpace); /*We display the result on the custom layer*/ /*self.customLayer.contents = (id) newImage;*/ /*We display the result on the image view (We need to change the orientation of the image so that the video is displayed correctly)*/ UIImage *image= [UIImage imageWithCGImage:newImage scale:1.0 orientation:UIImageOrientationRight]; self.capturedView.image = image; /*We relase the CGImageRef*/ CGImageRelease(newImage); }

El código parece funcionar bien hasta la llamada a CGBitmapContextCreate . siempre devuelve un puntero NULL . por lo tanto, en consecuencia, ninguna de las demás funciones funciona. No importa lo que parezca que lo pase, la función devuelve null. no tengo ni idea de porqué.


La forma en que está transmitiendo en baseAddress supone que los datos de imagen están en el formulario

ACCC

(donde C es un componente de color, R || G || B).

Si ha configurado su AVCaptureSession para capturar los cuadros de video en formato nativo, lo más probable es que esté recuperando los datos de video en formato YUV420 planar. (ver: texto del enlace ) Para hacer lo que está intentando hacer aquí, probablemente lo más fácil sería especificar que desea que los cuadros de video se capturen en kCVPixelFormatType_32RGBA. Apple recomienda que capture los cuadros de video en kCVPixelFormatType_32BGRA si lo captura en un formato no plano en absoluto, el razonamiento no se indica, pero puedo suponer razonablemente que se debe a consideraciones de rendimiento.

Advertencia: no he hecho esto y supongo que acceder a los contenidos de CVPixelBufferRef de esta manera es una forma razonable de crear la imagen. No puedo garantizar que esto realmente funcione, pero puedo / puedo / decirle que la forma en que está haciendo las cosas en este momento no funcionará de manera confiable debido al formato de píxeles que (probablemente) está capturando los cuadros de video.


Puede llamar directamente:

self.yourImageView.image=[[UIImage alloc] initWithCIImage:[CIImage imageWithCVPixelBuffer:imageBuffer]];


Si simplemente necesita convertir un CVImageBufferRef a UIImage, parece ser mucho más difícil de lo que debería ser. Esencialmente necesita convertir a CIImage, luego CGImage, THEN UIImage. Ojalá pudiera decirte por qué. Quién sabe.

-(void) screenshotOfVideoStream:(CVImageBufferRef)imageBuffer { CIImage *ciImage = [CIImage imageWithCVPixelBuffer:imageBuffer]; CIContext *temporaryContext = [CIContext contextWithOptions:nil]; CGImageRef videoImage = [temporaryContext createCGImage:ciImage fromRect:CGRectMake(0, 0, CVPixelBufferGetWidth(imageBuffer), CVPixelBufferGetHeight(imageBuffer))]; UIImage *image = [[UIImage alloc] initWithCGImage:videoImage]; [self doSomethingWithOurUIImage:image]; CGImageRelease(videoImage); }

Este método en particular me funcionó cuando estaba convirtiendo el video H.264 usando la devolución de llamada VTDecompressionSession para obtener el CVImageBufferRef (pero debería funcionar para cualquier CVImageBufferRef). Yo estaba usando iOS 8.1, XCode 6.2.