十六进制代码亮度PHP?

31

我希望我的网站用户能够选择一个十六进制颜色,并且只显示白色文本于深色的颜色中,黑色文本于浅色的颜色中。您能否从十六进制代码中计算出亮度值(最好使用PHP)?

6个回答

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
}

完美地工作,甚至不需要进入色相和饱和度! :) - Juddling
在我的情况下,使用250而不是382效果更好。我认为完全的绿色(#00ff00)不应该使用浅色字体,而完全的红色则可以使用深色。只是说一下。 - Robin Manoli

25

我做了一个类似的东西,但是基于每种颜色的权重 (基于这个主题的C#版本)

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

编辑: 小优化: Sqrt(平方根)是一种代价昂贵的数学运算,尽管在大多数情况下可能可以忽略不计,但无论如何,可以通过像这样做来避免它。

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

它简单地不应用平方根,而是将期望的对比度切割值平方,这是一种更便宜的计算方法。


太棒了!谢谢! - Eduardo Russo
1
要获取十进制的 R G B 值,只需使用以下代码: list($r, $g, $b) = sscanf($color, "%02x%02x%02x"); 或者如果 $color 以 # 开头,则使用以下代码: list($r, $g, $b) = sscanf($color, "#%02x%02x%02x"); - JoTaRo

5
我知道这是一个非常古老的话题,但对于来自“谷歌搜索”的用户,这个链接可能是他们正在寻找的。我已经搜索了类似的东西,我认为在这里发布它是一个好主意: https://github.com/mexitek/phpColors
use Mexitek\PHPColors\Color;
// Initialize my color
$myBlue = new Color("#336699");

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

就是这样了。

2
你需要将RGB值转换为HLS / HSL(色相,亮度和饱和度),然后可以使用亮度来确定是否需要浅色文本或深色文本。 这个页面提供了有关如何在PHP中进行转换以及从中选择补色的一些详细信息。 我刚刚发现这个网站是一个占星术网站 - 如果有人感到冒犯,请接受我的道歉。

1
关于占星网站:是的,那真是可怕!(不,开个玩笑,有关编程方面的主题在他们的网站上很有趣,我没想到。) - Marcel Korpel

1
如果您已经启用了imagemagick扩展,您可以简单地创建一个ImagickPixel对象,使用您的十六进制值调用setColor,然后调用getHSL()(我想获取获得的数组的最后一项)...

1

我尝试了一种不同的方法,使用HSL(色相、饱和度和亮度)亮度百分比来检查颜色是暗色还是亮色。(就像@chrisf在他的答案中所说的那样)

功能:

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);
}

在返回行上,它会检查亮度百分比是否高于50%,如果是,则返回true,否则返回false。您可以轻松更改它,以便在颜色具有30%亮度等情况下返回true。 $ lightness 变量可以返回从0到100的值,其中0是最暗的,而100是最亮的。

如何使用该函数:

$color = '#111111';
if ( colorislight($color) ) {
   echo 'this color is light';
}
else {
   echo 'this color is dark';
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接