在颜色空间之间转换CGColors的正确方法

时间:2012-08-21 09:53:44

标签: ios macos colors core-graphics cgcolorspace

有几个问题要求在Apple平台上的颜色空间之间转换颜色。不幸的是,答案经常涉及NSColorUIColor - 不能在OS X和iOS上互换使用的非可移植Objective-C类。

所以我想问一个非常具体的事情,我肯定必须有一个很好的答案。我简直无法相信苹果公司不会预见到这一点。

如何以一般方式将CGColor从一个颜色空间(例如,单色)转换为另一个(例如,RGB),支持所有CGColorSpace类型,同时仅使用便携式Core图形功能?


一些背景。我需要将在线服务提供的值乘以UIColor中存储的值。在iOS5之前提取RGB组件的正确方法(最终引入方法-[UIColor getRed:green:blue:alpha:])是使用CGColorGetComponents()。然后,我将此颜色与从在线服务获取的颜色相乘。如果+[UIColor grayColor]用于生成UIColor,则会失败。意思是,我需要将颜色从灰度颜色空间转换为RGB。在这种情况下,它很容易。那提供的其他颜色空间怎么样?或者,如果在理论上的未来情景中我只想处理单个像素的颜色?

有人建议我将一个像素绘制到位图上下文然后读取这个像素。那是疯了,我希望这不是唯一的方法。显然,绘图方法可以弄清楚如何执行转换;我们如何在不创建位图上下文的情况下利用它来单独绘制像素?


其他研究:

    关于颜色转换的
  • This article,除了UIColor的未记录/私有方法-styleString之外,更有趣的是提及未记录的CGColorTransform s。
  • ColorCG.cpp from WebKit表示有一个名为CoreGraphics/CGColorTransform.h的标头。不幸的是,这个标题不存在,至少在Mountain Lion上不存在。为什么Apple会隐藏这些API?
  • 我发现提到CGColorTransform的唯一其他合理资源是FreeQuartz,这是Core Graphics的免费/开源重新实现。

向Apple提交雷达#12141580,以打开并记录CGColorTransform。不过,我没有屏住呼吸,所以如果还有其他合情合理的建议,我全都听见了。

3 个答案:

答案 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:

  • ObjC:CGColorCreateCopyByMatchingToColorSpace
  • 斯威夫特:CGColor.converted(to:intent:options:)