HSL插值

时间:2009-09-13 00:53:22

标签: algorithm colors interpolation color-picker hsl

如果我的HSL颜色的色调分量是度数,我怎样才能在两种色调之间正确插值?在所有情况下使用(h1 + h2)/ 2似乎都不会产生理想的结果。以下两个例子说明了原因:

让:

红色= 0°
黄色= 60°
蓝色= 240°

(红色+黄色)/ 2 = 30°(橙色)
(黄色+蓝色)/ 2 = 150°(蓝绿色)
(红色+蓝色)/ 2 = 120°(绿色)

正如你所看到的,平均红色和蓝色产生绿色而不是紫色/洋红色!但是,如果我们让:

红色= 360°
黄色= 60°
蓝色= 240°

(红色+黄色)/ 2 = 210°(蓝绿色)
(黄色+蓝色)/ 2 = 150°(蓝绿色)
(红色+蓝色)/ 2 = 300°(品红色)

现在,红色和蓝色产生预期的颜色,但红色和黄色产生蓝绿色!我可以以什么方式插入颜色的色调分量,以便结果与混合实际涂料的结果相匹配?谢谢!

3 个答案:

答案 0 :(得分:3)

你基本上这样做是为了获得我想要的东西,这是一种看起来在你的两个输入之间的中间颜色,但你只需要处理这个计算是在一个包裹的圆上完成的事实。 (我假设你不是真的想要“混合像油漆”而只是中等颜色 - 即你不想要红色和绿色给棕色,对吗?)

这是一个Python函数,它将选择圆上两个角度之间的角度。它基本上只是尝试两个选项(添加或不添加360)并选择一个最接近原始角度的角度:

pairs = [(0, 60), (60, 239), (60, 241), (0, 240), (350, 30)]

def circ_ave(a0, a1):
    r = (a0+a1)/2., ((a0+a1+360)/2.)%360 
    if min(abs(a1-r[0]), abs(a0-r[0])) < min(abs(a0-r[1]), abs(a1-r[1])):
        return r[0]
    else:
        return r[1]

for a0, a1 in pairs:
    print a0, a1, circ_ave(a0, a1)

产生

0 60    30.0
60 239  149.5  # 60, 240 is ambiguous
60 241  330.5
0 240   300.0
350 30  10.0

(我觉得应该有一种更简单的方法来进行此计算,但我没有想到。)

答案 1 :(得分:1)

你可能不想听到这个,但转换为RGB,插值并转换回来。

编辑刚刚看到“会混合实际油漆”

在这种情况下,您可能希望转换为CMY色彩空间而不是RGB。看看colour mixing on Wikipedia

答案 2 :(得分:1)

对于每个颜色值x, x < 360,它可以是xx+360。然后你有4对颜色值。如果找到最小距离对,则使用该对来插值颜色。它可能会给你正确的视觉效果。

例如,

红色= 0°或360°
黄色= 60°或420°
蓝色= 240°或600°

红色和黄色的最小距离为60(红色0黄色60),因此插值应为30 黄色和蓝色的最小距离为180(黄色60蓝色240),因此插值应为150 红色和蓝色的最小距离为60(红色360蓝色240),因此插值应为300.