How to check if hex color is "too black"?

I'm trying to evaluate the darkness of a color chosen by a color picker to see if it's "too black", and if so, set it to white. I thought I could use the first characters of the hex value to pull this off. It's working, but it's switching some legitimately "light" colors too.

I have code doing this:

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

There must be a more efficient way with hex math to know that a color has gone beyond a certain level of darkness? Like if lightcolor + "some hex value" <= "some hex value" then set it to white.

I have tinyColor added, which might be of use for this, but I don't know for sure.

A bunch!


You have to extract the three RGB components individually, and then use a standard formula to convert the resulting RGB values into their perceived brightness.

Assuming a six character colour:

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
}

EDIT

Since May 2014 tinycolor now has a getBrightness() function, albeit using the CCIR601 weighting factors instead of the ITU-R ones above.


The TinyColor library (you've already mentioned it) provides several functions for inspecting and manipulating colors, among them:

  • getBrightness

    Returns the perceived brightness of a color, from 0-255, as defined by Web Content Accessibility Guidelines (Version 1.0).

    tinycolor("#fff").getBrightness(); // 255
    
  • isLight

    Return a boolean indicating whether the color's perceived brightness is light.

    tinycolor("#fff").isLight(); // true
    tinycolor("#000").isLight(); // false
    
  • isDark

    Return a boolean indicating whether the color's perceived brightness is dark.

    tinycolor("#fff").isDark(); // false
    tinycolor("#000").isDark(); // true
    
  • getLuminance

    Returns the perceived luminance of a color, from 0-1 as defined by Web Content Accessibility Guidelines (Version 2.0).

    tinycolor("#fff").getLuminance(); // 1
    

  • You can compute the luminance:

    Luminance is thus an indicator of how bright the surface will appear.

    So it's great to choose if the text should be white or black.

    var getRGB = function(b){
        var a;
        if(b&&b.constructor==Array&&b.length==3)return b;
        if(a=/rgb(s*([0-9]{1,3})s*,s*([0-9]{1,3})s*,s*([0-9]{1,3})s*)/.exec(b))return[parseInt(a[1]),parseInt(a[2]),parseInt(a[3])];
        if(a=/rgb(s*([0-9]+(?:.[0-9]+)?)%s*,s*([0-9]+(?:.[0-9]+)?)%s*,s*([0-9]+(?:.[0-9]+)?)%s*)/.exec(b))return[parseFloat(a[1])*2.55,parseFloat(a[2])*2.55,parseFloat(a[3])*2.55];
        if(a=/#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(b))return[parseInt(a[1],16),parseInt(a[2],16),parseInt(a[3],
    16)];
        if(a=/#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(b))return[parseInt(a[1]+a[1],16),parseInt(a[2]+a[2],16),parseInt(a[3]+a[3],16)];
        return (typeof (colors) != "undefined")?colors[jQuery.trim(b).toLowerCase()]:null
    };
    
    var luminance_get = function(color) {
        var rgb = getRGB(color);
        if (!rgb) return null;
            return 0.2126 * rgb[0] + 0.7152 * rgb[1] + 0.0722 * rgb[2];
    }
    

    The method above allows you to pass the color in different formats, but the algorithm is basically just in luminance_get .

    When I used it, I was setting the color to black if the luminance was greater than 180 , white otherwise.

    链接地址: http://www.djcxy.com/p/87326.html

    上一篇: Android EditText文字颜色在输入过程中自动更改

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