我正在尝试实时显示来自相机的 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 调用,我看到了输出)
- 我知道我正确设置了 IBOutlet 声明。如果我使用上面的注释代码从 web 加载任意图像而不是简单地发送
setImage:theImage
到 imageView,则图像被正确加载(并且对 NSLog 的第二次调用报告了一个非 nil 对象)。 - 至少在基本范围内,我得到的图像
imageFromSampleBuffer:
很好,因为 NSLog 报告的大小为 360x480,这是我预期的大小。
我正在使用的代码是AVFoundation
Apple 最近发布的代码片段,可在此处获得。
特别是,我使用的代码设置了AVCaptureSession
对象和朋友(我对此知之甚少),并从核心视频缓冲区创建 UIImage 对象(这就是imageFromSampleBuffer
方法)。
最后,如果我尝试使用返回的 by发送drawInRect:
到普通的 UIView 子类,我可以让应用程序崩溃,而如果我使用上述 URL 中的一个,它不会崩溃。这是崩溃内部调试器的堆栈跟踪(我得到一个 EXC_BAD_ACCESS 信号):UIImage
imageFromSamplerBuffer
UIImage
#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:
有 size 691208 = 360*480*4 + 8
,因此像素数据中有 8 个额外的字节。CVPixelBufferGetDataSize
本身返回这个off-by-8 值。我想了一会儿,这可能是由于在内存中对齐的位置分配缓冲区,但 691200 是 256 的倍数,所以这也不能解释。这种大小差异是我能分辨出的两个 UIImage 之间的唯一区别,它可能会导致麻烦。尽管如此,没有理由为缓冲区分配额外的内存会导致 EXC_BAD_ACCESS 违规。
非常感谢您的帮助,如果您需要更多信息,请告诉我。