背景色を任意にしつつ、見やすい文字色は白か黒のどちらか。それを算出したい。
成果物
少数による計算が必要だが、bashでは整数でしか計算できない。ので、pythonで実装した。
情報源
2色のコントラスト値が4.5以上なら見やすい。4.5以下なら見づらい。
実装をみる
contrast.js
module.exports = (a, b) => { // WCAG contrast ratio // see http://www.w3.org/TR/2008/REC-WCAG20-20081211/#contrast-ratiodef a = new Color(a); b = new Color(b); const l1 = a.luminance(); const l2 = b.luminance(); return l1 > l2 ? (l1 + 0.05) / (l2 + 0.05) : (l2 + 0.05) / (l1 + 0.05); }
luminance.js
Color.prototype.luminance = function(lum) { if (lum !== undefined && type(lum) === 'number') { if (lum === 0) { // return pure black return new Color([0,0,0,this._rgb[3]], 'rgb'); } if (lum === 1) { // return pure white return new Color([255,255,255,this._rgb[3]], 'rgb'); } // compute new color using... let cur_lum = this.luminance(); let mode = 'rgb'; let max_iter = MAX_ITER; const test = (low, high) => { const mid = low.interpolate(high, 0.5, mode); const lm = mid.luminance(); if (Math.abs(lum - lm) < EPS || !max_iter--) { // close enough return mid; } return lm > lum ? test(low, mid) : test(mid, high); } const rgb = (cur_lum > lum ? test(new Color([0,0,0]), this) : test(this, new Color([255,255,255]))).rgb(); return new Color([...rgb,this._rgb[3]]); } return rgb2luminance(...(this._rgb).slice(0,3)); } const rgb2luminance = (r,g,b) => { // relative luminance // see http://www.w3.org/TR/2008/REC-WCAG20-20081211/#relativeluminancedef r = luminance_x(r); g = luminance_x(g); b = luminance_x(b); return 0.2126 * r + 0.7152 * g + 0.0722 * b; } const luminance_x = (x) => { x /= 255; return x <= 0.03928 ? x/12.92 : pow((x+0.055)/1.055, 2.4); }
対象環境
- Raspbierry pi 4 Model B
- Raspberry Pi OS buster 10.0 2020-08-20 ※
- bash 5.0.3(1)-release
$ uname -a Linux raspberrypi 5.4.83-v7l+ #1379 SMP Mon Dec 14 13:11:54 GMT 2020 armv7l GNU/Linux