gtk2hs - 将颜色转换为十六进制三元组

时间:2014-07-12 00:18:22

标签: haskell gtk rgb gtk2hs color-depth

我使用gtk2hs在Haskell工作,遇到了一个我无法找到答案的问题。

我正在编写一个非常简单的程序:它采用颜色值(或多个颜色值),然后将一个函数应用于它们。它可以做一些事情,比如补色,一组颜色的平均值等等。我已经完成了在Glade中的界面,并阅读了一些关于使用gtk2hs的简单教程;到目前为止一切正常,我的界面将在我运行程序时显示。

但是,我的问题在于ColorSelection窗口小部件。当我从中获取我的值时,它给出的值是Color Word16 Word16 Word16类型,其中每个Word16介于0到65535之间。我希望能够做到的是将其转换为十六进制理想情况下,三元组(作为String),或者我可以转换为十六进制三元组的东西。到目前为止,我发现它似乎与颜色存储为rrrrggggbbbb的事实有关,而不是HTML样式的rrggbb。我发现了,使用此代码:

colorToHex (Color a b c)
    =  (showHex a "") ++ " " ++ (showHex b "") ++ " " ++ (showHex c "")

就是这样,虽然大部分时间都是准确的,但是当使用颜色选择器工具时,我可以输入一个看似与输出颜色不同的颜色。例如,使用颜色选择器,我选择了#A9D06E - 但是,我的函数返回了"aa11 d12d 6e41"。虽然相当接近,但我无法弄清楚这种关系 - 在这个例子中,红色通道的舍入是如何工作的?另外,如果我直接输入十六进制值#A9D06E,我会得到"a9a9 d0d0 6e6e"

我尝试使用Hoogle查找将Colour转换为StringColour转换为其他任何内容的函数,并在Hackage上搜索Gtk包中的文档,但没有找到任何可以做我想要的东西。我也搜索过互联网,但找不到处理Colour类型的问题。我找到了一个完全符合我想要的功能,位于底部here。然而,这也存在同样的问题,因为它不会给出颜色选择器本身给出的特定选择的相同值。

更新1

我也尝试过改变值。换算8位几乎总是给出正确的价值,但是,按照我尝试过的其他事情,每隔一段时间它就会稍微偏出。

1 个答案:

答案 0 :(得分:1)

我想我在这里找到了自己问题的答案 - 经过一番挖掘后,我发现我想要做的就是转换GTK颜色选择器给我的东西 - 也就是说,每通道16位颜色 - 成为8 bpc颜色。有了这个,我在Adobe论坛上找到了this页面。使用那里发布的答案,我编写了一些Haskell代码,它将类型Color的值转换为Hex三元组,并且就我发现而言,似乎始终与报告的值匹配颜色选择器本身。以下是我使用的代码:

toHex :: (Integral a, Show a) => a -> String
toHex i
  | length o == 1 = '0':o
  | otherwise     = o
  where
    o = map toUpper $ showHex i ""

d16to8 :: Integral a => a -> Integer
d16to8 i = (255 * d16to15 + 16385) `div` 32768
  where d16to15 =  (32768 * (toInteger i) + 32768) `div` 65535

colorToHex :: Color -> String
colorToHex (Color a b c) = (toHex.d16to8 $ a) ++ (toHex.d16to8 $ b) ++ (toHex.d16to8 $ c)