评估一个十六进制值是深色还是浅色。

12

我正在构建的ASP.NET Web应用程序中,用户可以选择颜色来用于某些元素(例如按钮/标题),以实现一定程度的个性化。

问题在于默认情况下这些层上的文本为黑色...我试图通过选择器评估用户选择的HEX值,并通过编程方式在黑色和白色文本之间切换 - 这可以使用JavaScript或代码后台完成。

问题的关键是我不确定如何评估HEX以做出决策,即所选择的颜色是否太接近黑色而无法使用黑色文本。

有什么想法吗?

4个回答

18

不像其他回答者(ricknz)所说的将RGB组件相加,实际上应该取它们的平均值。

另外,由于绿色对人眼比蓝色更可见,因此您还应该添加一个权重。

因此,您必须首先将红色分量乘以0.299,将绿色分量乘以0.587,将蓝色分量乘以0.114。

因此亮度由以下公式给出:Luminance = (r*0.299 + g*0.587 + b*0.114)/3

编辑: 下面是一个计算它的片段:

 float calcLuminance(int rgb)
 {
      int r = (rgb & 0xff0000) >> 16;
      int g = (rgb & 0xff00) >> 8;
      int b = (rgb & 0xff);

      return (r*0.299f + g*0.587f + b*0.114f) / 256;
 }

顺便提一下,除以256是因为我们的RGB范围是0-256(而不是0-1)

编辑:根据聪明的评论更改了计算方法,现在除以256而不是768


2
如果你只是在比较浅色与深色,取平均值不会改变结果。 - RickNZ
无论如何,(r*0.299f + g*0.587f + b*0.114f)始终在0-255范围内,而不是768。 - nickf
2
johannes:维基百科...还有哪里呢;^) http://en.wikipedia.org/wiki/YUV YUV中的Y代表亮度。 - Toad
@Toad - 我该如何将我的十六进制转换为整数?这样我才能使用你提供的方法? - chobo2
@chobo:int number = Convert.ToInt32(hexString, 16); 其中的 16 表示这是十六进制数。 - Toad
显示剩余2条评论

10

转换为HSL并查看L亮度值。这将告诉您它有多明亮。

下面是用于执行此转换的javascript函数


要将字符串转换为数字,您可以使用例如 parseInt("coffee".substring(0,2), 16) 来表示红色。 - Johannes Hoff
1
感谢提供的链接(+1),它们帮助我快速构建了一个测试程序 - 它的效果非常好,但像Reinier所建议的那样在绿色和黄色上似乎不太准确。 - Chris
链接已经失效,请将代码放在回答中,谢谢! - Doug S
Doug S: 我基本上同意答案中的代码,但是HSL转换代码太长了,我觉得它会分散答案的注意力;RGB到HSL转换代码应该很容易找到。我用维基百科和stackoverflow的链接替换了原来的链接。希望它们能更持久 :) - Johannes Hoff

5
现在,这些操作的方法已经内置于 .Net 中:
    var hexcolor = "#FA3CD0";
    var color = System.Drawing.ColorTranslator.FromHtml(hexcolor);
    var brightness = color.GetBrightness();
    if (brightness > .5)
    {
        // color is light
    }
    else
    {
        // color is dark
    }

1

十六进制颜色代码由三个强度值组成,一个代表红色,一个代表绿色,一个代表蓝色,每个值都有两个十六进制数字。要确定暗色与亮色,只需将这三个值相加。较小的数值会比较大的值更暗。

例如对于 #010203,将RGB值相加得到 01+02+03 = 06。这将比 #102030 = 60 更暗。


谢谢 - 当您进入AA>FF的值时,您会如何评估? - Chris
ricknz:这是不正确的,因为绿色比蓝色更容易被眼睛看到。 - Toad
对于AA到FF,您只需要将十六进制的两位值转换为十进制,然后进行计算。在JavaScript中,您可以使用parseInt()函数。@reinier:没错,但仅仅将它们相加会得到一个粗略的近似值,并且等同于简单的颜色-->灰度/黑白转换。 - RickNZ
工作得很好,实施起来也非常容易 - 在我看来,准确度不如reinier提供的解决方案。再次感谢。 - Chris

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