有几个问题要求在Apple平台上的颜色空间之间转换颜色。不幸的是,答案经常涉及NSColor
或UIColor
- 不能在OS X和iOS上互换使用的非可移植Objective-C类。
所以我想问一个非常具体的事情,我肯定必须有一个很好的答案。我简直无法相信苹果公司不会预见到这一点。
如何以一般方式将CGColor
从一个颜色空间(例如,单色)转换为另一个(例如,RGB),支持所有CGColorSpace
类型,同时仅使用便携式Core图形功能?
一些背景。我需要将在线服务提供的值乘以UIColor
中存储的值。在iOS5之前提取RGB组件的正确方法(最终引入方法-[UIColor getRed:green:blue:alpha:]
)是使用CGColorGetComponents()
。然后,我将此颜色与从在线服务获取的颜色相乘。如果+[UIColor grayColor]
用于生成UIColor
,则会失败。意思是,我需要将颜色从灰度颜色空间转换为RGB。在这种情况下,它很容易。那提供的其他颜色空间怎么样?或者,如果在理论上的未来情景中我只想处理单个像素的颜色?
有人建议我将一个像素绘制到位图上下文然后读取这个像素。那是疯了,我希望这不是唯一的方法。显然,绘图方法可以弄清楚如何执行转换;我们如何在不创建位图上下文的情况下利用它来单独绘制像素?
其他研究:
UIColor
的未记录/私有方法-styleString
之外,更有趣的是提及未记录的CGColorTransform
s。CoreGraphics/CGColorTransform.h
的标头。不幸的是,这个标题不存在,至少在Mountain Lion上不存在。为什么Apple会隐藏这些API?CGColorTransform
的唯一其他合理资源是FreeQuartz,这是Core Graphics的免费/开源重新实现。向Apple提交雷达#12141580,以打开并记录CGColorTransform
。不过,我没有屏住呼吸,所以如果还有其他合情合理的建议,我全都听见了。
答案 0 :(得分:6)
Apple对rdar的官方回应#12141580我要求曝光CGColorTransform
:
非常感谢您的反馈。
工程已确定不会更改行为 关于以下信息:
使用ColorSync。
如果您对此问题的解决方案有疑问,请 使用该信息更新您的错误报告。
我们现在正在关闭此错误报告。
请务必定期检查新的Apple版本是否有任何更新 这可能会影响这个问题。
无论是谁写了这个回应,显然都有必要非常详细地解释这个决定。特别是建议使用高度复杂的API(如ColorSync)的决定。
答案 1 :(得分:4)
问题明确表示他们希望避免使用仅为转换颜色而创建的位图上下文,但我没有意识到并想出了这个。
我会留下这个作为参考,以便任何可能偶然发现这个问题,并想知道如何通过绘制临时位图进行转换
CGColorRef source;
CGColorSpaceRef targetColorSpace;
int components = CGColorSpaceGetNumberOfComponents(targetColorSpace);
CGFloat temp-buffer[components];
CGContextRef temp-bmp = CGBitmapContextCreate(
temp-buffer,
1,1,8 * sizeof(CGFloat),components,
targetColorSpace,
kCGBitmapFloatComponents );
CGContextSetFillColorWithColor(temp-bmp,source);
CGContextFillRect(temp-bmp,CGRectMake(0,0,1,1));
CGColor target = CGColorCreate(targetColorSpace,temp-buffer);
/* then you cleanup and destroy created objects */
我没有尝试此代码,可能需要一些修复。
答案 2 :(得分:4)
Apple在iOS 9和macOS 10.11中添加了此API:
CGColorCreateCopyByMatchingToColorSpace
CGColor.converted(to:intent:options:)