RSS Feed

Lisp Project of the Day

dufy

You can support this project by donating at:

Donate using PatreonDonate using Liberapay

Or see the list of project sponsors.

dufygraphics

Documentation🤨
Docstrings🥺
Tests 😀
Examples😀
RepositoryActivity🥺
CI 🥺

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:

Original (#F4BBFF)
Darker (#B78CBF)

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.


Brought to you by 40Ants under Creative Commons License