iOS 上这张图片的正确色彩空间转换是什么?

What is the proper colorspace conversion for this image on iOS?

我们如何修复下面的代码,以便正确地为您从我们传入的 sampleBuffer 中看到的图像着色?

我们正在尝试将传入的 sampleBuffer 图像转换为 UIImage,但结果是您在下面看到的反色图像。

您可以看到我们尝试在代码中使用 kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange 选项 - 但结果是一样的。

我们尝试显示的传入图像具有所有正确的颜色,事实证明,如果我们将图像渲染到 GLKView 中,所有颜色都在那里。

这可能是 YUV420 转换问题吗?

这是我们使用的转换代码:

- (CGImageRef) imageFromSampleBuffer:(CMSampleBufferRef) sampleBuffer // Create a CGImageRef from sample buffer data
{
    CVImageBufferRef imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer);
    CVPixelBufferLockBaseAddress(imageBuffer,0);        // Lock the image buffer

    uint8_t *baseAddress = (uint8_t *)CVPixelBufferGetBaseAddressOfPlane(imageBuffer, 0);   // Get information of the image
    size_t bytesPerRow = CVPixelBufferGetBytesPerRow(imageBuffer);
    size_t width = CVPixelBufferGetWidth(imageBuffer);
    size_t height = CVPixelBufferGetHeight(imageBuffer);
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();

    // CGContextRef newContext = CGBitmapContextCreate(baseAddress, width, height, 8, bytesPerRow, colorSpace, kCGBitmapByteOrder32Little | kCGImageAlphaPremultipliedFirst);

    CGContextRef newContext = CGBitmapContextCreate(baseAddress, width, height, 8, bytesPerRow, colorSpace, kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange | kCGImageAlphaPremultipliedFirst);



    CGImageRef newImage = CGBitmapContextCreateImage(newContext);
    CGContextRelease(newContext);

    CGColorSpaceRelease(colorSpace);
    CVPixelBufferUnlockBaseAddress(imageBuffer,0);
    /* CVBufferRelease(imageBuffer); */  // do not call this!

    return newImage;
}

这是我们用于传入 CVPixelBuffer 的设置代码:

// Now create the CVPixelBuffer to which we will render
    CVReturn retVal = CVPixelBufferCreate(kCFAllocatorDefault,
                                          self.screenWidth,
                                          self.screenHeight,
                                          kCVPixelFormatType_32BGRA,
                                          attrs,
                                          &_outputRenderTarget);


对于尝试恢复和显示所有正确颜色有什么建议吗?

除了您需要换回 commented/uncommented 行之外,显示的代码没有问题。

我会退后一步,看看是什么将数据写入您的传入缓冲区。例如,我使用 AVAssetReaderVideoCompositionOutput 对象来生成样本缓冲区。视频组合对象的初始化具有与您用于创建传入 cvpixelbuffer 的视频设置相匹配的视频设置以及 cgimage 和位图兼容性密钥。

原来我们用 1-r、1-g、1-b 反转了所有颜色。

一旦我们删除了反转,颜色又恢复正常了。