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 数据,但这并没有真正发生输出图像数据与所需的数据相差甚远。至少输出不是零。

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

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

4

2 回答 2

0

从我在这里可以看到,该CGColorSpaceRef colorspace参数只能指 RGB、CMYK 或灰度。

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

于 2014-01-19T12:50:19.953 回答
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)}];
于 2018-01-10T20:10:43.807 回答