Building on my answer to a similar question.
You need to break the hex code into 3 pieces to get the individual red, green, and blue intensities. Each 2 digits of the code represent a value in hexadecimal (base-16) notation. I won't get into the details of the conversion here, they're easy to look up.
Once you have the intensities for the individual colors, you can determine the overall intensity of the color and choose the corresponding text.
if (red*0.299 + green*0.587 + blue*0.114) > 186 use #000000 else use #ffffff
The threshold of 186 is based on theory, but can be adjusted to taste. Based on the comments below a threshold of 150 may work better for you.
Edit:don'tThe formula given for contrast in the W3C Recommendations is (L1 + 0.05) / (L2 + 0.05)
, where L1
is the luminance of the lightest color and L2
is the luminance of the darkest on a scale of 0.0-1.0. The luminance of black is 0.0 and white is 1.0, so substituting those values lets you determine the one with the highest contrast. If the contrast for black is greater than the contrast for white, use black, otherwise use white. Given the luminance of the color you're testing as L
the test becomes:
if (L + 0.05) / (0.0 + 0.05) > (1.0 + 0.05) / (L + 0.05) use #000000 else use #ffffff
This simplifies down algebraically to:
if L > sqrt(1.05 * 0.05) - 0.05
Or approximately:
if L > 0.179 use #000000 else use #ffffff
The only thing left is to compute L
. That formula is also given in the guidelines and it looks like the conversion from sRGB to linear RGB followed by the ITU-R recommendation BT.709 for luminance.
for each c in r,g,b:
c = c / 255.0
if c <= 0.03928 then c = c/12.92 else c = ((c+0.055)/1.055) ^ 2.4
L = 0.2126 * r + 0.7152 * g + 0.0722 * b
The threshold of 0.179 should not be changed since it is tied to the W3C guidelines. If you find the results not to your liking, try the simpler formula above.