2

I have found answers to this question that explain how to convert an NSString hex into a UIColor (I have done this) and others explaining how to convert RGB to HSB, and others explaining how to determine lightness and darkness of RGB, but I'm wondering if there is a more direct way of figuring this out that does not involve going hex->UIColor->rgb->hsb->b. Hex->hsb, for instance? Or hex->rgb->brightness calculation?

I've got backgrounds that change color each time the view loads (hex values from XML), and I need to have the text on top change to white or black accordingly so it'll stay legible.

Help would be much appreciated, I've been kicking this around for days now.

spongefile
  • 309
  • 4
  • 12

3 Answers3

2

See Formula to determine brightness of RGB color.

Hex colors are usually RRGGBB or RRGGBBAA (alpha).

how to convert hexadecimal to RGB

To get three ints instead of a UIColor, you can modify the answer from that to:

void rgb_from_hex(char *hexstring, int *red, int *green, int *blue) {
    // convert everything after the # into a number
    long x = strtol(hexstring+1, NULL, 16);

    // extract the bytes
    *blue = x & 0xFF;
    *green = (x >> 8) & 0xFF;
    *red = (x >> 16) & 0xFF;
}

// The above function is used like this:
int main (int argc, const char * argv[])
{
    int r,g,b;
    rgb_from_hex("#123456", &r, &g, &b);
    printf("r=%d, g=%d, b=%d\n", r, g, b);
}

(The function will probably only correctly handle RGB, not RGBA.)

Community
  • 1
  • 1
Jacob Jennings
  • 2,796
  • 1
  • 24
  • 26
  • I was looking at the hex to RGB question earlier, but the answers seem to convert hex to UIColor. Is UIColor the same as RGB, eg can I access the R,G and B components separately from UIColor? – spongefile Sep 30 '11 at 21:21
  • From the docs, it seems like UIColor wraps CGColor, which is fairly opaque and doesn't do colourspace conversions. – millimoose Sep 30 '11 at 21:52
  • In that case, I'm still missing a way to convert hex to RGB values(four int values (r, g, b, a), for instance?), while not involving UIColor at all. The answers to the question referenced above take you directly to UIColor from the hex string. (or perhaps converting from hex NSString to rgb ints is so simple that no one has thought to mention how it's done?) – spongefile Oct 01 '11 at 12:11
  • 1
    The linked answer /does/ convert to three RGB ints, it just wraps them inside a UIColor at the very end. It should be reasonably easy to wrap them in an int[] instead. – millimoose Oct 01 '11 at 13:29
  • 1
    @spongefile: Right, I (somehow) managed to make working C to do the conversion, I added it to the answer. – millimoose Oct 01 '11 at 13:44
0

The maximum of the red, green, and blue components seems to determine the "brightness" of a color in the HSB sense.

millimoose
  • 39,073
  • 9
  • 82
  • 134
  • If that was the case, white (#ffffff) would have the same brightness as blue (#0000ff). – omz Sep 30 '11 at 21:14
  • It does. It just has a different saturation. The HSV colorspace does not model colour appearance, it's just a mapping of RGB to a different set of axes. – millimoose Sep 30 '11 at 21:17
  • Okay, you're right. I was thinking of the perceived luminance. Sorry about the downvote, it seems that I can't remove it unless the answer is edited. – omz Sep 30 '11 at 21:25
  • This is actually an interesting point--I had assumed(and so had others in previous questions) that in HSB, brightness is the same as "lightness", eg what looks light or dark to the eye. Looks like saturation is what I'm looking for. Edit: wrong again. Saturation limit PLUS brightness limit. – spongefile Sep 30 '11 at 21:29
  • 1
    @spongefile: Searching around gave me [this blog post](http://www.destraynor.com/serendipity/index.php?/archives/140-Crimes-Against-Web-Usability-2.html), which deals with the same problem you have. It also lists a guideline on the recommended brightness and hue difference, so you can, for example, prefer black text if it's "good enough" even if white text gives numerically more contrast. (I believe the formula is the same one as one of those Jacob linked to.) – millimoose Sep 30 '11 at 22:08
0

In addition to the above, this is another solution, put together from others' answers here and elsewhere .

    - (BOOL)hasDkBg {    
        NSScanner* scanner = [NSScanner scannerWithString:@"BD8F60"];
        int hex;
        if ([scanner scanHexInt:&hex]) {
            // Parsing successful. We have a big int representing the 0xBD8F60 value
            int r = (hex >> 16) & 0xFF; // get the first byte
            int g = (hex >>  8) & 0xFF; // get the middle byte
            int b = (hex      ) & 0xFF; // get the last byte

            int lightness = ((r*299)+(g*587)+(b*114))/1000; //get lightness value

    if (lightness < 127) { //127 = middle of possible lightness value
        return YES;
    }
    else return NO;
}    

}

Community
  • 1
  • 1
spongefile
  • 309
  • 4
  • 12