首页
学习
活动
专区
圈层
工具
发布

HSL插值
EN

Stack Overflow用户
提问于 2009-09-13 00:53:22
回答 3查看 3.5K关注 0票数 3

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

让我们:

红色= 0°

黄色= 60°

蓝色= 240°

(红色+黄色)/2= 30°(橙色)

(黄色+蓝色)/2= 150°(蓝色绿色)

(红色+蓝色)/2= 120°(绿色)

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

红色= 360°

黄色= 60°

蓝色= 240°

(红色+黄色)/2= 210°(蓝色、绿色)

(黄色+蓝色)/2= 150°(蓝色绿色)

(红色+蓝色)/2= 300°(洋红色)

现在,红色和蓝色产生预期的颜色,而红色和黄色产生蓝绿色!我如何插值颜色的色调分量,以便结果与混合实际涂料时所期望的结果相匹配?谢谢!

EN

回答 3

Stack Overflow用户

发布于 2009-09-13 04:11:13

你这样做基本上是为了得到我认为你想要的东西,这是一种看起来介于两个输入之间的中间颜色,但你只需要处理这样一个事实,即这个计算是在一个环绕的圆上完成的。(我假设您并不真的想要“像颜料一样混合”,而只是想要一种中档颜色--也就是说,您不想让红色和绿色变成棕色,对吧?)

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

代码语言:javascript
复制
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)

产生:

代码语言:javascript
复制
0 60    30.0
60 239  149.5  # 60, 240 is ambiguous
60 241  330.5
0 240   300.0
350 30  10.0

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

票数 3
EN

Stack Overflow用户

发布于 2009-09-13 05:57:09

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

例如,

红色= 0°或360°

黄色= 60°或420°

蓝色= 240°或600°

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

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

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

票数 1
EN

Stack Overflow用户

发布于 2009-09-13 01:23:27

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

编辑:刚刚看到“可能会混合实际的油漆”

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

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1416560

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档