将LAB颜色存储为整数

时间:2013-01-05 19:32:13

标签: c# serialization colors rgb

使用RGB值时,.NET内置了从整数转换的方法,并且可以直接将颜色转换为int。有没有办法将LAB颜色存储为整数?与RGB不同,LAB颜色值可以为负值。我不想将颜色存储在RGB中并在运行时转换它们,如果我可以避免它,因为我不需要RGB值。

1 个答案:

答案 0 :(得分:1)

所以正在进行的转换是RGB - >具有旧的2度观察者和CIE标准光源D65的XYZ - > CIELAB。下面给出了用于执行的参考代码(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.如果你可以保留三个有符号的短整数,事情会变得更简单。

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