【问题标题】:Determine Color Lightness via RGB通过 RGB 确定颜色亮度
【发布时间】:2019-03-23 13:41:46
【问题描述】:

我有一些颜色样本应该显示所显示颜色的 rgb 值,背景是实际颜色。然后,如果有问题的颜色是浅色的,文本应该是黑色的,如果有问题的颜色是深的,文本颜色应该是白色的。

如何检测 RGB 值是浅色还是深色??

JS FIDDLE

<style>
#preview {
  display: block; 
  height: 40px; 
  line-height: 40px; 
  font-size: 20px; 
  vertical-align: middle;
  width: 150px; 
  text-align: center; 
}
</style>

<!-- html -->
<button id="new_color">Try Random Color</button>
<p id="preview">Click the button!</p>

<script>
const getRandNum = () => Math.floor(Math.random() * 256);

const get_random_color = () => (`rgb(${getRandNum()}, ${getRandNum()}, ${getRandNum()})`);

const checkColor = (color) => {
    // color = 'rgb(x, y, z)'; 
    // check color is light
    // or color is dark
    return true; 
}

$('#new_color').click(function(){
    const p = $('#preview');
    const bg_color = get_random_color(); 
    const color_is_light = checkColor( bg_color ); 

    const text_color = color_is_light ? 'black' : 'white';

    p.css({
        color: text_color,
        backgroundColor: bg_color
    })
});
</script>

我只找到了#hex 颜色的解决方案,但没有找到 rgb 的解决方案。很感谢任何形式的帮助。

【问题讨论】:

    标签: javascript jquery colors


    【解决方案1】:

    如果您正在寻找相对亮度,可以使用的快速公式是:

    Y = 0.2126R + 0.7152G + 0.0722B
    

    来源:https://en.wikipedia.org/wiki/Relative_luminance

    为了能够直接使用上面的系数,您必须将 RGB 分量归一化为 1。或者先除以 255。您将获得的 Y 值介于 0-1 之间,因此您可以这样做:

    const color_is_light = y > 0.5;
    

    我会这样做:

    const getRandomRgb = () => [
      Math.random(),
      Math.random(), 
      Math.random()
    ];
    
    const getRelativeLuminance = (rgb) =>
      0.2126 * rgb[0]
      + 0.7152 * rgb[1]
      + 0.0722 * rgb[2];
    
    const getCssColor = (rgb) => `rgb(${rgb.map((c) => c * 255)}`;
    

    不过,实际上会有一个“灰色区域”,在中间灰色背景下,无论是白色文本还是黑色文本,您都无法获得足够的对比度。

    您可能想要更改您的 get_random_color 函数以返回各个组件,进行上述数学运算,然后构造 CSS 颜色值。

    【讨论】:

      【解决方案2】:

      因此,如果您有 hex 的答案,请调整 RGB 的答案,因为 hex 值只是 rgb base 10 值的 base 16 数字。现在正在寻找一种在碱基之间转换的方法。

      编辑:如果您的 r 十六进制值是“5a”,那么 rgb() 以 10 为底的 r 值的方法是 parseInt("5a",16)

      EDIT2:要从十进制中获取十六进制值,可以使用:const hex = d =&gt; Number(d).toString(16).padStart(2, '0') ~ 取自 How to convert decimal to hex in JavaScript?

      【讨论】:

      • 没错,但如果我不需要的话,我宁愿不转换......只是一个不必要的步骤,imo。不过建议很好。
      【解决方案3】:

      您必须检查if(red + green + blue &gt;= 255 * 1.5) 的浅色,如this post 中的第二个答案所述

      const checkColor = (color) => {
          // extract values of red, green and blue from color
          let clrarr = color.match(/\d+/g).map(num => +num);
      
        if(clrarr[0] + clrarr[1] + clrarr[2] >= 255 * 3 / 2) 
          return true; // color is light
      
        return false; // color is dark
      }
      

      JSFiddle

      【讨论】:

      • 致反对者:请检查编辑。如果您发现任何错误,最好添加评论而不是投反对票
      • 不知道为什么投反对票...我明白了。无论如何,这也有效!谢谢。 jsfiddle.net/av4sxhop/4
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-04-23
      • 2011-07-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-06-09
      相关资源
      最近更新 更多