YUV转JPEG iOS

4
我希望能将iOS中从相机直接捕获的yuv 420SP格式图像(YCbCr格式)转换为jpg。我找到了CGImageCreate()函数 https://developer.apple.com/library/mac/documentation/graphicsimaging/reference/CGImage/Reference/reference.html#//apple_ref/doc/uid/TP30000956-CH1g-F17167,该函数需要一些参数,包括包含字节数组的输入,并应返回一些CGImage,当UIImage输入UIImageJPEGRepresentation()时,它会返回jpeg数据,但实际上并没有发生。
输出的图像数据与所需的差距很大。至少输出不是nil。
作为CGImageCreate()的输入,我将每个组件的位数设置为4,每像素的位数设置为12,并使用一些默认值。
它真的可以将yuv YCbCr图像转换为rgb吗?如果是的话,那么我认为在传递给CGImageCreate()函数的输入值中出现了问题。

找同样的东西。你有运气吗? - Evol Gate
没有运气。我得到的结果是这样的: 默认编码器即CGImageCreate()只能用于将RGBA(交错,quartz不支持平面)格式的图像转换为JPEG。我在文档中读到过一个表格,其中列出了所有可能的位数、每个组件的位数等值。所有这些值(可能是全部,因为我记不清了)都对应于RGBA。没有一个对应于yuv,这一点我很确定。 - neeraj
2个回答

0
这是将由AVVideoDataOutputcaptureOutput:didOutputSampleBuffer:fromConnection方法返回的示例缓冲区转换为代码的方法:
- (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)}];

0

从我所看到的这里, CGColorSpaceRef colorspace参数只能引用RGB、CMYK或灰度。

因此,我认为首先您需要将您的YCbCr420图像转换为RGB,例如使用IPP函数YCbCr420toRGB(doc)。或者,您可以编写自己的转换程序,这并不难。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接