//Sorry for the formatting of this - not quite sure what happened to the width!
Hi,
I am trying to devise a way of programmatically deciding if two hex values would be visible to a human viewer.
If for example my webpage had a background colour of #FFFFFF and i set my text value to the same value then you couldn't see the text. That is programmatically a nice simple pattern match. However, if i were to change the text value just a little to ... say #EDFAE, the pattern match would fail... but a user would have a great deal of trouble reading it.
I have looked at a few approaches, and have come up with this.... there is one vital flaw however:-
Code:
Step 1: Set visibility metric:
Visible text < 90% match
Step 2: Split the hexidecimal representation into the component colour values:
FF, FF, FF
Step 3: Convert each bigram value to decimal:
FF -> 255, FF -> 255, FF -> 255
Step 4: Sum the decimal values:
255 + 255 + 255 = 765
Step 5: Repeats steps 2-4 for second hexidecimal value (e.g. the text value).
Step 6: Compare the two resulting values.
Step 7: Perform visibility calculation:
SMALLEST VALUE * (100/LARGEST VALUE)
Step 8: If the result is less than or equal to our visibility metric, then the text should be visible to the human eye. If the result is larger than the metric then we can assume that the text was designed to be invisible to human viewers.
Worked Example
Let's run the algorithm over our earlier example of #FFFFFF(our background) against #EDFAE6(our text).
#FFFFFF -> 255+255+255=765
#EDFAE6 -> 237+250+230=717
#FFFFFF is the larger decimal value so becomes the denominator in our equation.
717*(100/765) = 93.72%
With our visibility metric set to 90% this comparison would appear to be invisible to human viewers.
If one of the values is black - #000000 then I am dividing by zero - causing a major problem... e.g. if #000000 is compared to #FFFFFF - 0*(100/756) = 0 - this is fine... it is visible... but if we compare #000000 to #000033 - 0*(100/51) = 0 - NOT A MATCH, but if you look at this colour combination it is hard to see!
I have though about incrementing each hex value by one to prevent the divide by zero issue. However this causes a different problem outlined in the next example
Code:
This example uses a hex->++dec conversion!
#000000 = 3
#000033 = 54
3*(100/54) = 5% - This is not zero, but 5% suggests it is visible, when it isn't - a value of 95% would be more appropriate
I would dearly welcome any input anyone else might have on this problem, i have covered my desk with bits of paper trying to work this out. I have thought about using a Vector model for each R,G,B value and checking to see if the value we compare is within X places of the original, however I think this might present more problems that it is worth - although programmatically a vector space is a nice array!
Any comments greatfully received!
aceduk