This library is named in honour of Raoul Dufy, the French painter. It provides functions for color manipulation and conversion in various color spaces.
To experiment with Dufy
we’ll write a two helper function to convert RGB
colors from and to hexadecimal representation:
POFTHEDAY> (defun string-to-rgb (s)
(loop for i from 1 to 5 by 2
collect (parse-integer s
:start i
:end (+ 2 i)
:radix 16)
into result
finally (return (values-list result))))
POFTHEDAY> (string-to-rgb "#F4BBFF")
244
187
255
POFTHEDAY> (defun rgb-to-string (r g b)
(format nil "#~2,'0X~2,'0X~2,'0X"
r g b))
POFTHEDAY> (rgb-to-string 244 187 255)
"#F4BBFF"
Now it is time to test how does color conversion work:
POFTHEDAY> (dufy:qrgb-to-hsv 244 187 255)
290.2941176470588d0
0.2666666666666667d0
1.0d0 (100.0d0%)
POFTHEDAY> (dufy:hsv-to-qrgb 290.2941176470588d0
0.2666666666666667d0
1.0d0)
244
187
255
Dufy
provides a number of such functions. It also implements functions
for color difference calculation.
But let’s do something more practical - create a color which is a little bit darker but has the same tone.
To do this, we need to convert RGB
to HSV
, reduce V
part and convert it
back. This function can be useful when generating CSS
using Lass
library:
POFTHEDAY> (defun darker (color &optional (ratio 0.75))
"Returns CSS color which is a little bit darker"
(rutils:with ((r g b (string-to-rgb color))
(h s v (dufy:qrgb-to-hsv r g b))
(new-r new-g new-b (dufy:hsv-to-qrgb h s (* v ratio))))
(rgb-to-string new-r new-g new-b)))
POFTHEDAY> (darker "#F4BBFF")
"#B78CBF"
Here is the result:
<div style="background-color: #F4BBFF; width: 400px; height: 50px; padding: 10px">Original (#F4BBFF)</div>
<div style="background-color: #B78CBF; width: 400px; height: 50px; padding: 10px">Darker (#B78CBF)</div>
Let’s tests the function for distance calculation and find out how different these two colors!
POFTHEDAY> (string-to-rgb "#F4BBFF")
244
187
255
POFTHEDAY> (string-to-rgb "#B78CBF")
183
140
191
POFTHEDAY> (dufy:qrgb-deltae00
244 187 255
183 140 191)
14.557112327275474d0
;; The difference between black and white:
POFTHEDAY> (dufy:qrgb-deltae00
255 255 255
0 0 0)
100.00000000000003d0
Lem uses a similar function to pick the nearest color index. But seems it is
much simpler. I’ll try to replace it with an algorithm from Dufy
and see
if my problem with Solarized color theme will disappear.
Probably there are other function for color manipulation which I don’t understand.