8

で作業しており、に変換しAVCaptureVideoDataOutputたいと考えています。UIImageView に表示されない CMSampleBufferRef から作成されたこの UIImage のように、多くの答えは同じです。および複数のプレビューを含む AVCaptureSessionCMSampleBufferRefUIImage

VideoDataOutput 色空間を BGRA に設定すると正常に動作します (この回答CGBitmapContextCreateImage errorにクレジットされています) 。

NSString* key = (NSString*)kCVPixelBufferPixelFormatTypeKey;
NSNumber* value = [NSNumber numberWithUnsignedInt:kCVPixelFormatType_32BGRA];
NSDictionary* videoSettings = [NSDictionary dictionaryWithObject:value forKey:key];
[dataOutput setVideoSettings:videoSettings];

上記の videoSettings がないと、次のエラーが表示されます

CGBitmapContextCreate: invalid data bytes/row: should be at least 2560 for 8 integer bits/component, 3 components, kCGImageAlphaPremultipliedFirst.
<Error>: CGBitmapContextCreateImage: invalid context 0x0

Brad とCodo が AVCaptureSession に起因する CMSampleBuffer から Y コンポーネントを取得する方法で述べているように、YUV (デフォルトの AVCaptureSession 色空間) から BGRA への変換オーバーヘッドがあるため、BGRA での作業は適切な選択ではありません。

YUV色空間に変換CMSampleBufferRefして操作する方法はありますか?UIImage

4

2 に答える 2

9

多くの調査を行い、アップルのドキュメントとウィキペディスを読んだ後。私は答えを見つけ出し、それは私にとって完璧に機能します。したがって、将来の読者のために、ビデオピクセルタイプが次のように設定されている場合に変換CMSampleBufferRefするコードを共有していますUIImagekCVPixelFormatType_420YpCbCr8BiPlanarFullRange

// Create a UIImage from sample buffer data
// Works only if pixel format is kCVPixelFormatType_420YpCbCr8BiPlanarFullRange
-(UIImage *) imageFromSamplePlanerPixelBuffer:(CMSampleBufferRef) sampleBuffer{

    @autoreleasepool {
        // Get a CMSampleBuffer's Core Video image buffer for the media data
        CVImageBufferRef imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer);
        // Lock the base address of the pixel buffer
        CVPixelBufferLockBaseAddress(imageBuffer, 0);

        // Get the number of bytes per row for the plane pixel buffer
        void *baseAddress = CVPixelBufferGetBaseAddressOfPlane(imageBuffer, 0);

        // Get the number of bytes per row for the plane pixel buffer
        size_t bytesPerRow = CVPixelBufferGetBytesPerRowOfPlane(imageBuffer,0);
        // Get the pixel buffer width and height
        size_t width = CVPixelBufferGetWidth(imageBuffer);
        size_t height = CVPixelBufferGetHeight(imageBuffer);

        // Create a device-dependent gray color space
        CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceGray();

        // Create a bitmap graphics context with the sample buffer data
        CGContextRef context = CGBitmapContextCreate(baseAddress, width, height, 8,
                                                     bytesPerRow, colorSpace, kCGImageAlphaNone);
        // Create a Quartz image from the pixel data in the bitmap graphics context
        CGImageRef quartzImage = CGBitmapContextCreateImage(context);
        // Unlock the pixel buffer
        CVPixelBufferUnlockBaseAddress(imageBuffer,0);

        // Free up the context and color space
        CGContextRelease(context);
        CGColorSpaceRelease(colorSpace);

        // Create an image object from the Quartz image
        UIImage *image = [UIImage imageWithCGImage:quartzImage];

        // Release the Quartz image
        CGImageRelease(quartzImage);

        return (image);
    }
}
于 2015-05-08T09:24:31.783 に答える