我正在使用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秒。
提前谢谢!
答案 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来自摄像机。
代码:
// 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?