开发者

Is there a way to tell if a HTML hex colour is light or dark

I want font colour on my html page to change t开发者_开发问答o black if the background colour of the row is light and black if the background is white

I'm using jsp in my page. is there a way to say something like this

if colour < ##0686FF then fontcolour = #000000 for example

edit: looking for a scriptlet or javascript


This solution uses the java.awt.Color class to derive the brightness value of the colour and use that to determine which background colour should be used.

edit: This solution is differs from some of the other solutions because the other solutions will consider some bright colours to be dark eg. primary red (#FF0000). Whereas this solution, will consider primary red to be one of the brightest colours you can have. I suppose it depends on your preferences. Do you want to read red on black or red on white?

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 stands for Hue, Saturation, Brightness -- brightness is also known as luminosity. With the Color class values are between 1 and 0. Ergo, 0.5 brightness is the the halfway point between the brightest colours and the darkest colours).

The interplay between hue, saturation and brightness are a little more complex than red, blue and green. Use this tool experiment with different colours and find the relationships between RGB and HSB


By "color" we usually mean 24-bit RGB color: 1 byte (8 bits) for red, green, blue. That is, every channel has value from 0-255, or 0x00 to 0xff in hexadecimal display.

White color is all channels at full: #FFFFFF, black is all channels turned off: #000000. Obviously, lighter color means higher values in channels, darker color means lower values in channels.

How exactly you choose your algorithm is up to you, simple one would be:

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

Edit: asker asks for more complete example, so he/she can have better start, so here it is:

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);
}

It produces output:

red = 11, green = 22, blue = 33
using white color #ffffff
color was #112233

And shows technique of splitting color in format #aabbcc into rgb channels, joining them later (if needed), etc.


A more natural approach might be using the HSL colorspace. You can use the third component ("lightness") to figure out how light a colour is. That will work for most purposes.

Plenty of descriptions out there by googling. Basically you take the colour component with the highest value (let's say it's red) and the one with the lowest (say, green). In this case:

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

Assuming you extracted your colours as values from 0 to 255. You'll get a value between 0 and 1. A light colour could be any colour with a lightness above a certain arbitrary value (for instance, 0.6).


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;
}

The color picker used in http://www.careerbless.com/services/css/csstooltipcreator.php works good


Here is Kiran's answer from above in PHP, which works great for me. Thanks 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;
}

Usage (using maliayas's adjustBrightness() function):

$adjustPercent = -0.45;  //  45% darker
$darkHexColor = (isTooLightYIQ($hexColor)) ? adjustBrightness($hexColor, $adjustPercent) : $HexColor;
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜