2012-03-16 36 views
34

漂亮的直线前进,以黄色和白色:如何以编程方式计算两种颜色之间的对比度?

back_color = {r:255,g:255,b:255}; //white 
text_color = {r:255,g:255,b:0}; //yellow 

什么法律上的通用常量的上帝在地球物理学,使得事实,黄色文本无法在白色背景读取,但蓝色文本可以吗?

为了我的可定制小部件,我尝试了所有可能的颜色模型,我找到了转换函数;根据数字比较,也不能说绿色可以是白色,黄色不能。

我看着Adsense(它是由所有互联网的Budda创建的),并猜测他们做了什么,他们做了预设和颜色单元格的距离计算。我不能那样做。只要文本仍然可以阅读,我的用户就有权选择最敏感的视网膜炎症,不美观的组合。

+0

所以用户可以任意选择两种颜色,只要它们是可读的对比? – DanRedux 2012-03-16 07:13:25

+0

从技术的角度来看,我觉得这很有趣,但更实际的是,如果用户有选择任何颜色的“正确”,为什么你甚至在乎它是否可以读取?他们没有把它做好吗? – nnnnnn 2012-03-16 07:19:05

+0

@nnnnnn我并不在乎他们选择什么颜色,他们可以混合他们想要的任何东西,但我关心(c)2012年公司的可读性。 – 2012-03-16 07:42:54

回答

38

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

因此,白色将具有100%的亮度,而黄色将具有89%。与此同时,绿色只有59%。 11%几乎比41%的差距低四倍!

甚至石灰(#00ff00)不适合阅读大量的文本。

恕我直言,对于良好的对比度颜色的亮度应该至少有50%不同。这个亮度应该转换成灰度来测量。

UPD:最近发现了一个comprehensive tool网络 其中,为了使用从w3 document 的阈值公式可以从#1.4 可以采取下面是该更先进的东西的实现。

function luminanace(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) { 
    return (luminanace(rgb1[0], rgb1[1], rgb1[2]) + 0.05) 
     /(luminanace(rgb2[0], rgb2[1], rgb2[2]) + 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 
+1

+1这是真的。在现实生活中 - 转换为灰度来检查设计的可读性是必须做的(特别是徽标)。 – 2012-03-16 07:29:01

+0

我会选择这个答案作为解决方案,因为它是最全面的,我不能选择两种解决方案;但我会选择HondaSuzukiShaolinShaorma的答案,因为它提供了随时可用的代码。 – 2012-03-16 07:38:08

+0

是的,我也喜欢他的回答=) – kirilloid 2012-03-16 07:40:52

16

有计算对比不同的方式,而是一种常见的方式是这样的公式:

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

你为两种颜色做到这一点,然后你走差异。这显然给白色上的蓝色比白色上的黄色更大。

0

最近我在这个页面上看到了答案,我用代码为Adobe Illustrator制作脚本来计算对比度。

在这里你可以看到的结果是:http://screencast.com/t/utT481Ut

上面的一些混乱的地方,我和其中在Adobe工作不延长脚本脚本的速记符号的。因此,我认为分享我对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; 
} 

当然,你需要调用这个函数

在for循环内我得到的所有从我的插画物体的颜色

//just a snippet here to demonstrate the notation 
var selection = app.activeDocument.selection; 
for (i = 0; i < selection.length; i++) { 
    red[i] = selection[i].fillColor.red; 
    //I left out the rest,because it would become to long 
} 

//this can then be used to calculate the contrast ratio. 
var foreGround = luminance(red[0], green[0], blue[0]); 
var background = luminance(red[1], green[1], blue[1]); 
luminanceValue = foreGround/background; 
luminanceValue = round(luminanceValue, 2); 

//for rounding the numbers I use this function: 
function round(number, decimals) { 
    return +(Math.round(number + "e+" + decimals) + "e-" + decimals); 
} 
约对比度

的更多信息:http://webaim.org/resources/contrastchecker/

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

}; 
+0

这看起来不错,但为什么'colorcontrast'方法接受'hex'参数,但是这个参数没有被使用? – ctlockey 2018-03-09 15:02:44

0

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

}]); 
相关问题