What is the efficient way to calculate human eye contrast difference for RGB values?

前端 未结 5 1115
太阳男子
太阳男子 2020-12-11 09:35

In order to check if two colors in grayscale will be too close to be distinguished by the human eye. I want to be able to generate a warning to the user if \'dangerous\' col

5条回答
  •  一整个雨季
    2020-12-11 09:56

    Maybe this is something that can help. (Pulled from yea dusty olde js crypt).

    I believe this was initially developed to mathematically determine if text color on color background is actually readable.

    Color Contrast

    Defined by (WCAG Version 2)

    http://www.w3.org/TR/2008/REC-WCAG20-20081211

    Contrast ratios can range from 1 to 21

    section 1.4.3

    • Highly Visible: (enhanced) Minimum contrast ratio of 7 to 1 -- 7:1
    • Normal Text: Minimum contrast ratio of 4.5 to 1 -- 4.5:1
    • Large Text: Minimum contrast ratio of 3 to 1 -- 3:1

    This contrastRatio function spits out a number between 1 and 21, which serves as the first number in the ratio.

    e.g. n:1 where "n" is the result of this method

    The higher the number, the more readable it is.

    function getLum(rgb) {
    
        var i, x;
        var a = []; // so we don't mutate
        for (i = 0; i < rgb.length; i++) {
            x = rgb[i] / 255;
            a[i] = x <= 0.03928 ? x / 12.92 : Math.pow((x + 0.055) / 1.055, 2.4);
        }
        return 0.2126 * a[0] + 0.7152 * a[1] + 0.0722 * a[2];
    
    }
    
    
    var RE_HEX_RGB = /[a-f0-9]{6}|[a-f0-9]{3}/i;
    
    function HEX_RGB(str) {
        var match = str.toString(16).match(RE_HEX_RGB);
        if (!match) {
            return [0, 0, 0];
        }
    
        var colorString = match[0];
    
        // Expand 3 character shorthand triplet e.g. #FFF -> #FFFFFF
        if (match[0].length === 3) {
            var Astr = colorString.split('');
            for (var i = 0; i < Astr.length; i++) {
                var ch = Astr[i];
                Astr[i] = ch + ch;
            }
            colorString = Astr.join('');
        }
    
        var integer = parseInt(colorString, 16);
    
        return [
            (integer >> 16) & 0xFF,
            (integer >> 8) & 0xFF,
            integer & 0xFF
        ];
    };
    
    
    function contrastRatio(rgb1, rgb2) {
        var l1 = getLum(rgb1);
        var l2 = getLum(rgb2);
        return (Math.max(l1, l2) + 0.05) / (Math.min(l1, l2) + 0.05);
    }
    
    
    var c1 = '#9d5fb0';
    var c2 = '#318261';
    
    var cr = contrastRatio( HEX_RGB(c1), HEX_RGB(c2) );
    console.log("cr", cr);
    

提交回复
热议问题