我正在尝试实时显示来自相机的UIImage,但似乎我的UIImageView不能正确地显示图像。这是AVCaptureVideoDataOutputSampleBufferDelegate
必须实现的方法。
- (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];
}
为了先解决简单的问题:
- 使用UIImagePickerController不是一个选项(最终我们将实际处理图像)
- 我知道处理程序被调用了(NSLog调用已经执行,我看到了输出)
- 如果我使用上述注释掉的代码从Web上加载任意图片而不是仅仅向imageView发送
setImage:theImage
,则可以正确加载该图片(并且第二次NSLog呈现非空对象)。 - 至少在基本层面上,我从
imageFromSampleBuffer:
获取的图像是好的,因为NSLog报告的尺寸为360x480,这是我预期的大小。
我正在使用最近发布的苹果AVFoundation
片段中的代码,可在此处获取。
特别地,这是我使用的设置AVCaptureSession
对象及其相关内容(我很少理解),并从Core Video缓冲区创建UIImage对象的代码(即imageFromSampleBuffer
方法)。
最后,如果我尝试使用从imageFromSamplerBuffer
返回的UIImage
向普通UIView子类发送drawInRect:
,应用程序会崩溃,而使用上面的URL中的UIImage
则不会崩溃。下面是来自调试器内崩溃的堆栈跟踪(我收到一个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:] ()
编辑:以下是关于那段代码返回的UIImage的更多信息。
使用这里描述的方法,我可以提取像素并将它们打印出来,在第一眼看起来它们看起来还好(例如,alpha通道中的每个值均为255)。然而,缓冲区大小似乎有些不对。我从那个URL获取的Flickr图像的大小为375x500,其[pixelData length]
给出750000 = 375*500*4
,这是期望的值。然而,从imageFromSampleBuffer:
返回的图像的像素数据大小为691208 = 360*480*4 + 8
,因此像素数据中有8个额外的字节。CVPixelBufferGetDataSize
本身也返回了这个少了8个字节的值。我曾经想过可能是在内存中分配缓冲区时采用了对齐位置,但是691200是256的倍数,所以这也无法解释。这种大小差异是我能够发现的仅有的两个UIImages之间的区别,并且它可能会引起问题。尽管如此,为缓冲区分配额外的内存不应该导致EXC_BAD_ACCESS违规。
非常感谢任何的帮助,如果您需要更多信息,请告诉我。