今天在处理一张图片时图片处理后变成了纯黑色图片,其中定位到处理图片时进行了 CGContext 绘制操作,初始化 context 的代码如下所示:
1 | CGContextRef contextRef = CGBitmapContextCreate(NULL, width, height, 8, 0, CGImageGetColorSpace(image.CGImage), kCGImageAlphaNoneSkipLast|kCGBitmapByteOrderDefault); |
报错信息如下
1 | [Unknown process name] CGBitmapContextCreate: unsupported parameter combination: set CGBITMAP_CONTEXT_LOG_ERRORS environmental variable to see the details |
最终发现图片的颜色空间是 CYMK 格式的
1 | po CGImageGetColorSpace(image.CGImage) |
按照 Quartz 2D Programming Guide 的 Graphics Contexts 中介绍的有关位图上下文支持的像素格式,iOS 设备仅支持 RGB 和 GRAY,不支持 CYMK 格式,所以导致无法创建位图上下文,从而不能进行画布绘制等操作。
CS|Pixel format and bitmap information constant|Availability|
—|—|—|—|
Null|8 bpp, 8 bpc, kCGImageAlphaOnly|Mac OS X, iOS|
Gray|8 bpp, 8 bpc,kCGImageAlphaNone|Mac OS X, iOS|
Gray|8 bpp, 8 bpc,kCGImageAlphaOnly|Mac OS X, iOS|
Gray|16 bpp, 16 bpc, kCGImageAlphaNone|Mac OS X|
Gray|32 bpp, 32 bpc, kCGImageAlphaNone|kCGBitmapFloatComponents|Mac OS X|
RGB|16 bpp, 5 bpc, kCGImageAlphaNoneSkipFirst|Mac OS X, iOS|
RGB|32 bpp, 8 bpc, kCGImageAlphaNoneSkipFirst|Mac OS X, iOS|
RGB|32 bpp, 8 bpc, kCGImageAlphaNoneSkipLast|Mac OS X, iOS|
RGB|32 bpp, 8 bpc, kCGImageAlphaPremultipliedFirst|Mac OS X, iOS|
RGB|32 bpp, 8 bpc, kCGImageAlphaPremultipliedLast|Mac OS X, iOS|
RGB|64 bpp, 16 bpc, kCGImageAlphaPremultipliedLast|Mac OS X|
RGB|64 bpp, 16 bpc, kCGImageAlphaNoneSkipLast|Mac OS X|
RGB|128 bpp, 32 bpc, kCGImageAlphaNoneSkipLast、kCGBitmapFloatComponents|Mac OS X|
RGB|128 bpp, 32 bpc, kCGImageAlphaPremultipliedLast、kCGBitmapFloatComponents|Mac OS X|
CMYK|32 bpp, 8 bpc, kCGImageAlphaNone|Mac OS X|
CMYK|64 bpp, 16 bpc, kCGImageAlphaNone|Mac OS X|
CMYK|128 bpp, 32 bpc, kCGImageAlphaNone、kCGBitmapFloatComponents|Mac OS X|
更深入的说,Quartz 2D 支持颜色管理系统使用的标准颜色空间,也支持通用的颜色空间、索引颜色空间和模式(pattern)颜色空间,但 iOS 仅支持使用设备颜色空间,设备颜色空间创建方式如下
- CGColorSpaceCreateDeviceGray:创建设备依赖灰度颜色空间
- CGColorSpaceCreateDeviceRGB:创建设备依赖RGB颜色空间
- CGColorSpaceCreateDeviceCMYK:创建设备依赖CMYK颜色空间
而 CoreGraphic 支持两种图形上下文,bitmapContext 和 PDFContext,通常使用的 bitmapContext 仅支持 RGB 和 Gray。
因此当创建 bitmap 时,不应当调用 CGImageGetColorSpace
从图片获取 colorSpace 来设置上下文。
此外,如果是通过 PhotoFramework 从相册直接获取到 UIImage 对象则 PhotoFramework 会帮你将其 colorSpace 转换为 RGB,但是获取 NSData 到内存中自己通过 imageWithData 方法转换则会保留它的 colorSpace 信息。