将LAB颜色存储为整数
本文关键字:整数 存储 颜色 LAB | 更新日期: 2023-09-27 17:50:44
当使用RGB值时,. net已经建立了从整数转换的方法,将颜色转换为int很简单。是否有一种方法将LAB颜色存储为整数?与RGB不同,LAB颜色值可以是负值。如果我不需要RGB值,我不想在运行时将颜色存储为RGB并在运行时转换它们。
因此正在进行的转换是RGB -> XYZ,使用旧的2度观察者和CIE标准光源D65 -> 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