有没有一种方法可以确定 HTML 十六进制颜色是浅色还是深色?

4

如果行的背景颜色是浅色,则我希望我的html页面上的字体颜色变为黑色,如果背景是白色,则字体颜色变为白色。

我在我的页面中使用jsp。是否有一种方法可以这样说:

如果颜色 < ##0686FF,则字体颜色=#000000 例如

编辑:正在寻找一个脚本或JavaScript。


1
我认为你应该尝试使用JavaScript来实现这个。 - Harry Joy
你可以通过使用你的颜色的反色来快速完成剪切 - 这样你就可以确保文本始终可见。 反转的颜色=FFFFFF的十六进制值-你的颜色 - Lucius
5个回答

12

这个解决方案使用了java.awt.Color类来获取颜色的亮度值,并根据此值确定应使用哪种背景颜色。

编辑:与其他一些解决方案不同,此解决方案会将某些亮色视为暗色,例如基本红色(#FF0000)。而此解决方案将把基本红色视为最亮的颜色之一。我想这取决于您的喜好。您想在黑色背景上阅读红色文字还是在白色背景上阅读?

String fontColor = "#0cf356";

// remove hash character from string
String rawFontColor = fontColor.substring(1,fontColor.length());

// convert hex string to int
int rgb = Integer.parseInt(rawFontColor, 16);

Color c = new Color(rgb);

float[] hsb = Color.RGBtoHSB(c.getRed(), c.getGreen(), c.getBlue(), null);

float brightness = hsb[2];

if (brightness < 0.5) {
   // use a bright background
} else {
   // use a dark background
}

HSB代表色相(Hue)、饱和度(Saturation)和亮度(Brightness)——亮度也被称为明度。使用Color类时,值在1和0之间。因此,0.5亮度是最亮的颜色和最暗的颜色之间的中点。

色相、饱和度和亮度之间的相互作用比红、蓝和绿色更加复杂。使用此工具尝试不同的颜色,并找到RGB和HSB之间的关系。


很好,运行良好。你能告诉我0.5是什么意思吗?那会是什么颜色? - 124697
同时,使用您的代码后,绿色(#45A61F)的亮度比浅蓝色(#99CCCC)更亮,您该如何解决这个问题? - 124697
1
你确定绿色和蓝色吗?我迅速运行了程序,它产生了蓝色亮度为0.8,绿色亮度为0.65的结果(其中1是最亮的,0是最暗的)。将添加一个关于hsb和0.5意义的编辑。 - Dunes

10

通常我们所说的 "颜色" 是指24位RGB颜色:每种颜色分别用1字节(8位)表示红、绿、蓝三种颜色通道,即每个通道的值都在0-255之间,或者在十六进制显示中为0x00到0xff。

白色是所有通道都开启的状态:#FFFFFF,黑色是所有通道都关闭的状态:#000000。显然,较浅的颜色意味着通道中的值更高,而较深的颜色意味着通道中的值更低。

您如何选择算法完全取决于您自己,简单的算法可能是:

//pseudo-code
if (red + green + blue <= (0xff * 3) / 2) //half-down, half-up
  fontcolor = white;
else
  fontcolor = black;

编辑: 询问者要求更完整的示例,以便可以有更好的起点,因此在此提供:

public static void main(String[] args) throws IOException {

String value =
       // new Scanner(System.in).nextLine(); //from input
        "#112233"; //from constant
int red = Integer.parseInt(value.substring(1, 1 + 2), 16);
int green = Integer.parseInt(value.substring(3, 3 + 2), 16);
int blue = Integer.parseInt(value.substring(5, 5 + 2), 16);

System.out.println("red = " + Integer.toHexString(red)
        + ", green = " + Integer.toHexString(green)
        + ", blue = " + Integer.toHexString(blue));

if (red + green + blue <= 0xff * 3 / 2)
    System.out.println("using white color #ffffff");
else
    System.out.println("using black color #000000");

String colorBackToString = "#" + Integer.toHexString(red) +
        Integer.toHexString(green) +
        Integer.toHexString(blue);
System.out.println("color was " + colorBackToString);
}

输出结果为:

红色 = 11, 绿色 = 22, 蓝色 = 33
使用白色 #ffffff
颜色为 #112233

并展示了将格式为 #aabbcc 的颜色拆分为rgb通道,以后再合成它们的技巧(如果需要)。


这是一个网页,它怎么知道0xff是什么。我正在处理像#000000这样的代码。 - 124697
尝试阅读一些有关Java和JSP的教程,这是简单的编码。 - peenut
谢谢您的回答,但是有没有更简单的方法?我只想在页面上使用一个脚本或JavaScript。 - 124697
有比几行代码更简单的方法吗?天哪,还有什么比这更容易的呢? - peenut

3

一种更自然的方法可能是使用HSL颜色空间。您可以使用第三个组件(“亮度”)来确定颜色有多亮。这对大多数目的都适用。

通过谷歌搜索可以找到很多描述。基本上,您需要选择值最高的颜色分量(比如红色)和值最低的颜色分量(比如绿色)。在本例中:

L = (red + green) / (255*2.0)

假设您从0到255提取了颜色值。您将获得一个介于0和1之间的值。浅色可以是任何亮度高于某个任意值(例如0.6)的颜色。

@Dunes,嗯,我还是会点赞你使用 "Color" API。我太懒了,没去查它的文档 :-) - wds

1
function isTooLightYIQ(hexcolor)
{
      var r = parseInt(hexcolor.substr(0,2),16);
      var g = parseInt(hexcolor.substr(2,2),16);
      var b = parseInt(hexcolor.substr(4,2),16);
      var yiq = ((r*299)+(g*587)+(b*114))/1000;
      return yiq >= 128;
}

http://www.careerbless.com/services/css/csstooltipcreator.php中使用的颜色选择器效果良好。


太好了!我需要用PHP实现,所以我会在下面发布PHP代码。 - user2607743

0

这是Kiran在上面的 PHP 答案,对我很有用。谢谢Kiran。

function isTooLightYIQ($hexcolor)
{
    $hexcolor = ltrim($hexcolor, "#");
    $r = base_convert(substr($hexcolor, 0, 2), 16, 10); 
    $g = base_convert(substr($hexcolor, 2, 2), 16, 10); 
    $b = base_convert(substr($hexcolor, 4, 2), 16, 10); 
    $yiq = (($r * 299) + ($g * 587) + ($b * 114)) / 1000;
    return $yiq >= 128;
}

使用方法(使用 马利亚斯的adjustBrightness()函数):
$adjustPercent = -0.45;  //  45% darker
$darkHexColor = (isTooLightYIQ($hexColor)) ? adjustBrightness($hexColor, $adjustPercent) : $HexColor;

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