iosmacoscolorscore-graphicscgcolorspace

Proper way to convert CGColors between colorspaces


There are several questions out there that ask about converting colors between colorspaces on Apple platforms. Unfortunately, the answers quite often involve NSColor or UIColor -- non portable Objective-C classes that cannot be interchangeably used on OS X and iOS.

So I'd like to ask a very specific thing that I'm sure there must be a good answer to out there. I simply cannot believe that Apple would not foresee the need for this.

How does one convert CGColor from one colorspace (for example, monochrome) to another one (for example, RGB) in a generic way, supporting all CGColorSpace types, while using solely the portable Core Graphics functions?


Some context. I need to multiply the value provided by an online service with a value stored in UIColor. Correct way to extract the RGB components prior to iOS5, which finally introduced the method -[UIColor getRed:green:blue:alpha:], is to use CGColorGetComponents(). I then multiply this color with the color fetched from the online service. This fails in case +[UIColor grayColor] was used to generate the UIColor. Meaning, I need to convert the color from the greyscale colorspace into RGB. In this case, it's easy. What about some other colorspace being provided? Or what if in a theoretical future scenario I just want to process a single pixel's color?

There is a suggestion somewhere that I paint a pixel into a bitmap context and then read this pixel. That's insane, and I hope it isn't the only way to do this. Obviously the drawing method can figure out how to perform the conversion; how can we leverage this without creating a bitmap context solely to draw a pixel in it?


Additional research:

Filed a radar with Apple, #12141580, to open up and document CGColorTransform. I'm not holding my breath, though, so if there are other sensible suggestions, I'm all ears.


Solution

  • Apple added this API in iOS 9 and macOS 10.11: