2012-03-16 37 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; 
}; 

}]); 
相關問題