gtk2hs - преобразование цвета в шестнадцатеричный триплет
Я работаю в Haskell с gtk2hs и столкнулся с проблемой, на которую не могу найти ответ.
Я пишу очень простую программу: она принимает значение цвета (или несколько значений цвета), а затем применяет к ним функцию. Он может делать такие вещи, как дополнительные цвета, среднее значение набора цветов и так далее. Я закончил собирать интерфейс в Glade и прочитал несколько простых руководств по использованию gtk2hs; пока все работает, и мой интерфейс будет отображаться при запуске моей программы.
Тем не менее, моя проблема с ColorSelection
виджет. Когда я получаю свою ценность от этого, значение, которое это дает, имеет тип Color Word16 Word16 Word16
где каждый Word16
между 0 и 65535. То, что я хочу сделать, это преобразовать это в триплет Hex (как String
) в идеале, или что-то, что я могу преобразовать в шестнадцатеричный триплет. До сих пор я обнаружил, что, похоже, это связано с тем, что цвета хранятся как rrrrggggbbbb, а не как rrggbb в стиле HTML. Что я нашел, используя этот код:
colorToHex (Color a b c)
= (showHex a "") ++ " " ++ (showHex b "") ++ " " ++ (showHex c "")
является то, что, хотя в большинстве случаев это точно, при использовании инструмента выбора цвета я могу ввести цвет, который кажется отличным от того, что выводится. Например, используя палитру цветов, я выбрал #A9D06E
- однако моя функция вернулась "aa11 d12d 6e41"
, Хотя и довольно близко, я не могу определить отношения - как работает округление для красного канала в этом примере? Кроме того, если я введу шестнадцатеричное значение #A9D06E
прямо я получаю "a9a9 d0d0 6e6e"
,
Я пытался с помощью Google, чтобы найти функцию, которая преобразовала Colour
к String
или Colour
к чему-то еще, и искал документы на Hackage для пакета Gtk, но не нашел там ничего, что сделало бы то, что я хотел. Я также искал в Интернете, и не мог найти много о работе с Colour
тип. Я нашел одну функцию для выполнения именно того, что хотел, расположенную здесь внизу. Тем не менее, у этого была та же самая проблема, в которой это не дало бы то же самое значение, которое само средство выбора цвета дало для определенного выбора.
Обновление 1
Я также попытался сдвинуть значения. Сдвиг на 8 бит почти всегда дает правильное значение, но, как и другие вещи, которые я пробовал, время от времени это немного выходит.
1 ответ
Я думаю, что нашел ответ на свой вопрос здесь - после небольшого копания я обнаружил, что хочу преобразовать то, что дал мне палитра цветов GTK, то есть 16 бит на канал. цвет - в цвет 8 бит на канал. Вооружившись этим, я нашел эту страницу на форумах Adobe. Используя ответ, опубликованный там, я написал некоторый код на 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)