CGImageCreate中的颜色失真

时间:2012-03-29 07:25:00

标签: iphone objective-c image camera cgimage

我正在尝试为我的iOS应用程序构建一个图像捕获,但我的CGImage结果仍然会出现颜色失真。这是相机预览,正确的颜色。

enter image description here

可可是红色的,一切都很好。

当我运行快照代码时,我明白了:

enter image description here

可可是蓝色的......这是从哪里来的?

我尝试弄乱了一些参数,但最终却没有得到任何图像。这是我的快照代码:

int bitsPerComponent = 8;
    int bitsPerPixel = 32;
    int bytesPerRow = [cameraVideo bufRowBytes];
    CGDataProviderRef provider = CGDataProviderCreateWithData(NULL, [cameraVideo bufDataPtr], [cameraVideo bufWidth]*[cameraVideo bufHeight]*4, NULL);

    CGColorSpaceRef colorSpaceRef = CGColorSpaceCreateDeviceRGB();
    CGBitmapInfo bitmapInfo = kCGImageAlphaNoneSkipLast;
    CGColorRenderingIntent renderingIntent = kCGRenderingIntentPerceptual;

    CGImageRef imageRef = CGImageCreate( [cameraVideo bufWidth], [cameraVideo bufHeight], bitsPerComponent, bitsPerPixel,
                                        bytesPerRow, colorSpaceRef, bitmapInfo, provider, NULL, NO, renderingIntent);

    CGColorSpaceRelease(colorSpaceRef);

我在我的智慧结束,所以如果有人能看到我做错了什么,请告诉我。

固定

以下是最终代码:

if (cameraVideo.ARPixelFormat == kCVPixelFormatType_32ARGB) {
    bitmapInfo = kCGBitmapByteOrder32Big | kCGImageAlphaNoneSkipFirst;
} else {
    bitmapInfo = kCGBitmapByteOrder32Little | kCGImageAlphaNoneSkipFirst;
}

1 个答案:

答案 0 :(得分:12)

看起来您的R(红色)和B(蓝色)频道已被交换。相机以BGR顺序填充缓冲区,但您告诉CGImage数据是RGB顺序。我相信您可以使用kCGBitmapByteOrder...中的CGBitmapInfo个常量之一来控制它。尝试像这样设置bitmapInfo

CGBitmapInfo bitmapInfo = kCGImageAlphaNoneSkipLast | kCGBitmapByteOrder32Big;

如果这不起作用,请尝试其他kCGBitmapByteOrder...常量(kCGBitmapByteOrder32LittlekCGBitmapByteOrder16BigkCGBitmapByteOrder16Little)。

修改

Apple的SquareCam示例项目有一个名为SquareCam/SqareCamViewController.m的文件(是的,“Square”在文件名中拼写错误)。它包含以下代码:

    sourcePixelFormat = CVPixelBufferGetPixelFormatType( pixelBuffer );
    if ( kCVPixelFormatType_32ARGB == sourcePixelFormat )
        bitmapInfo = kCGBitmapByteOrder32Big | kCGImageAlphaNoneSkipFirst;
    else if ( kCVPixelFormatType_32BGRA == sourcePixelFormat )
        bitmapInfo = kCGBitmapByteOrder32Little | kCGImageAlphaNoneSkipFirst;
    else
        return -95014; // only uncompressed pixel formats

您可能想要做同样的事情。

相关问题