如何检查十六进制颜色是否“太黑”?

2022-08-30 04:02:56

我正在尝试评估颜色选择器选择的颜色的深度,以查看它是否“太黑”,如果是这样,请将其设置为白色。我想我可以使用十六进制值的第一个字符来实现这一点。它正在工作,但它也在切换一些合法的“浅”颜色。

我有代码这样做:

        if (lightcolor.substring(0,3) == "#00"|| lightcolor.substring(0,3) == "#010"){
            lightcolor="#FFFFFF";
            color=lightcolor;
        }

必须有一种更有效的十六进制数学方法来知道一种颜色已经超过了一定程度的黑暗?例如,如果浅色+“一些十六进制值”<=“一些十六进制值”,然后将其设置为白色。

我添加了tinyColor,这可能对此有用,但我不确定。


答案 1

您必须分别提取三个 RGB 分量,然后使用标准公式将生成的 RGB 值转换为其感知亮度。

假设有六个字符的颜色:

var c = c.substring(1);      // strip #
var rgb = parseInt(c, 16);   // convert rrggbb to decimal
var r = (rgb >> 16) & 0xff;  // extract red
var g = (rgb >>  8) & 0xff;  // extract green
var b = (rgb >>  0) & 0xff;  // extract blue

var luma = 0.2126 * r + 0.7152 * g + 0.0722 * b; // per ITU-R BT.709

if (luma < 40) {
    // pick a different colour
}

编辑

自2014年5月以来,尽管使用CCIR601加权因子而不是上面的ITU-R因子,但现在具有功能。tinycolorgetBrightness()

编辑

得到的亮度值范围为 0..255,其中 0 表示最暗,255 表示最亮。大于 128 的值被 视为浅色。(无耻地从@pau.moreno和@Alnitak的评论中复制)tinycolor


答案 2

我发现了这个WooCommerce Wordpress PHP函数(wc_hex_is_light),我转换为JavaScript。工作正常!

function wc_hex_is_light(color) {
    const hex = color.replace('#', '');
    const c_r = parseInt(hex.substr(0, 2), 16);
    const c_g = parseInt(hex.substr(2, 2), 16);
    const c_b = parseInt(hex.substr(4, 2), 16);
    const brightness = ((c_r * 299) + (c_g * 587) + (c_b * 114)) / 1000;
    return brightness > 155;
}