4

AVFoundationを使用してビデオを撮影し、kCVPixelFormatType_420YpCbCr8BiPlanarFullRangeフォーマットで録画しています。YpCbCrフォーマットのY平面から直接グレースケール画像を作成したい。

CGContextRefを呼び出して作成しようとしましCGBitmapContextCreateたが、問題は、選択する色空間とピクセル形式がわからないことです。

- (void)captureOutput:(AVCaptureOutput *)captureOutput 
didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer 
       fromConnection:(AVCaptureConnection *)connection 
{       
    CVImageBufferRef imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer); 
    CVPixelBufferLockBaseAddress(imageBuffer,0);        

    /* Get informations about the Y plane */
    uint8_t *YPlaneAddress = CVPixelBufferGetBaseAddressOfPlane(imageBuffer, 0);
    size_t bytesPerRow = CVPixelBufferGetBytesPerRowOfPlane(imageBuffer, 0);
    size_t width = CVPixelBufferGetWidthOfPlane(imageBuffer, 0);
    size_t height = CVPixelBufferGetHeightOfPlane(imageBuffer, 0);

    /* the problematic part of code */
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceGray();

    CGContextRef newContext = CGBitmapContextCreate(YPlaneAddress,
    width, height, 8, bytesPerRow, colorSpace, kCVPixelFormatType_1Monochrome);

    CGImageRef newImage = CGBitmapContextCreateImage(newContext); 
    UIImage *grayscaleImage = [[UIImage alloc] initWithCGImage:newImage];

    // process the grayscale image ... 
}

上記のコードを実行すると、次のエラーが発生しました。

<Error>: CGBitmapContextCreateImage: invalid context 0x0
<Error>: CGBitmapContextCreate: unsupported parameter combination: 8 integer bits/component; 16 bits/pixel; 1-component color space; kCGImageAlphaPremultipliedLast; 192 bytes/row.

PS:私の英語でごめんなさい。

4

1 に答える 1

2

私が間違っていなければ、経由するべきではありませんCGContext。代わりに、データ プロバイダーを作成してから、イメージを直接作成する必要があります。

コードのもう 1 つの間違いは、kCVPixelFormatType_1Monochrome定数の使用です。Core Graphics (CG ライブラリ) ではなく、ビデオ処理 (AV ライブラリ) で使用される定数です。を使用するだけkCGImageAlphaNoneです。ピクセルごとに 1 つのコンポーネント (グレー) が必要であること (RGB のように 3 つではなく) は、色空間から導き出されます。

次のようになります。

CGDataProviderRef  dataProvider = CGDataProviderCreateWithData(NULL, YPlaneAdress,
      height * bytesPerRow, NULL);
CGImageRef newImage = CGImageCreate(width, height, 8, 8, bytesPerRow,
      colorSpace, kCGImageAlphaNone, dataProvider, NULL, NO, kCGRenderingIntentDefault);
CGDataProviderRelease(dataProvider);
于 2012-04-15T17:54:22.067 に答える