我正在尝试将 YUV 图像转换为 CIIMage 并最终转换为 UIImage。我在这些方面相当新手,并试图找出一种简单的方法来做到这一点。据我所知,从 iOS6 YUV 可以直接用于创建 CIImage 但是当我试图创建它时,CIImage 只持有一个 nil 值。我的代码是这样的 ->
NSLog(@"Started DrawVideoFrame\n");
CVPixelBufferRef pixelBuffer = NULL;
CVReturn ret = CVPixelBufferCreateWithBytes(
kCFAllocatorDefault, iWidth, iHeight, kCVPixelFormatType_420YpCbCr8BiPlanarFullRange,
lpData, bytesPerRow, 0, 0, 0, &pixelBuffer
);
if(ret != kCVReturnSuccess)
{
NSLog(@"CVPixelBufferRelease Failed");
CVPixelBufferRelease(pixelBuffer);
}
NSDictionary *opt = @{ (id)kCVPixelBufferPixelFormatTypeKey :
@(kCVPixelFormatType_420YpCbCr8BiPlanarFullRange) };
CIImage *cimage = [CIImage imageWithCVPixelBuffer:pixelBuffer options:opt];
NSLog(@"CURRENT CIImage -> %p\n", cimage);
UIImage *image = [UIImage imageWithCIImage:cimage scale:1.0 orientation:UIImageOrientationUp];
NSLog(@"CURRENT UIImage -> %p\n", image);
这里的lpData是YUV数据,是一个无符号字符数组。
这看起来也很有趣:vImageMatrixMultiply,找不到关于此的任何示例。谁能帮我解决这个问题?
最佳答案
我也遇到过类似的问题。我试图在屏幕上显示 YUV(NV12) 格式的数据。该解决方案在我的项目中有效...
//YUV(NV12)-->CIImage--->UIImage Conversion
NSDictionary *pixelAttributes = @{kCVPixelBufferIOSurfacePropertiesKey : @{}};
CVPixelBufferRef pixelBuffer = NULL;
CVReturn result = CVPixelBufferCreate(kCFAllocatorDefault,
640,
480,
kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange,
(__bridge CFDictionaryRef)(pixelAttributes),
&pixelBuffer);
CVPixelBufferLockBaseAddress(pixelBuffer,0);
unsigned char *yDestPlane = CVPixelBufferGetBaseAddressOfPlane(pixelBuffer, 0);
// Here y_ch0 is Y-Plane of YUV(NV12) data.
memcpy(yDestPlane, y_ch0, 640 * 480);
unsigned char *uvDestPlane = CVPixelBufferGetBaseAddressOfPlane(pixelBuffer, 1);
// Here y_ch1 is UV-Plane of YUV(NV12) data.
memcpy(uvDestPlane, y_ch1, 640*480/2);
CVPixelBufferUnlockBaseAddress(pixelBuffer, 0);
if (result != kCVReturnSuccess) {
NSLog(@"Unable to create cvpixelbuffer %d", result);
}
// CIImage Conversion
CIImage *coreImage = [CIImage imageWithCVPixelBuffer:pixelBuffer];
CIContext *MytemporaryContext = [CIContext contextWithOptions:nil];
CGImageRef MyvideoImage = [MytemporaryContext createCGImage:coreImage
fromRect:CGRectMake(0, 0, 640, 480)];
// UIImage Conversion
UIImage *Mynnnimage = [[UIImage alloc] initWithCGImage:MyvideoImage
scale:1.0
orientation:UIImageOrientationRight];
CVPixelBufferRelease(pixelBuffer);
CGImageRelease(MyvideoImage);
这里我展示了 YUV(NV12) 数据的数据结构,以及我们如何获得用于创建 CVPixelBufferRef 的 Y-Plane(y_ch0) 和 UV-Plane(y_ch1)。让我们看看 YUV(NV12) 数据结构.. 如果我们看一下图片,我们可以得到以下有关 YUV(NV12) 的信息,
- 总框架大小 = 宽度 * 高度 * 3/2,
- Y 平面大小 = 帧大小 * 2/3,
- UV-Plane size = Frame Size * 1/3,
- 数据存储在 Y 平面 -->{Y1, Y2, Y3, Y4, Y5.....}.
- U 平面-->(U1、V1、U2、V2、U3、V3、……}。
希望对大家有所帮助。 :) 享受 IOS 开发的乐趣 :D
关于ios - 如何从 YUV 转换为 CIImage for iOS,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25659671/