【JavaScript】sRGB色空間からLa*b*空間に変換する関数
【JavaScript】sRGB色空間からLa*b*空間に変換する関数:
この記事では、sRGB色空間からLa*b*色空間へ変換する関数を紹介しています(勉強がてらにメモしています)。この色空間たちは直接変換することができないため、一旦sRGBからxyz色空間に変換したのち、La*b*色空間へ変換しています。
RGBの値域は全て、0 ≦ x ≦ 1としています。
L の値域は、0 ≦ L ≦ 100、a* と b* の値域は、(sRGBから変換した場合) -0.86 ≦ a* ≦ 0.98, -1.07 ≦ b* ≦ 0.94 となります[1]。
(実際に動かして色味を見てみたところ、a*がマゼンタ⇔緑、b*が黄⇔青に対応していました)
xyz色空間から、La*b*色空間へ変換する際に、「ホワイトポイント」という言葉が現れます。これは、xyz色空間における「白色」をどの基準点とするかによって変化します。今回は(くわしくは知らないのですが)ベタそうなD65光源を基準としました。他にも、D50光源やD55光源というものもあるようです[2]。
xとy, zは、それぞれが「虚色」という色を示しています。名前がカッコいい(中二病)。 虚色とは物理的に存在しない仮想の色のことで、虚数のようなものです。xyzは、それぞれ次のような意味を持っています[3]。
xyz色空間においては、明るさの成分を持つのが y だけなので、輝度である L へ変換するときには x や z が出てこないんですね。へー。
概要
この記事では、sRGB色空間からLa*b*色空間へ変換する関数を紹介しています(勉強がてらにメモしています)。この色空間たちは直接変換することができないため、一旦sRGBからxyz色空間に変換したのち、La*b*色空間へ変換しています。
コード
function XYZtoLab(x, y, z) {
return XYZtoLab(...RGBtoXYZ(R, G, B));
}
function XYZtoLab(x, y, z) {
const x = 0.412391 * r + 0.357584 * g + 0.180481 * b;
const y = 0.212639 * r + 0.715169 * g + 0.072192 * b;
const z = 0.019331 * r + 0.119195 * g + 0.950532 * b;
return [x, y, z];
}
function XYZtoLab(x, y, z) {
// ホワイトポイントはD65光源とする。
x *= 100 / 95.047;
y *= 100 / 100;
z *= 100 / 108.883;
// x, y, z の補正式: ※ 0.008856 = Math.pow(6/29, 3), 7.787037 = 1 / (3 * Math.pow(6/29, 2))
let f = (value) => {
return value > 0.008856 ? Math.pow(value, 1 / 3) : (7.787037 * value) + (4 / 29);
}
[x, y, z] = [f(x), f(y), f(z)];
// xyz → La*b*変換式
let L = (116 * y) - 16;
let a = 500 * (x - y);
let b = 200 * (y - z);
return [L, a, b];
}
補足・解説
値域
RGBの値域は全て、0 ≦ x ≦ 1としています。L の値域は、0 ≦ L ≦ 100、a* と b* の値域は、(sRGBから変換した場合) -0.86 ≦ a* ≦ 0.98, -1.07 ≦ b* ≦ 0.94 となります[1]。
(実際に動かして色味を見てみたところ、a*がマゼンタ⇔緑、b*が黄⇔青に対応していました)
ホワイトポイントとは?
xyz色空間から、La*b*色空間へ変換する際に、「ホワイトポイント」という言葉が現れます。これは、xyz色空間における「白色」をどの基準点とするかによって変化します。今回は(くわしくは知らないのですが)ベタそうなD65光源を基準としました。他にも、D50光源やD55光源というものもあるようです[2]。
xyzの意味
xとy, zは、それぞれが「虚色」という色を示しています。- x : 明るさを持たないが、赤みを持つ
- y : 明るさと、緑みを持つ
- z : 明るさを持たないが、青みを持つ
xyz色空間においては、明るさの成分を持つのが y だけなので、輝度である L へ変換するときには x や z が出てこないんですね。へー。
コメント
コメントを投稿