Estoy tratando de mostrar un UIImage en tiempo real proveniente de la cámara, y parece que mi UIImageView no muestra la imagen correctamente. Este es el método que un AVCaptureVideoDataOutputSampleBufferDelegate
tiene que implementarUIImage creado a partir de CMSampleBufferRef no se muestra en UIImageView?
- (void)captureOutput:(AVCaptureOutput *)captureOutput
didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer
fromConnection:(AVCaptureConnection *)connection
{
// Create a UIImage from the sample buffer data
UIImage *theImage = [self imageFromSampleBuffer:sampleBuffer];
// NSLog(@"Got an image! %f %f", theImage.size.width, theImage.size.height);
// NSLog(@"The image view is %@", imageView);
// UIImage *theImage = [[UIImage alloc] initWithData:[NSData
// dataWithContentsOfURL:[NSURL
// URLWithString:@"http://farm4.static.flickr.com/3092/2915896504_a88b69c9de.jpg"]]];
[self.session stopRunning];
[imageView setImage: theImage];
}
Para obtener los problemas fáciles fuera del camino:
- Usando UIImagePickerController no es una opción (con el tiempo vamos a realmente hacer cosas con la imagen)
- Sé que se está llamando al controlador (las llamadas NSLog están hechas, y veo la salida)
- Sé que tengo las declaraciones IBOutlet configuradas correctamente. Si uso el código comentado de arriba para cargar una imagen arbitraria desde la web en lugar de simplemente enviar
setImage:theImage
a la imageView, la imagen se carga correctamente (y la segunda llamada a NSLog informa un objeto que no es nada). - Al menos en una medida básica, la imagen que recibo de
imageFromSampleBuffer:
está muy bien, ya que NSLog informa del tamaño que ser 360x480, que es el tamaño lo que esperaba.
El código que estoy usando es el publicado recientemente AVFoundation
fragmento de Apple disponibles here.
En particular, ese es el código que uso que configura el objeto y amigos AVCaptureSession
(del cual entiendo muy poco), y crea el objeto UIImage de los almacenamientos intermedios de Core Video (ese es el método imageFromSampleBuffer
).
Por último, puedo conseguir la aplicación se bloquee si intento enviar drawInRect:
a una subclase UIView llano con el UIImage
devuelto por imageFromSamplerBuffer
, mientras que no se cuelga si uso un UIImage
desde una dirección URL que el anterior. Aquí está el seguimiento de la pila desde el depurador en el interior del accidente (me da una señal EXC_BAD_ACCESS):
#0 0x34a977ee in decode_swap()
#1 0x34a8f80e in decode_data()
#2 0x34a8f674 in img_decode_read()
#3 0x34a8a76e in img_interpolate_read()
#4 0x34a63b46 in img_data_lock()
#5 0x34a62302 in CGSImageDataLock()
#6 0x351ab812 in ripc_AcquireImage()
#7 0x351a8f28 in ripc_DrawImage()
#8 0x34a620f6 in CGContextDelegateDrawImage()
#9 0x34a61fb4 in CGContextDrawImage()
#10 0x321fd0d0 in -[UIImage drawInRect:blendMode:alpha:]()
#11 0x321fcc38 in -[UIImage drawInRect:]()
EDIT: Aquí hay más información sobre el UIImage ser devuelto por ese trozo de código.
Usando el método descrito here, puedo llegar a los píxeles e imprimirlos, y se ven bien a primera vista (cada valor en el canal alfa es 255, por ejemplo). Sin embargo, hay algo levemente apagado con los tamaños de buffer. La imagen que obtengo de Flickr de esa URL es 375x500, y su [pixelData length]
me da 750000 = 375*500*4
, que es el valor esperado. Sin embargo, los datos de píxeles de la imagen devuelta desde imageFromSampleBuffer:
tienen el tamaño 691208 = 360*480*4 + 8
, por lo que hay 8 bytes adicionales en los datos de píxeles. CVPixelBufferGetDataSize
en sí mismo devuelve este valor off-by-8. Pensé por un momento que podría deberse a la asignación de almacenamientos intermedios en posiciones alineadas en la memoria, pero 691200 es un múltiplo de 256, por lo que tampoco lo explica. Esta discrepancia de tamaño es la única diferencia que puedo decir entre los dos UIImages, y podría estar causando el problema. Aún así, no hay ninguna razón para asignar memoria adicional para que el almacenamiento intermedio cause una violación EXC_BAD_ACCESS.
Muchas gracias por cualquier ayuda, y quiero saber si necesita más información.
Tengo el mismo problema. Lo que es irritante es que fue la propia Apple que nos proporcionó la función personalizada "imageFromSampleBuffer". –
Aún más extraño, el contenido de la imagen en sí es correcto. Estoy empujando los píxeles brutos a través de un socket a una máquina diferente y son exactamente los cuadros de video capturados desde la cámara en el formato correcto. –