【问题标题】:gtk2hs - converting Color to a hex tripletgtk2hs - 将颜色转换为十六进制三元组
【发布时间】:2023-12-08 23:07:01
【问题描述】:

我正在使用 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 位几乎总能得到正确的值,但是,根据我尝试的其他方法,它经常会稍微偏离。

【问题讨论】:

    标签: haskell gtk rgb gtk2hs color-depth


    【解决方案1】:

    我想我已经在这里找到了我自己问题的答案——经过一番挖掘,我发现我想做的是转换 GTK 颜色选择器给我的东西——即 16 位——每通道颜色 - 变成 8 bpc 颜色。有了这个,我在 Adob​​e 论坛上找到了this 页面。使用那里发布的答案,我编写了一些 Haskell 代码,它将 Color 类型的值转换为十六进制三元组,据我所知,似乎总是与颜色选择器本身报告的值相匹配.这是我正在使用的代码:

    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)
    

    【讨论】: