在iOS12上使用CGColorSpaceCreateDeviceGray进行CGImageCreate

时间:2018-10-23 00:49:24

标签: objective-c core-image ios12

我正在使用CGImageCreate和CGColorSpaceCreateDeviceGray将缓冲区(CVPixelBufferRef)转换为灰度图像。速度非常快,并且在iOS 12之前运行良好...现在返回的图像为空。

代码如下:

bitmapInfo = kCGBitmapByteOrder32Little | kCGImageAlphaNoneSkipFirst;

CGDataProviderRef provider = CGDataProviderCreateWithData((void *)i_PixelBuffer,
                                                              sourceBaseAddr,
                                                              sourceRowBytes * height,
                                                              ReleaseCVPixelBuffer);
    retImage = CGImageCreate(width,
                             height,
                             8,
                             32,
                             sourceRowBytes,
                             CGColorSpaceCreateDeviceGray(),
                             bitmapInfo,
                             provider,
                             NULL,
                             true,
                             kCGRenderingIntentDefault);
    CGDataProviderRelease(provider);

这是iOS 12中的已知错误吗?如果此功能不再支持设备灰色,您可以建议我另一种方法吗?

请注意,一张4K图像的转换时间应少于0.1秒。

提前谢谢!

2 个答案:

答案 0 :(得分:0)

根据Supported Pixel Formats in the Quartz 2D Programming Guide的列表,iOS不支持每像素32位带有灰色空间。即使在macOS上,32 bpp灰色也需要使用kCGBitmapFloatComponents(和浮动数据)。

您的数据真的是32 bpp吗?如果是这样,它是否浮动?您为bitmapInfo使用什么?

我不希望CGImageCreate()“转换”缓冲区,包括灰度。您提供的参数告诉它如何解释数据。如果您不使用浮点组件,我怀疑它只是采用一种颜色通道并将其解释为灰度级而忽略了其他组件。因此,这不是适当的灰度转换。

Apple的建议是创建一个能够正确代表该图像的图像;使用所需的色彩空间,像素布局和位图信息创建位图上下文;将前者吸引到后者;并根据上下文创建最终图像。

答案 1 :(得分:0)

我终于找到了解决该问题的方法。请注意,CVPixelBuffer来自摄像机。

  • 将相机输出像素格式更改为
    kCVPixelFormatType_420YpCbCr8BiPlanarFullRange (AVCaptureVideoDataOutput)
  • 从YpCbCr中提取Y平面
  • 使用Y平面构建CGImage

代码:

// some code

colorSpace = CGColorSpaceCreateDeviceGray();
sourceRowBytes = CVPixelBufferGetBytesPerRowOfPlane(i_PixelBuffer, 0);
sourceBaseAddr = (unsigned char*)CVPixelBufferGetBaseAddressOfPlane(i_PixelBuffer,0);
bitmapInfo = kCGImageByteOrderDefault;

// some code

CGContextRef context = CGBitmapContextCreate(sourceBaseAddr,
                                             width,
                                             height,
                                             8,
                                             sourceRowBytes,
                                             colorSpace,
                                             bitmapInfo);
retImage = CGBitmapContextCreateImage(context);

// some code

您还可以查看以下相关文章: 420YpCbCr8BiPlanarVideoRange To YUV420 ?/How to copy Y and Cbcr plane to Single plane?

相关问题