Emacs Lisp: Convert Color Formats: RGB, HSL, HSV 🚀

By Xah Lee. Date: . Last updated: .

The color package color.el, in emacs 24.1, lets you convert colors from various models and formats. For example: RGB, HSL, HSV, named color values, and things like finding the color complement.

This page shows you:

Convert RGB to HSL

;; convert RGB color to HSL.
;; all input and output are in the range {0, 1}

(require 'color )

(color-rgb-to-hsl 1 0 0) ; ⇒  (0.0 1 0.5) red

(color-rgb-to-hsl 0 1 0) ; ⇒ (0.3333333333333333 1 0.5) green

(color-rgb-to-hsl 0 0 1) ; ⇒ (0.6666666666666666 1 0.5) blue

(color-rgb-to-hsl 1 1 1) ; ⇒ (0.0 0.0 1.0) white

(color-rgb-to-hsl 0 0 0) ; ⇒ (0.0 0.0 0.0) black

Note that if you are converting from hexadecimal valued RGB format such as #aabbcc, you must first convert the hexadecimal to integer, then re-scale from {0 to 255} based range to {0 to 1} based range, then feed that to color-rgb-to-hsl.

For explanation of the HSL color model, see: CSS: HSL Color

Convert HSL to RGB

;; convert HSL color to RGB.
;; all input and output are in the range {0 to 1}

(require 'color )

(color-hsl-to-rgb 0 1 .5) ; (1.0 0.0 0.0) red

(color-hsl-to-rgb .3 1 .5) ; ⇒ (0.19999999999999996 1.0 0.0) greenish

(color-hsl-to-rgb .6 1 .5) ; ⇒ (0.0 0.3999999999999999 1.0) blueish

(color-hsl-to-rgb 0 0 1) ; ⇒ (1 1 1) white

(color-hsl-to-rgb 0 0 0) ; ⇒ (0 0 0) black

Convert RGB Hexadecimal Format to Emacs Lisp Vector Format

(defun xah-css-normalize-number-scale (Val RangeMax)
  "Scale Val from range [0, RangeMax] to [0, 1]
The arguments can be int or float.
Return value is float.

URL `http://xahlee.info/emacs/emacs/emacs_CSS_colors.html'
Version: 2016-07-19"
  (/ (float Val) (float RangeMax)))

(defun xah-css-convert-color-hex-to-vec (Rrggbb)
  "Convert color Rrggbb from rrggbb string to a elisp vector [r g b], where the values are from 0 to 1.
Example:
 (xah-css-convert-color-hex-to-vec \"00ffcc\") ⇒ [0.0 1.0 0.8]

Note: The input string must NOT start with #.

URL `http://xahlee.info/emacs/emacs/emacs_CSS_colors.html'
Version: 2016-07-19 2023-05-13"
  (vector
   (xah-css-normalize-number-scale (string-to-number (substring Rrggbb 0 2) 16) 255)
   (xah-css-normalize-number-scale (string-to-number (substring Rrggbb 2 4) 16) 255)
   (xah-css-normalize-number-scale (string-to-number (substring Rrggbb 4) 16) 255)))

Command to Convert RGB Color to HSL

Here's a command that convert between CSS's RGB hexadecimal format to HSL format. For example, #ffefd5 → hsl(37,100%,91%)

It works on the word under cursor.

(defun xah-css-hex-color-to-hsl ()
  "Convert color spec under cursor from “#rrggbb” to CSS HSL format.
 e.g. #ffefd5 ⇒ hsl(37,100%,91%)

URL `http://xahlee.info/emacs/emacs/elisp_convert_rgb_hsl_color.html'
Version: 2016-07-19"
  (interactive)
  (let* (
         (xbds (bounds-of-thing-at-point 'word))
         (xp1 (car xbds))
         (xp2 (cdr xbds))
         (xcurrentWord (buffer-substring-no-properties xp1 xp2)))
    (if (string-match "[a-fA-F0-9]\\{6\\}" xcurrentWord)
        (progn
          (delete-region xp1 xp2)
          (when (equal (char-before) 35) ; 35 is #
            (delete-char -1))
          (insert (xah-css-hex-to-hsl-color xcurrentWord )))
      (progn
        (user-error "The current word 「%s」 is not of the form #rrggbb." xcurrentWord)))))
(defun xah-css-hex-to-hsl-color (HexStr)
  "Convert HexStr color to CSS HSL format.
Return a string. Example: ffefd5 ⇒ hsl(37,100%,91%)
Note: The input string must NOT start with “#”.

URL `http://xahlee.info/emacs/emacs/emacs_CSS_colors.html'
Version: 2016-07-19 2023-05-13"
  (let* (
         (xcolorVec (xah-css-convert-color-hex-to-vec HexStr))
         (xR (elt xcolorVec 0))
         (xG (elt xcolorVec 1))
         (xB (elt xcolorVec 2))
         (xhsl (color-rgb-to-hsl xR xG xB))
         (xH (elt xhsl 0))
         (xS (elt xhsl 1))
         (xL (elt xhsl 2)))
    (format "hsl(%d,%d%%,%d%%)" (* xH 360) (* xS 100) (* xL 100))))

The code is from Emacs: Xah CSS Mode (xah-css-mode.el).

color.el is written by Julien Danjou [https://julien.danjou.info/blog/ ] , Drew Adams [http://www.emacswiki.org/emacs/DrewAdams ] Thanks guys.