yuv到jpeg iOS

时间:2012-09-26 05:21:29

标签: ios image

我想将一个yuv 420SP图像(直接从相机,YCbCr格式捕获)转换为iOS中的jpg。我发现的是CGImageCreate()函数https://developer.apple.com/library/mac/documentation/graphicsimaging/reference/CGImage/Reference/reference.html#//apple_ref/doc/uid/TP30000956-CH1g-F17167,它接受​​一些参数,包括包含的字节数组,并且应该返回一些CGImage,当输入到UIImageJPEGRepresentation()时,其UIImage返回jpeg数据,但实际上并没有发生 输出图像数据远非所需。至少输出不是零。

作为CGImageCreate()的输入,我将每个组件的位设置为4,每像素位为12,以及一些默认值。

真的可以转换yuv YCbCr图片广告不仅仅是rgb吗?如果是,那么我认为我在CGImageCreate函数的输入值中做错了。

2 个答案:

答案 0 :(得分:0)

从我可以看到的hereCGColorSpaceRef colorspace参数只能引用RGB,CMYK或灰度。

所以我认为首先需要将YCbCr420图像转换为RGB,例如,使用IPP函数YCbCr420toRGBdoc)。或者,您可以编写自己的转换例程,但并不难。

答案 1 :(得分:0)

以下是转换captureOutput:didOutputSampleBuffer:fromConnection AVVideoDataOutput方法返回的样本缓冲区的代码:

- (void)captureOutput:(AVCaptureOutput *)output didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection
{
    CVPixelBufferRef pixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer);
    CVPixelBufferLockBaseAddress(pixelBuffer, 0);
    GLubyte *rawImageBytes = CVPixelBufferGetBaseAddress(pixelBuffer);
    size_t bytesPerRow = CVPixelBufferGetBytesPerRow(pixelBuffer); //2560 == (640 * 4)
    size_t bufferWidth = CVPixelBufferGetWidth(pixelBuffer);
    size_t bufferHeight = CVPixelBufferGetHeight(pixelBuffer);  //480
    size_t dataSize = CVPixelBufferGetDataSize(pixelBuffer); //1_228_808 = (2560 * 480) + 8
CGColorSpaceRef defaultRGBColorSpace = CGColorSpaceCreateDeviceRGB();


    CGContextRef context = CGBitmapContextCreate(rawImageBytes, bufferWidth, bufferHeight, 8, bytesPerRow, defaultRGBColorSpace, kCGBitmapByteOrder32Little | kCGImageAlphaPremultipliedFirst);
    CGImageRef image = CGBitmapContextCreateImage(context);

    CFMutableDataRef imageData = CFDataCreateMutable(NULL, 0);
    CGImageDestinationRef destination = CGImageDestinationCreateWithData(imageData, kUTTypeJPEG, 1, NULL);
    NSDictionary *properties = @{(__bridge id)kCGImageDestinationLossyCompressionQuality: @(0.25),
                                 (__bridge id)kCGImageDestinationBackgroundColor: (__bridge id)CLEAR_COLOR,
                                 (__bridge id)kCGImageDestinationOptimizeColorForSharing : @(TRUE)
                                 };
    CGImageDestinationAddImage(destination, image, (__bridge CFDictionaryRef)properties);

    if (!CGImageDestinationFinalize(destination))
    {
        CFRelease(imageData);
        imageData = NULL;
    }
    CFRelease(destination);

    UIImage *frame = [[UIImage alloc] initWithCGImage:image];
    CGContextRelease(context);
    CGImageRelease(image);

    renderFrame([self.childViewControllers.lastObject.view viewWithTag:1].layer, frame);

    CVPixelBufferUnlockBaseAddress(pixelBuffer, 0);
}

以下是像素格式类型的三个选项:

kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange
kCVPixelFormatType_420YpCbCr8BiPlanarFullRange
kCVPixelFormatType_32BGRA

如果_captureOutput是我的AVVideoDataOutput实例的指针引用,则设置像素格式类型的方式如下:

[_captureOutput setVideoSettings:@{(id)kCVPixelBufferPixelFormatTypeKey: @(kCVPixelFormatType_32BGRA)}];