给定一个背景颜色,黑色或白色的文本?

46

我正在尝试找到一种方法,可以确定在给定背景颜色(以十六进制值表示)的情况下,是使用黑色文本还是白色文本。有人处理过这个问题吗?是否有一种有效的方法来解决这个问题?

在我的情况下,我将使用PHP来实现这个逻辑(但任何其他语言的经验都是受欢迎的)。

7个回答

47

亮度对比度算法

我认为最好的方法是使用亮度对比度算法

function getContrastColor($hexColor)
{
        // hexColor RGB
        $R1 = hexdec(substr($hexColor, 1, 2));
        $G1 = hexdec(substr($hexColor, 3, 2));
        $B1 = hexdec(substr($hexColor, 5, 2));

        // Black RGB
        $blackColor = "#000000";
        $R2BlackColor = hexdec(substr($blackColor, 1, 2));
        $G2BlackColor = hexdec(substr($blackColor, 3, 2));
        $B2BlackColor = hexdec(substr($blackColor, 5, 2));

         // Calc contrast ratio
         $L1 = 0.2126 * pow($R1 / 255, 2.2) +
               0.7152 * pow($G1 / 255, 2.2) +
               0.0722 * pow($B1 / 255, 2.2);

        $L2 = 0.2126 * pow($R2BlackColor / 255, 2.2) +
              0.7152 * pow($G2BlackColor / 255, 2.2) +
              0.0722 * pow($B2BlackColor / 255, 2.2);

        $contrastRatio = 0;
        if ($L1 > $L2) {
            $contrastRatio = (int)(($L1 + 0.05) / ($L2 + 0.05));
        } else {
            $contrastRatio = (int)(($L2 + 0.05) / ($L1 + 0.05));
        }

        // If contrast is more than 5, return black color
        if ($contrastRatio > 5) {
            return '#000000';
        } else { 
            // if not, return white color.
            return '#FFFFFF';
        }
}

// Will return '#FFFFFF'
echo getContrastColor('#FF0000');

一些结果:

在此输入图片描述

注意: 字体颜色由前一个函数决定。方括号中的数字是对比度比率。



YIQ算法(较不精确)

另一种最简单和不太精确的方法称为YIQ(因为它将RGB颜色空间转换为YIQ):

public function getContrastColor($hexcolor) 
{               
    $r = hexdec(substr($hexcolor, 1, 2));
    $g = hexdec(substr($hexcolor, 3, 2));
    $b = hexdec(substr($hexcolor, 5, 2));
    $yiq = (($r * 299) + ($g * 587) + ($b * 114)) / 1000;
    return ($yiq >= 128) ? 'black' : 'white';
}                   

2
如果您可以提供*R/G/B值(范围在0到255之间),这是一个压缩版本:*function textColor($r,$g,$b) { return ((0.2126*$r/255)+(0.7152*$g/255)+(0.0722*$b/255)>=0.5?'#000':'#FFF'); }**。 - ashleedawg
1
我已经将第一个函数改编为Python,如果有人需要的话:https://gist.github.com/Benbb96/e7b1ce654f616da08e61fa888e666354 - Benbb96
1
@Benbb96 做得好! - tomloprod
1
注意:此处使用的亮度对比度算法基于WCAG 2.0技术的早期工作草案。公式和所需比率在最终版本中已更改。 - andrewmacpherson

39

请看这个页面: 使用PHP计算颜色对比度

请注意,如果黑色和白色是你唯一的选择,你可能会遇到两种颜色都不是特别适合的情况。


12
计算颜色亮度或亮度比对RGB值的平均要优越得多。 #FF0000是明亮的红色,而不是平均值85会让你误以为它是暗淡的颜色。在HSB系统中(B的0-100%比例),您可以获得明亮红色的B = 100。在Lab系统中,您只能获得54,这可能更有用,因为它超过了50%的点,表明您应该使用黑色来对抗它,而不是白色。 - Warren Young
注意:splitbrain.org文章中的公式来自WCAG 2.0技术工作草案的早期版本。在最终版本中,该公式和所需比率已更改。 - andrewmacpherson

8
  function getTextColour($hex){
    list($red, $green, $blue) = sscanf($hex, "#%02x%02x%02x");
    $luma = ($red + $green + $blue)/3;

    if ($luma < 128){
      $textcolour = "white";
    }else{
      $textcolour = "black";
    }
    return $textcolour;
  }

2

你应该看一下CSS颜色库。它是用PHP实现的,可以为你完成所有繁重的工作。


2

1
一个简单但不完美的解决方案是将各个组成部分(RGB)相加,值越大“颜色就越浅”。因此,对于较高的值,可以使用黑色作为前景色,而对于较低的值,则使用白色。
然后,您可以改进这种方法,为灰度颜色( R=G=B )制定特定的情况,除非是非常深的灰色,否则不会很好地显示白色文本。
编辑:当然,这意味着您需要知道十六进制值中RGB存储的格式,标准的24bpp存储方式是0x00RRGGBB,有8个十六进制数字。

0
我会计算RGB分量的平均值,然后决定使用黑色或白色,例如,白色高达0x66。

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