objective-c - 如何将 CVImageBufferRef 转换为 UIImage

标签 objective-c iphone uiimage

我正在尝试从相机捕获视频。我已经获得了要触发的 captureOutput:didOutputSampleBuffer: 回调,它为我提供了一个示例缓冲区,然后我将其转换为 CVImageBufferRef。然后,我尝试将该图像转换为 UIImage,然后可以在我的应用程序中查看。

- (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);
}

在调用CGBitmapContextCreate之前,代码似乎工作正常。它总是返回一个NULL指针。因此,该函数的其余部分都不起作用。无论我似乎传递什么,该函数都会返回 null。我不知道为什么。

最佳答案

您传递 baseAddress 的方式假定图像数据采用以下形式

ACCC

(其中 C 是某个颜色分量,R || G || B )。

如果您已将 AVCaptureSession 设置为以 native 格式捕获视频帧,则您很可能会以平面 YUV420 格式获取视频数据。 (请参阅: link text )为了执行您在此处尝试执行的操作,可能最简单的方法是指定您希望在 kCVPixelFormatType_32RGBA 中捕获视频帧。如果您以非平面格式捕获视频帧,Apple 建议您以 kCVPixelFormatType_32BGRA 捕获视频帧,其原因未说明,但我可以合理地假设是出于性能考虑。

警告:我还没有这样做,并且假设像这样访问 CVPixelBufferRef 内容是构建图像的合理方法。我不能保证这实际上有效,但我/可以/告诉你,由于你(可能)捕获视频帧的像素格式,你现在做事的方式可靠地不会工作。

关于objective-c - 如何将 CVImageBufferRef 转换为 UIImage,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3152259/

相关文章:

ios - 关于UIScrollView的一些问题

iphone - UILocalNotification 应用角标(Badge)编号重复

iphone - 在视网膜和非视网膜屏幕上使用图像作为文本

ios - XCode 给我以下 "Apple Mach-O Linker"警告

ios - 如何为 UITableView 和 UISearchBar 创建透明背景

objective-c - 在 ARC 下,如何释放 NSArray 中的元素?

iphone - 如何在 iOS 中减少 "Live Bytes"?

ios - PayPalEnvironmentProduction 和 PayPalEnvironmentSandbox 失败

ios - 从 SQL 数据库保存和加载图像

iphone - 在 View 之间显示图像