Bashで行いたかったが少数計算ができないためPythonで実装する。
成果物
参考
Lab, XYZ表色系を仲介するようだ。
コード
const lch2rgb = (...args) => { args = unpack(args, 'lch'); const [l,c,h] = args; const [L,a,b_] = lch2lab (l,c,h); const [r,g,b] = lab2rgb (L,a,b_); return [r, g, b, args.length > 3 ? args[3] : 1]; }
const lch2lab = (...args) => { let [l,c,h] = unpack(args, 'lch'); if (isNaN(h)) h = 0; h = h * DEG2RAD; return [l, cos(h) * c, sin(h) * c] }
DEG2RAD: PI / 180,
const lab2rgb = (...args) => { args = unpack(args, 'lab'); const [l,a,b] = args; let x,y,z, r,g,b_; y = (l + 16) / 116; x = isNaN(a) ? y : y + a / 500; z = isNaN(b) ? y : y - b / 200; y = LAB_CONSTANTS.Yn * lab_xyz(y); x = LAB_CONSTANTS.Xn * lab_xyz(x); z = LAB_CONSTANTS.Zn * lab_xyz(z); r = xyz_rgb(3.2404542 * x - 1.5371385 * y - 0.4985314 * z); // D65 -> sRGB g = xyz_rgb(-0.9692660 * x + 1.8760108 * y + 0.0415560 * z); b_ = xyz_rgb(0.0556434 * x - 0.2040259 * y + 1.0572252 * z); return [r,g,b_,args.length > 3 ? args[3] : 1]; }; const xyz_rgb = (r) => { return 255 * (r <= 0.00304 ? 12.92 * r : 1.055 * pow(r, 1 / 2.4) - 0.055) } const lab_xyz = (t) => { return t > LAB_CONSTANTS.t1 ? t * t * t : LAB_CONSTANTS.t2 * (t - LAB_CONSTANTS.t0) }
module.exports = { // Corresponds roughly to RGB brighter/darker Kn: 18, // D65 standard referent Xn: 0.950470, Yn: 1, Zn: 1.088830, t0: 0.137931034, // 4 / 29 t1: 0.206896552, // 6 / 29 t2: 0.12841855, // 3 * t1 * t1 t3: 0.008856452, // t1 * t1 * t1 }
所感
これくらいライブラリがあっても良かったと思う。たぶん誰かそのうち作ってくれるはず。それまで自前のこれでなんとかする。
対象環境
- 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