Skip to content

ralph-schleicher/rs-colors

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

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!