Algorithm HSL插值

Algorithm HSL插值,algorithm,colors,interpolation,color-picker,hsl,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=15

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

让我们:

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

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

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

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

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


现在,红色和蓝色产生预期的颜色,但红色和黄色产生蓝绿色!我可以用什么方法插值颜色的色调成分,使结果与混合实际颜料的预期结果相匹配?谢谢

您可能不想听这个,但要转换为RGB,插值并转换回来

编辑:刚刚看到的“预计将混合实际油漆”


在这种情况下,您可能希望转换为CMY颜色空间,而不是RGB。看一看。

基本上你做得很好,得到了我假设你想要的颜色,这是一种介于两个输入之间的颜色,但你只需要处理这样一个事实,即这个计算是在一个包裹的圆上完成的。(我假设你并不真的想要“像油漆一样混合”,而是想要一种中档颜色——也就是说,你不想让红色和绿色变成棕色,对吧?)

下面是一个Python函数,它将拾取圆上两个角度之间的角度。它基本上只是尝试两个选项(添加360或不添加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)

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

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

比如说,

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

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

红色和蓝色的最小距离为60(红色360蓝色240),因此插值应为300。

这是正确答案。原始问题中的问题是,当原始值相距超过180d时,“平均值”实际上位于圆的错误一侧(或180d错误)。这里实现的解决方案是尝试avg和avg+180d,并使用更接近的一个。HLS实际上是一个更好的模型。
0 60    30.0
60 239  149.5  # 60, 240 is ambiguous
60 241  330.5
0 240   300.0
350 30  10.0