27

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

所以我想问一个非常具体的问题,我相信肯定有一个很好的答案。我简直不敢相信苹果不会预见到这种需求。

如何CGColor以一种通用的方式从一种颜色空间(例如单色)转换为另一种颜色空间(例如 RGB),支持所有CGColorSpace类型,同时仅使用可移植的 Core Graphics 功能?


一些上下文。我需要将在线服务提供的值与存储在UIColor. iOS5之前的提取RGB分量的正确方法,最后介绍了方法-[UIColor getRed:green:blue:alpha:],就是使用CGColorGetComponents(). 然后我将此颜色与从在线服务获取的颜色相乘。如果+[UIColor grayColor]用于生成UIColor. 意思是,我需要将颜色从灰度颜色空间转换为 RGB。在这种情况下,这很容易。提供其他一些色彩空间呢?或者如果在理论上的未来场景中我只想处理单个像素的颜色怎么办?

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


补充研究:

  • 这篇关于颜色转换的文章,除了UIColor's undocumented/private method之外-styleString,更有趣的还提到了 undocumented CGColorTransforms。
  • WebKit 的 ColorCG.cpp建议有一个名为CoreGraphics/CGColorTransform.h. 不幸的是,这个标题不存在,至少在 Mountain Lion 上不存在。苹果为什么要隐藏这些 API?
  • 我发现提到 s 的唯一其他合理资源CGColorTransform是 FreeQuartz,它是 Core Graphics 的免费/开源重新实现。

向 Apple 提交了雷达 #12141580,以打开和记录CGColorTransform. 不过,我并没有屏住呼吸,所以如果有其他明智的建议,我会全神贯注。

4

3 回答 3

7

Apple 在 iOS 9 和 macOS 10.11 中添加了这个 API:

  • 对象:CGColorCreateCopyByMatchingToColorSpace
  • 迅速:CGColor.converted(to:intent:options:)
于 2017-02-17T18:39:50.953 回答
6

Apple 对我要求公开的 rdar #12141580 的官方回应CGColorTransform

非常感谢您的反馈。

工程根据以下信息确定行为不会改变:

使用颜色同步。

如果您对此问题的解决有疑问,请使用该信息更新您的错误报告。

我们现在关闭此错误报告。

请务必定期检查新的 Apple 版本,了解可能影响此问题的任何更新。

不管是谁写了这个回复,显然都觉得有必要详细解释这个决定。尤其是建议使用高度复杂的 API(例如 ColorSync)的决定。

于 2013-05-24T20:29:17.993 回答
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 */

我没有尝试此代码,它可能需要一些修复。

于 2012-09-08T23:08:47.093 回答