views:

307

answers:

4

Hi,

I need to determine whether a selected UIColor (picked by the user) is dark or bright, so I can change the color of a line of text that sits on top of that color, for better readability.

Here's an example in Flash/Actionscript (with demo): http://theflashblog.com/?p=173

Any thoughts?

Cheers, Andre

UPDATE

Thanks to everyone's suggestions, here's the working code:

- (void) updateColor:(UIColor *) newColor
{
    const CGFloat *componentColors = CGColorGetComponents(newColor.CGColor);

    CGFloat colorBrightness = ((componentColors[0] * 299) + (componentColors[1] * 587) + (componentColors[2] * 114)) / 1000;
    if (colorBrightness < 0.5)
    {
        NSLog(@"my color is dark");
    }
    else
    {
        NSLog(@"my color is light");
    }
}

Thanks once again :)

+1  A: 

You may be interested in a similar question that I asked a while back. I was looking to do the same thing, and the answer provided by Peter Hosey did the trick for me.

e.James
+1  A: 

For everything that's not grayish, the RGB inverse of a color is usually highly contrasted with it. The demo just inverts the color and desaturates it (converts it to a gray).

But generating a nice soothing combination of colors is quite complicated. Look at :

http://particletree.com/notebook/calculating-color-contrast-for-legible-text/

rep_movsd
If only there was an iPhone version of that :D
Andre
So if I got the RGB values of a color (which I don't know how to do) and created a new color with the inverse of those values, that should work on a very basic level?
Andre
A: 

If you want to find the brightness of the color, here is some pseudo code:

public float GetBrightness(int red, int blue, int green)
{
    float num = red / 255f;
    float num2 = blue / 255f;
    float num3 = green / 255f;
    float num4 = num;
    float num5 = num;
    if (num2 > num4)
        num4 = num2;
    if (num3 > num4)
        num4 = num3;
    if (num2 < num5)
        num5 = num2;
    if (num3 < num5)
        num5 = num3;
    return ((num4 + num5) / 2f);
}

If it is > 0.5 it is bright, and otherwise dark.

Bryan Denny
You can't weight each of the colors equally. Our eyes have a bias against blue and to a lesser extent red.
Erik Nedwidek
@ErikNedwidek: Fair enough, the question simply asked for the brightness of a color :)
Bryan Denny
+5  A: 

W3C has the following: http://www.w3.org/WAI/ER/WD-AERT/#color-contrast

If you're only doing black or white text, use the color brightness calculation above. If it is below 125, use white text. If it is 125 or above, use black text.

edit 1: bias towards black text. :)

edit 2: The formula to use is ((Red value * 299) + (Green value * 587) + (Blue value * 114)) / 1000.

Erik Nedwidek
do you know how to get the red , green and blue values of a color?
Andre
You can use `NSArray *components = (NSArray *)CGColorGetComponents([UIColor CGColor]);` to get an array of the colour components, including the alpha. The docs don't specify what order they're in but I assume it would be red, green, blue, alpha. Also, from the docs, "the size of the array is one more than the number of components of the color space for the color." - it doesn't say why...
Jasarien
Thanks! I'll give it a go :)
Andre
That's odd...using:NSArray *components = (NSArray *) CGColorGetComponents(newColor.CGColor); NSLog(@"my color components %f %f %f %f", components[0], components[1], components[2], components[3]);just to see if i can get the values, it seems only the 0 index changes, the others will remain the same, regardless of what color I pick.Any idea why?
Andre
Got it. You can't use NSArray. Use this instead:const CGFloat *components = CGColorGetComponents(newColor.CGColor); Also, the order is: red is components[0];green is components[1];blue is components[2];alpha is components[3];
Andre
Ah, my bad. I thought it returned a CFArrayRef, not a C array. Sorry!
Jasarien