rs-colors
2022-04-01
A color data type for Common Lisp.
Upstream URL
Author
Ralph Schleicher <rs@ralph-schleicher.de>
License
Modified BSD License
A color data type for Common Lisp.
Implemented color spaces:
* generic RGB
* generic HSV/HSB
* generic HSL
* generic CMY
* generic CMYK
and
* CIE RGB
* CIE XYZ
* CIE xyY
* CIE L*u*v*
* CIE L*a*b*
* CIE L*C*h
* sRGB
* Adobe RGB
Color space conversion is resolved by CLOS:
(srgb-color-coordinates
(make-ciexyy-color 1/3 1/3 1))
==> 1
0.976911599934101d0
0.9587075033783911d0
(change-class (make-generic-rgb-color 1/2 1/2 1) 'generic-hsv-color)
==> #<HSV-COLOR (240 1/2 1)>
(change-class (make-generic-hsv-color 240 1/2 1) 'generic-rgb-color)
==> #<RGB-COLOR (1/2 1/2 1)>
Colors can be read and written:
(with-input-from-string (stream "#4E9A06 junk")
(let ((color (read-color-html stream)))
(values color
(format nil color-formatter-html color)
(format nil color-formatter-css3-rgb color)
(format nil color-formatter-xcms-ciexyy color))))
==> #<SRGB-COLOR (26/85 154/255 2/85)>
"#4E9A06"
"rgb(78, 154, 6)"
"CIExyY:0.33748913/0.5669201/0.24743336"
You can define your own formats:
(define-color-printer fubar (color stream)
(multiple-value-bind (a b c)
(abc-color-coordinates color)
(format stream "<ABC:~A,~A,~A>" a b c)))
(print-color-fubar (make-srgb-color 199 21 133 :byte-size 8))
There are dictionaries with predefined colors:
(ql:quickload "rs-colors-html")
html-color:silver
==> #<SRGB-COLOR (64/85 64/85 64/85)>
(ql:quickload "rs-colors-svg")
svg-color:tan
==> #<SRGB-COLOR (14/17 12/17 28/51)>
(ql:quickload "rs-colors-tango")
(tango-color:orange :light)
==> #<SRGB-COLOR (84/85 35/51 62/255)>
(ql:quickload "rs-colors-x11")
x11-color:ghost-white
==> #<SRGB-COLOR (248/255 248/255 1)>
Adding a new color space is straight forward:
(defclass abc-color (color) (a b c))
(defmethod color-coordinates ((color abc-color))
(with-slots (a b c) color
(values a b c)))
(defun make-abc-color (a b c) ...)
;; Color conversion.
(defun abc-from-ciexyz (x y z) ...)
(defun ciexyz-from-abc (a b c) ...)
(defgeneric abc-color-coordinates (color)
(:method ((color abc-color))
(color-coordinates color))
;; Otherwise, go via CIE XYZ.
(:method ((color color))
(multiple-value-call #'abc-from-ciexyz
(ciexyz-color-coordinates color))))
(defmethod ciexyz-color-coordinates ((color abc-color))
(multiple-value-call #'ciexyz-from-abc
(abc-color-coordinates color)))
Have fun!