NSColor+ContrastingLabelExtensions

A quick Cocoa source code post. This one is simple: it’s a category on NSColor which returns another NSColor for use when drawing label text on top of the receiver. Either white or black is returned, depending on which will have most visual contrast with the receiver’s color. In the event of the receiver’s colorspace not being converted to RGB, black is returned by default.

Download the source code (includes a sample app, as always). This code came about due to a conversation I was having today with Iain, so cheers to the man himself for that.

4 comments

  1. Matt,

    The exact ‘gray’ value of an RGB color can be determined more precisely as:

    (0.3*red)+(0.59*green)+(0.11*blue)

    This takes into account perceptual issues like the green component contributes more to the luminosity of the color than the red, and the red more than the blue.

    Neat sample all the same.

    Cheers,

    /a

  2. Nice tip there Alberto, cheers for that. :)

  3. Did not work for me with +[NSColor blackColor] on Leopard (haven’t tried on earlier systems, though). I had to change the color space conversion as detailed at http://www.zathras.de/angelweb/blog-cocoa-in-supercompiler.htm, so that line 16 would read:
    NSColor *rgbColor = [self colorUsingColorSpaceName:NSDeviceRGBColorSpace];
    Works perfectly now—thanks for this handy category, Matt!

  4. I modified the code to do a couple of things:

    1. Use the NSCalibratedRGBColorSpace.
    2. Apply the same alpha level as the original colour.

    - (NSColor *)contrastingLabelColor
    {
    NSColor *rgbColor = [self colorUsingColorSpaceName:NSCalibratedRGBColorSpace];
    if (!rgbColor) return [NSColor blackColor]; // happens if the colorspace couldn’t be converted

    float avgGray = (0.3 * [rgbColor redComponent]) + (0.59 * [rgbColor greenComponent]) + (0.11 * [rgbColor blueComponent]);

    if (avgGray >= 0.5)
    return [NSColor colorWithCalibratedRed:0.0f green:0.0f blue:0.0f alpha:[rgbColor alphaComponent]];
    else
    return [NSColor colorWithCalibratedRed:1.0f green:1.0f blue:1.0f alpha:[rgbColor alphaComponent]];
    }

Leave a comment