Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a penalty for mixing color spaces? (Core Graphics)

If I'm writing drawing code in Core Graphics on Mac OS X or iPhone OS, I can set the active fill color to red by calling:

CGContextSetRGBFillColor(context, 1.0, 0.0, 0.0, 1.0); // RGB(1,0,0)

If I want 50% gray, I could call:

CGContextSetRGBFillColor(context, 0.5, 0.5, 0.5, 1.0); // RGB(0.5,0.5,0.5)

But for shades of gray it's tempting to make a shorter line and call:

CGContextSetGrayFillColor(context, 0.5, 1.0);

However, this function is NOT simply calling the RGB method with the intensity value copied three times; instead it is changing the context's color space from DeviceRGB to DeviceGray. The next call to an RGB method will switch it back.

I'm curious to know:

  • What's the penalty for switching color spaces?
  • Is there a penalty for drawing when your context's color space doesn't match your device's native color space? (i.e., drawing in DeviceGray versus DeviceRGB)

I'm asking out of technical curiosity, not a desire to prematurely optimize, so please keep your admonitions to a minimum, please.

like image 347
benzado Avatar asked Oct 15 '22 10:10

benzado


2 Answers

Conceptually, there's a penalty, but in practice it's so miniscule as to be irrelevant; converting (e.g.) a shade of gray to an RGB triplet (plus alpha) is trivial arithmetic even with a custom colour space.

Colour spaces do have a penalty when you're drawing images, however, as it's more than a matter of a single conversion operation. Every pixel must be converted, and while there are optimizations that can be done here (e.g. CLUTs, Colour Look-Up Tables, are useful if the source image uses indexed colours) they don't tend to be useful in situations where you also find Quartz code.

You say you expect CGContextSetGrayFillColor() to change the colour space of the graphics context, but that isn't actually the case. Doing so would necessitate converting the contents of that graphics context to match the context's new colour space. Since it's far cheaper and simpler to convert the colour instead of the context's buffers (e.g. by making CGContextSetGrayFillColor() an under-the-covers wrapper around CGContextSetRGBFillColor()), such an expense is going to be avoided in any sensible implementation.

like image 95
Jonathan Grynspan Avatar answered Nov 02 '22 04:11

Jonathan Grynspan


I have been using both extensively in a similar manner and have noticed no penalty in terms of performance.

like image 24
Nick Toumpelis Avatar answered Nov 02 '22 05:11

Nick Toumpelis