Javascript 如何以编程方式计算两种颜色之间的对比度?

Javascript 如何以编程方式计算两种颜色之间的对比度?,javascript,validation,colors,Javascript,Validation,Colors,非常直截了当,以黄色和白色为例: back_color = {r:255,g:255,b:255}; //white text_color = {r:255,g:255,b:0}; //yellow 在上帝的地球上,宇宙常数的物理定律是什么,使得黄色文本不能在白色背景下阅读,而蓝色文本可以阅读 为了我的可定制小部件,我尝试了所有可能的颜色模型,我找到了转换函数;基于数字比较,两者都不能说绿色可以在白色上,黄色不能 我看了看Adsense(由全互联网的佛陀创建),猜猜他们做了什么,他们进行了预设

非常直截了当,以黄色和白色为例:

back_color = {r:255,g:255,b:255}; //white
text_color = {r:255,g:255,b:0}; //yellow
在上帝的地球上,宇宙常数的物理定律是什么,使得黄色文本不能在白色背景下阅读,而蓝色文本可以阅读

为了我的可定制小部件,我尝试了所有可能的颜色模型,我找到了转换函数;基于数字比较,两者都不能说绿色可以在白色上,黄色不能


我看了看Adsense(由全互联网的佛陀创建),猜猜他们做了什么,他们进行了预设和彩色单元格距离计算。我不能做那件事。我的用户有权选择哪怕是最刺激视网膜、最不美观的组合,只要文本仍然可以阅读。

根据维基百科的说法,当转换为灰度亮度表示时,“必须获得其红色、绿色和蓝色的值”,并按下一个比例混合:R:30%G:59%B:11%

因此,白色的亮度为100%,黄色的亮度为89%。同时,绿色的比例也只有59%。11%几乎是41%差异的四倍

即使是石灰(
#00ff00
)也不适合阅读大量文本

对于对比度好的颜色,其亮度应至少相差50%。这个亮度应该转换成灰度来测量

upd:最近在网上找到了一个 按顺序使用来自 阈值可以从 这里是这个更高级的东西的一个实现

function luminance(r, g, b) {
    var a = [r, g, b].map(function (v) {
        v /= 255;
        return v <= 0.03928
            ? v / 12.92
            : Math.pow( (v + 0.055) / 1.055, 2.4 );
    });
    return a[0] * 0.2126 + a[1] * 0.7152 + a[2] * 0.0722;
}
function contrast(rgb1, rgb2) {
    var lum1 = luminance(rgb1[0], rgb1[1], rgb1[2]);
    var lum2 = luminance(rgb2[0], rgb2[1], rgb2[2]);
    var brightest = Math.max(lum1, lum2);
    var darkest = Math.min(lum1, lum2);
    return (brightest + 0.05)
         / (darkest + 0.05);
}
contrast([255, 255, 255], [255, 255, 0]); // 1.074 for yellow
contrast([255, 255, 255], [0, 0, 255]); // 8.592 for blue
// minimal recommended contrast ratio is 4.5, or 3 for larger font-sizes
功能亮度(r、g、b){
变量a=[r,g,b].map(函数(v){
v/=255;

return v计算对比度有多种方法,但常用的方法是以下公式:

brightness = (299*R + 587*G + 114*B) / 1000

对两种颜色都这样做,然后取其差异。这显然会使蓝白对比度比黄白对比度大得多。

最近我在这页上找到了答案,我使用代码为Adobe Illustrator编写了一个脚本来计算对比度

在这里您可以看到结果:

上面脚本的一些速记符号让我感到困惑,并且无法在Adobe extend脚本中工作。因此,我认为分享我对kirilloid共享的代码的改进/解释会很好

function luminance(r, g, b) {
    var colorArray = [r, g, b];
    var colorFactor;
    var i;
    for (i = 0; i < colorArray.length; i++) {
        colorFactor = colorArray[i] / 255;
        if (colorFactor <= 0.03928) {
            colorFactor = colorFactor / 12.92;
        } else {
            colorFactor = Math.pow(((colorFactor + 0.055) / 1.055), 2.4);
        }
        colorArray[i] = colorFactor;
    }
    return (colorArray[0] * 0.2126 + colorArray[1] * 0.7152 + colorArray[2] * 0.0722) + 0.05;
}
功能亮度(r、g、b){
var colorArray=[r,g,b];
var颜色因子;
var i;
对于(i=0;i如果(颜色因子基于kirilloid答案:

通过传入十六进制值计算对比度和发光的角度服务:

.service('ColorContrast', [function() {
var self = this;

/**
 * Return iluminance value (base for getting the contrast)
 */
self.calculateIlluminance = function(hexColor) {
    return calculateIluminance(hexColor);
};

/**
 * Calculate contrast value to white
 */
self.contrastToWhite = function(hexColor){
    var whiteIlluminance = 1;
    var illuminance = calculateIlluminance(hexColor);
    return whiteIlluminance / illuminance;
};

/**
* Bool if there is enough contrast to white
*/
self.isContrastOkToWhite = function(hexColor){
    return self.contrastToWhite(hexColor) > 4.5;
};

/**
 * Convert HEX color to RGB
 */
var hex2Rgb = function(hex) {
    var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
    return result ? {
        r: parseInt(result[1], 16),
        g: parseInt(result[2], 16),
        b: parseInt(result[3], 16)
    } : null;
};

/**
 * Calculate iluminance
 */
var calculateIlluminance = function(hexColor) {
    var rgbColor = hex2Rgb(hexColor);
    var r = rgbColor.r, g = rgbColor.g, b = rgbColor.b;
    var a = [r, g, b].map(function(v) {
        v /= 255;
        return (v <= 0.03928) ?
            v / 12.92 :
            Math.pow(((v + 0.055) / 1.055), 2.4);
    });
    return a[0] * 0.2126 + a[1] * 0.7152 + a[2] * 0.0722;
};

}]);
.service('ColorContrast',[function()){
var self=这个;
/**
*返回i亮度值(获取对比度的基准)
*/
self.calculateIlluminance=函数(hexColor){
返回计算亮度(hexColor);
};
/**
*计算白色的对比度值
*/
self.ContractToWhite=函数(hexColor){
var白照度=1;
var照度=计算照度(六色);
返回白照度/照度;
};
/**
*如果与白色有足够的对比度,则为Bool
*/
self.isContrastowhite=函数(hexColor){
返回自身对比度白色(hexColor)>4.5;
};
/**
*将十六进制颜色转换为RGB
*/
var hex2Rgb=函数(十六进制){
var result=/^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(十六进制);
返回结果{
r:parseInt(结果[1],16),
g:parseInt(结果[2],16),
b:parseInt(结果[3],16)
}:null;
};
/**
*计算照度
*/
var calculateIlluminance=函数(hexColor){
var rgbColor=hex2Rgb(hexColor);
var r=rgbColor.r,g=rgbColor.g,b=rgbColor.b;
变量a=[r,g,b].map(函数(v){
v/=255;
返回(v

常量GetLuminance=(值)=>{
常量rgb=值。映射((v)=>{
常数val=v/255;
返回值{
const lumA=getluminace(colorA);
const lumB=getluminace(colorB);
返回值(数学最大值(lumA,lumB)+0.05)/(数学最小值(lumA,lumB)+0.05);
};
//用法:
const back_color=[255255255];//白色
常量文本颜色=[255255,0];//黄色
GetContractRatio(背面颜色、文本颜色);/1.0736196319018405

这样,用户就可以选择任何两种颜色,只要它们的对比度是可读的?从技术角度来看,我觉得这很有趣,但如果用户有“正确”的颜色,则更实用选择任何颜色为什么你甚至关心它是否可以阅读?这不是由他们自己决定的吗?@nnnnnnnn我真的不在乎他们选择什么颜色,他们可以随心所欲地混合,但我关心的是(c)的可读性2012年的Company Inc.是。我建立了一个JSFIDLE来亲自看看答案有多准确,他们确实能够很好地预测可读性:如果有人错过了邵康的回答,.+1是真的。在现实生活中,转换为灰度来检查设计的可读性是必须做的(特别是对于徽标)。我会选择这个答案作为解决方案,因为它是最全面的,我不能选择两个解决方案;但我会选择Hondasukishaolinshaorma的答案,因为它提供了现成的代码。
对比度([255,255,255],[0,0,255])
返回8.592,相同的数字反转
对比度([0,0,255],[255,255])
返回0.116–即1/8.592。要获得介于1和21之间的对比度,如果输出小于1,则需要将1除以输出。
函数对比度(rgb1,rgb2){var result=(亮度(rgb1[0],rgb1[1],rgb1[2])+0.05)/(亮度(rgb2[0],rgb2[1],rgb2[2])+0.05);如果(结果<1)result=1/result;return result;}
这里有一个小错误:
返回(亮度(rgb1[0]、rgb1[1]、rgb1[2])+0.05)/(亮度(rgb2[0]、rgb2[1]、rgb2[2])+0.05)
。您必须将较大的值除以较小的值。最好使用这个:
l1=亮度(rgb1[0]、rgb1[
module.exports = function colorcontrast (hex) {
    var color = {};

    color.contrast = function(rgb) {
        // check if we are receiving an element or element background-color
        if (rgb instanceof jQuery) {
            // get element background-color
            rgb = rgb.css('background-color');
        } else if (typeof rgb !== 'string') {
            return;
        }

        // Strip everything except the integers eg. "rgb(" and ")" and " "
        rgb = rgb.split(/\(([^)]+)\)/)[1].replace(/ /g, '');

        // map RGB values to variables
        var r = parseInt(rgb.split(',')[0], 10),
            g = parseInt(rgb.split(',')[1], 10),
            b = parseInt(rgb.split(',')[2], 10),
            a;

        // if RGBA, map alpha to variable (not currently in use)
        if (rgb.split(',')[3] !== null) {
            a = parseInt(rgb.split(',')[3], 10);
        }

        // calculate contrast of color (standard grayscale algorithmic formula)
        var contrast = (Math.round(r * 299) + Math.round(g * 587) + Math.round(b * 114)) / 1000;

        return (contrast >= 128) ? 'black' : 'white';
    };

    // Return public interface
    return color;

};
.service('ColorContrast', [function() {
var self = this;

/**
 * Return iluminance value (base for getting the contrast)
 */
self.calculateIlluminance = function(hexColor) {
    return calculateIluminance(hexColor);
};

/**
 * Calculate contrast value to white
 */
self.contrastToWhite = function(hexColor){
    var whiteIlluminance = 1;
    var illuminance = calculateIlluminance(hexColor);
    return whiteIlluminance / illuminance;
};

/**
* Bool if there is enough contrast to white
*/
self.isContrastOkToWhite = function(hexColor){
    return self.contrastToWhite(hexColor) > 4.5;
};

/**
 * Convert HEX color to RGB
 */
var hex2Rgb = function(hex) {
    var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
    return result ? {
        r: parseInt(result[1], 16),
        g: parseInt(result[2], 16),
        b: parseInt(result[3], 16)
    } : null;
};

/**
 * Calculate iluminance
 */
var calculateIlluminance = function(hexColor) {
    var rgbColor = hex2Rgb(hexColor);
    var r = rgbColor.r, g = rgbColor.g, b = rgbColor.b;
    var a = [r, g, b].map(function(v) {
        v /= 255;
        return (v <= 0.03928) ?
            v / 12.92 :
            Math.pow(((v + 0.055) / 1.055), 2.4);
    });
    return a[0] * 0.2126 + a[1] * 0.7152 + a[2] * 0.0722;
};

}]);