【JavaScript】sRGB色空間からLa*b*空間に変換する関数

【JavaScript】sRGB色空間からLa*b*空間に変換する関数:


概要

この記事では、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は、それぞれが「虚色」という色を示しています。名前がカッコいい(中二病)。 虚色とは物理的に存在しない仮想の色のことで、虚数のようなものです。xyzは、それぞれ次のような意味を持っています[3]。

  • x : 明るさを持たないが、赤みを持つ
  • y : 明るさと、緑みを持つ
  • z : 明るさを持たないが、青みを持つ
例えば、物理的に存在する色の場合、「明るさを持たない=黒=無彩色」となるため、明るさを持たないのに色みを持つものはあり得ません。逆に、色みを持つならば必ず明るさを持っているのです。

xyz色空間においては、明るさの成分を持つのが y だけなので、輝度である L へ変換するときには x や z が出てこないんですね。へー。


参考資料

コメント

このブログの人気の投稿

投稿時間:2021-06-17 05:05:34 RSSフィード2021-06-17 05:00 分まとめ(1274件)

投稿時間:2021-06-20 02:06:12 RSSフィード2021-06-20 02:00 分まとめ(3871件)

投稿時間:2020-12-01 09:41:49 RSSフィード2020-12-01 09:00 分まとめ(69件)