【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 が出てこないんですね。へー。
コメント
コメントを投稿