【发布时间】:2011-03-19 08:45:04
【问题描述】:
我正在尝试实时显示来自相机的 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,这是我预期的大小。
我使用的代码是 Apple 最近发布的AVFoundation sn-p 可用的here。
特别是,我使用的代码设置了AVCaptureSession 对象和朋友(我对此了解甚少),并从核心视频缓冲区创建 UIImage 对象(即imageFromSampleBuffer 方法)。
最后,如果我尝试将drawInRect: 发送到带有UIImage 由imageFromSamplerBuffer 返回的普通 UIView 子类,我可以让应用程序崩溃,而如果我使用来自的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 的更多信息。
使用here 描述的方法,我可以得到像素并打印它们,它们乍一看还不错(例如,Alpha 通道中的每个值都是 255)。但是,缓冲区大小略有不同。我从该 URL 从 Flickr 获得的图像是 375x500,它的[pixelData length] 给了我750000 = 375*500*4,这是预期值。但是,从imageFromSampleBuffer: 返回的图像的像素数据大小为691208 = 360*480*4 + 8,因此像素数据中有8 个额外的字节。 CVPixelBufferGetDataSize 本身返回这个 off-by-8 值。我想了一会儿,这可能是由于在内存中对齐的位置分配缓冲区,但 691200 是 256 的倍数,所以这也不能解释。这种大小差异是我能分辨出的两个 UIImage 之间的唯一区别,它可能会导致麻烦。尽管如此,没有理由为缓冲区分配 额外 内存会导致 EXC_BAD_ACCESS 违规。
非常感谢您的帮助,如果您需要更多信息,请告诉我。
【问题讨论】:
-
我遇到了同样的问题。令人恼火的是,是苹果自己为我们提供了自定义的“imageFromSampleBuffer”功能。
-
更奇怪的是,图片内容本身是正确的。我正在通过套接字将原始像素推送到另一台机器,它正是以正确格式从相机捕获的视频帧。
标签: iphone uiimageview uiimage ios4 avfoundation