如何通过HSL颜色进行着色?

3

我有一个复杂的问题,但可以通过解决这个小问题来解决。 我想制作一个逐像素工作的着色器。

我有一张图片,定义了基础颜色(图片中有一些像素具有这种颜色,还有很多其他接近这种颜色的像素):

Hex: #188DD9
HSL: 204° 80% 47%
RGB: 24 141 217

我知道我的目标基础颜色:
Hex: #23752E
HSL: 128° 54% 30%
RGB: 35 117 46

所以,我想要给一张图片上色。

我的假设是,如果我找到这两个HSL值之间的相关性,我就可以逐像素地对我的图片进行上色。

目前,我发现如果我将基础颜色色调移动(目标色调 - 基础色调)= -76,那么色调就会正常。

您能告诉我如何联系饱和度和亮度来解决这个问题吗?

1个回答

2
我假设无论您最终使用哪种映射,都希望将黑色映射为黑色,白色映射为白色,灰色映射为灰色。
对于色调,您使用的加性映射(带环绕)可能确实很好。对于饱和度,需要保留灰色值,建议使用乘性映射,如下所示:
S' = S * (Starget / Sbase)
超过100%饱和度的值将被剪切。然而,对于亮度,线性映射并不能胜任,因为您想要同时修复0%和100%的亮度,同时调整中间值。一个自然的选择可能是gamma类型的映射,即
L' = pow( L, log(Ltarget) / log(Lbase) ) = exp( log(L) * log(Ltarget) / log(Lbase) )。

将亮度值缩放到0和1之间。(注意:为了高效地计算大量像素的此映射,您可能需要预先计算一个查找表,例如256个条目。)

当然,还有很多其他映射可以使用,但我建议从这些开始,看看它们是否能够产生足够好的结果。请注意,最终,您的结果的质量也可能受到HSL颜色空间的感知不均匀性的限制;有关详细信息,请参见此维基百科页面


谢谢!它运行得很好。我只做了一个改进。对于一些接近末尾颜色(红色、绿色或蓝色)的目标值,在着色后会出现错误的颜色。改进是:在计算S'之前,如果(S > Sbase),则将S = Sbase; - Roland Soós
你是否尝试过使用 if (S' > Smax) S' = Smax;,其中Smax是您的最大有效饱和度(通常为1.0、100或255)。另外,我建议使用long int或float进行中间计算,否则可能会遇到算术溢出问题。此外,如果使用整数,请记得先进行乘法运算再进行除法运算。 - Ilmari Karonen
不,我之前没有尝试过。现在我尝试了一下,结果和你的解决方案一样,很合理。 :) 再次感谢! - Roland Soós

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接