Determine whether a color is bright or dark

For a site recently I have been working, I had to determine whether a background color is dark or bright. My target was to watermark it with contrast color. If its too bright, I’d use black. For dark color I’d use white. Its so simple to think. But not easy to find.

The main Idea was to find the Luminance of a color (capital Y) . If the luminance is enough high water mark it with dark color and vice versa. This will make a contrast so watermark will always visible be.

To find the Luminance of a color (Y) this forumula is used

Y = 0.2126 R + 0.7152 G + 0.0722 B

Here R, G and B are the Red, Green and Blue component of a color.  Here the constant values are determined by the contribution factor of intensity perceived by human eye. See the wiki. Now if Y is higher than 128 then its brighter color and you need to use dark color for water marking and use bright color for Y is less than 128.

HOWTO: Convert 6 digit css color code to 3 digit

Okay, So you want to convert 6 digit css color codes to 3 digit. They are almost same. But 3 digit helps to remember it.  Before jumping into code let me explain what does 3 digit represents. A css color #abc means #aabbcc. No its NOT  #a0b0c0. It may appear that  the second one is more appropriate. But the fact is Its not. You can test it.   See the following table.

#aabbcc #abc #a0b0c0
     

So to convert any 6 digit css color to a 3 digit color needs some calculation. Thats why I have written a php function.

See the code bellow

function convert_color($color){
 preg_match("|#([\da-h]{2})([\da-h]{2})([\da-h]{2})|", $color, $match);
 $n=array();
 array_shift($match);
 foreach($match as $m)
  array_push($n, reduce_digit($m));
 return "#". implode("", $n);
}

function reduce_digit($hex){
 $n = hexdec($hex);
 $r = $n%17 ;
 $d = intval($n/17)+ (($r<8)?0:1);
 return dechex($d);
}

Just call the convert_color function with 6 digit css color. For example. “#bcd465”. Here # is necessary. This will return the 3 digit css color.

If you want to test it, run the following code.

$params= array(
array("#aabbcc","#abc"),
array("#112233","#123"),
array("#456789","#468"),
array("#1234fa","#13f"),
array("#000000","#000")
);

foreach($params as $param){
    $f = convert_color($param[0]);
    $e = $param[1];
    echo "Passed={$param[0]}, Expected=", $e, ", Actual=";
    echo $f, ", Status=", (($e==$f)?"SUCCESS":"FAILED"), PHP_EOL;
}

I have run it it the result is good.

Passed=#aabbcc, Expected=#abc, Actual=#abc, Status=SUCCESS
Passed=#112233, Expected=#123, Actual=#123, Status=SUCCESS
Passed=#456789, Expected=#468, Actual=#468, Status=SUCCESS
Passed=#1234fa, Expected=#13f, Actual=#13f, Status=SUCCESS
Passed=#000000, Expected=#000, Actual=#000, Status=SUCCESS