4

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、これに関する例は見つかりません。誰でもこれで私を助けることができますか?

4

2 に答える 2

5

私もこの同様の問題に直面しました。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 プレーン サイズ = フレーム サイズ * 1/3、
  • Y平面に格納されたデータ -->{Y1, Y2, Y3, Y4, Y5.....}.
  • U平面-->(U1、V1、U2、V2、U3、V3、......}.

それがすべての人に役立つことを願っています。:) IOS開発を楽しんでください:D

于 2015-10-17T12:04:13.300 に答える