ios - 如何从 YUV 转换为 CIImage for iOS

标签 ios image-processing uiimage yuv ciimage

我正在尝试将 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) 数据结构.. enter image description here 如果我们看一下图片,我们可以得到以下有关 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/

相关文章:

ios - 具有双向绑定(bind)的自定义 SwiftUI View

ios - 有没有办法在发生某些事情后停止 touches 方法?

ios - 构建基本应用程序 iOS 应用程序 - 单一 View - 最佳实践

python - 类型错误 : Image data can not convert to float

javascript - 如何将图像转换为缓冲区

iphone - 像 Instagram 一样的照片效果

objective-c - 为什么 NSURLConnection 的 currentRequest 在重定向后不指示正确的 URL?

c - RGB565 转灰度

iphone - 过期的 [UIImage imageNamed :] object?

ios4 - 正确发布UIImagePickerController