1

RGB 値を使用する場合、.NET には整数から変換する方法が組み込まれており、色を int に変換するのは簡単です。代わりに LAB カラーを整数として保存する方法はありますか? RGB とは異なり、LAB カラー値は負になる場合があります。RGB 値を必要としないため、避けることができれば、色を RGB で保存して実行時に変換する必要はありません。

4

1 に答える 1

3

したがって、行われている変換は、RGB -> 古い 2 度の観測者と CIE 標準光源 D65 -> CIELAB を使用した XYZ です。参考までに、それを実行するためのコードを以下に示します (R、G、B は [0, 1] にあると想定されます)。

RGB でチャネルあたり 8 ビットから始まるこれらの変換を考慮すると、L* の範囲は [0, 100]、a* (-85.92, 97.96]、b* (-107.54, 94.20]) です。これらの値は近似値です。理論的には、a* および b* は無制限ですが、+-128、+-110 などの制限について説明している場所がいくつかあります。私の提案は、128 を各値に単純に合計し、100 を掛けてから、整数に丸めます (これは色に対して十分正確でなければなりません). 与えられた L*a*b トリプレットは 16 ビットの符号なし整数で表すことができます. それらを 64 ビットの整数にパックすることができます. そしてアンパックした後, 128 を引きます.各値から 3 つの符号付き短整数を保持できる場合、物事ははるかに簡単になります。

def rgb_xyz(r, g, b): # 2o. D65
    triple = [r, g, b]

    v, d = 0.04045, 12.94
    for i, c in enumerate(triple):
        triple[i] = 100 * (c / d if c <= v else ((c + 0.055)/1.055)**2.4)

    multipliers = (
            (0.4124, 0.3576, 0.1805),
            (0.2126, 0.7152, 0.0722),
            (0.0193, 0.1192, 0.9505))

    x, y, z = [sum(row[i] * triple[i] for i in range(3))
            for row in multipliers]
    return x, y, z

def xyz_cielab(x, y, z):
    triple = [x, y, z]

    t0, a, b = 0.008856, 7.787, 16/116.
    ref = (95.047, 100.0, 108.883)
    for i, c in enumerate(triple):
        triple[i] /= ref[i]
        c = triple[i]
        triple[i] = c ** (1/3.) if c > t0 else a * c + b

    l = 116 * triple[0] - 16
    a = 500 * (triple[0] - triple[1])
    b = 200 * (triple[1] - triple[2])
    return l, a, b
于 2013-01-05T22:36:34.780 に答える