将HSL转换为RGB

时间:2012-02-16 22:37:35

标签: haskell colors rgb hsl

我尝试使用Data.Colour模块将某些HSL值转换为RBG。 Hackage doc说Hue总是在0-360范围内。但现在有SaturationLightness值范围。它们是[0,100]还是[0,1]范围?

我认为第一种变体是正确的,但似乎不是。

λ> hsl 100 50 50
RGB {channelRed = 866.6666666666692, channelGreen = -2400.0, channelBlue = 2500.0}

我尝试将范围[0,1]用于饱和度和亮度。

λ> fmap truncate . (\(h,s,l) -> hsl h s l) $ (0,0,0)
RGB {channelRed = 0, channelGreen = 0, channelBlue = 0}
it :: RGB Integer

这就是为什么我开始认为只有Saturation应该是Double中的[0,1]

例如,我们有一些HSL格式的颜色值。

λ> let c = (34.0,0.54,68.0)
c :: (Double, Double, Double)

我们将其转换为RGB并截断所有值

λ> fmap truncate . (\(h,s,l) -> hsl h s l) $ c
RGB {channelRed = 31, channelGreen = 63, channelBlue = 104}

但是(31,63,104)::RGB (214,54,26)::HSL就像some online color-converters所说的那样。

我做错了什么?

2 个答案:

答案 0 :(得分:5)

看起来封装对亮度和饱和度使用范围[0, 1],但请注意,它也使用此范围用于RGB值,而不是[0, 255],因为您似乎在假设。考虑到这一点,我得到(几乎)预期值:

> fmap (truncate . (* 255)) $ hsl 214 0.54 0.26
RGB {channelRed = 30, channelGreen = 61, channelBlue = 102}

答案 1 :(得分:1)

所以最后我发现SaturationLightness值都应该在[0,1]范围内。

λ> fmap (round . (255*)). (\(h,s,l) -> hsl h s l) $ (34.0,0.54,0.68)
RGB {channelRed = 217, channelGreen = 179, channelBlue = 129}
it :: RGB Integer

这是有道理的,因为(217,179,129)::RGB值等于(34,54,68)::HSL

因此,在文档中添加约束可能会有所帮助。