Hex Code Brightness PHP?
Asked Answered
E

6

32

I want users on my website to be able to pick a hex colour, and I just want to display white text for dark colours and black text for light colours. Can you work out the brightness from a hex code (preferably PHP)?

Elytron answered 10/6, 2010 at 14:5 Comment(0)
R
46
$hex = "78ff2f"; //Bg color in hex, without any prefixing #!

//break up the color in its RGB components
$r = hexdec(substr($hex,0,2));
$g = hexdec(substr($hex,2,2));
$b = hexdec(substr($hex,4,2));

//do simple weighted avarage
//
//(This might be overly simplistic as different colors are perceived
// differently. That is a green of 128 might be brighter than a red of 128.
// But as long as it's just about picking a white or black text color...)
if($r + $g + $b > 382){
    //bright color, use dark font
}else{
    //dark color, use bright font
}
Raillery answered 10/6, 2010 at 14:18 Comment(2)
Works perfect, didn't even need to go into Hue and Saturation! :)Elytron
In my case it worked better to use 250 instead of 382. I don't think the full green color (#00ff00) should use a light color font, and the full red is fine with a dark color. Just saying.Ahriman
P
25

I made one similar - but based on weightings of each colour (based on the C# version of this thread)

function readableColour($bg){
    $r = hexdec(substr($bg,0,2));
    $g = hexdec(substr($bg,2,2));
    $b = hexdec(substr($bg,4,2));

    $contrast = sqrt(
        $r * $r * .241 +
        $g * $g * .691 +
        $b * $b * .068
    );

    if($contrast > 130){
        return '000000';
    }else{
        return 'FFFFFF';
    }
}

echo readableColour('000000'); // Output - FFFFFF

EDIT: Small optimisation: Sqrt is known as an expensive math operation, which is probably neglectable in most scenarios, but anyway, it could be avoided by doing something like this.

function readableColour($bg){
    $r = hexdec(substr($bg,0,2));
    $g = hexdec(substr($bg,2,2));
    $b = hexdec(substr($bg,4,2));

    $squared_contrast = (
        $r * $r * .299 +
        $g * $g * .587 +
        $b * $b * .114
    );

    if($squared_contrast > pow(130, 2)){
        return '000000';
    }else{
        return 'FFFFFF';
    }
}

echo readableColour('000000'); // Output - FFFFFF

It simply doesn't apply the sqrt, instead it powers the desired cut off contrast by two, which is a much cheaper calculation

Placenta answered 11/12, 2011 at 23:44 Comment(1)
to get R G B values in dec just use this line: list($r, $g, $b) = sscanf($color, "%02x%02x%02x"); or if $color start with a # list($r, $g, $b) = sscanf($color, "#%02x%02x%02x");Flap
T
5

I know this is a very old topic, but for users who came from "Google Search", this link may be what they are looking for. I've searched for something like this and I think it's a good idea to post it here:

https://github.com/mexitek/phpColors

use Mexitek\PHPColors\Color;
// Initialize my color
$myBlue = new Color("#336699");

echo $myBlue->isLight(); // false
echo $myBlue->isDark(); // true

That's it.

Terramycin answered 29/1, 2015 at 17:57 Comment(0)
S
2

You need to convert the RGB values to HLS/HSL (Hue Lightness and Saturation) you can then use the Lightness to determine whether you need light text or dark text.

This page has some details on how to the conversion in PHP as well as selecting complementary colour from this.

I've only just spotted that the site is an astrology site - so apologies if anyone's offended.

Seigel answered 10/6, 2010 at 14:8 Comment(1)
About astrology site: yes, that's horrendous! (No, just kidding, interesting they have such a programming related topic on their site, I wouldn't expect that.)Fidelity
F
1

If you have imagemagick extension activated, you can simply create an ImagickPixel object, call setColor with your hex value, and then call getHSL() (and get the last item of the obtained array I suppose)...

Fa answered 10/6, 2010 at 14:13 Comment(0)
B
1

I tried a different approach to this, I used HSL (hue, saturation & lightness) lightness percentage to check if the color is dark or light. (like @chrisf said in his answer)

function:

function colorislight($hex) {
   $hex       = str_replace('#', '', $hex);
   $r         = (hexdec(substr($hex, 0, 2)) / 255);
   $g         = (hexdec(substr($hex, 2, 2)) / 255);
   $b         = (hexdec(substr($hex, 4, 2)) / 255);
   $lightness = round((((max($r, $g, $b) + min($r, $g, $b)) / 2) * 100));
   return ($lightness >= 50 ? true : false);
}

On the return line it checks if the lightness percentage is higher than 50% and returns true otherwise false is returned. You can easily change it to return true if the color has 30% lightness and so on. The $lightness variable can return from 0 to 100 0 being the darkest and 100 being the lightest.

how to use the function:

$color = '#111111';
if ( colorislight($color) ) {
   echo 'this color is light';
}
else {
   echo 'this color is dark';
}
Beyrouth answered 10/9, 2015 at 2:20 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.