← Blog

Using the Appropriate Color Spaces

· James

Whether you’re setting colors for your app in its storyboard or XIB files, or creating NSColor objects programatically, it’s important to consider the color-space that will be used. RGB Color spaces can be device-dependent or device-independent. Colors from device-dependent color spaces are dependent on the physical characteristics of devices which can affect the color it produces. Whereas device-independent color spaces are more accurate representations of the colors perceived by the human eye. In this article I’ll briefly explain why using the correct color-space matters.

We have the following macros in our Ember project to help us create NSColor objects.

#define RGBA(r, g, b, a) [NSColor colorWithCalibratedRed:(r / 255.0) green:(g / 255.0) blue:(b / 255.0) alpha:a]
#define RGB(r, g, b) RGBA(r, g, b, 1.0)

We use them for quickly creating color objects from RGB(A) values provided by our designer Elliot.

NSGradient *backgroundGradient = [[NSGradient alloc] initWithStartingColor:RGB(252, 161, 9) endingColor:RGB(252, 121, 8)];

We previously, by mistake, wrote the macro using the colorWithDeviceRed:green:blue:alpha: method. It didn’t take long to notice that the colors provided by Elliot weren’t matching the colors in the app. The reason for this was due to the color-space being used.

The “Device” color-space names represent color spaces in which component values are applied to devices as specified. There is no optimization or adjustment for differences between devices in how they render colors. (Color Programming Topics: 12)

When using the device color-space the colors will look slightly different on different displays as we don’t know exactly what device is connected to the system.

Instead the NSCalibratedRGBColorSpace or NSCalibratedWhiteColorSpace are more appropriate to use. These color spaces are device-independent and are calibrated to a device that best represents devices in a particular class, such as color displays. Using these color spaces throughout Ember we’re able to present reasonably accurate colors when when we don’t know about the color space of the device connected to the system.

A project’s xib and storyboard files use these calibrated color spaces too. If you’re programatically changing colors of controls then it’s likely that you will want to use the same color space used as setting them in the Attributes Inspector.

<color key="textColor" red="1" green="0.0" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>

If you simply change the color methods in your project from the device to the calibrated color-space ones then the colors will appear different. What you will need to do is convert to them using colorUsingColorSpaceName:. This method returns an NSColor that is the same as the receiver, but in the specified color-space.

NSColor *deviceColor = [NSColor colorWithDeviceRed:0.5 green:0.3 blue:0.6 alpha:1.0];
NSColor *calibratedColor = [deviceColor colorUsingColorSpaceName:NSCalibratedRGBColorSpace];

I hope this brief article has been helpful. If there’s anything that you would like to discuss, let me know on Twitter.

Download

Confirm your email and we'll send your code. Unsubscribe any time. Privacy policy