Created
May 11, 2018 20:29
-
-
Save crowsonkb/a58d6a816ffd2c60995e5adf3e7aee6b to your computer and use it in GitHub Desktop.
Converts colors from HSL to RGB and back.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
"""Converts colors from HSL to RGB and back.""" | |
import numpy as np | |
from scipy import optimize | |
def tstack(a): | |
"""Stacks arrays in sequence along the last axis (tail).""" | |
a = np.asarray(a) | |
return np.concatenate([x[..., np.newaxis] for x in a], axis=-1) | |
def tsplit(a): | |
"""Splits arrays in sequence along the last axis (tail).""" | |
a = np.asarray(a) | |
return np.array([a[..., x] for x in range(a.shape[-1])]) | |
def hue_to_rgb_once(m1, m2, h): | |
h %= 1 | |
if h * 6 < 1: | |
return m1 + (m2 - m1) * h * 6 | |
if h * 2 < 1: | |
return m2 | |
if h * 3 < 2: | |
return m1 + (m2 - m1) * (2/3 - h) * 6 | |
return m1 | |
def hue_to_rgb(m1, m2, h): | |
m1m2h = tstack([m1, m2, h]) | |
return np.apply_along_axis(lambda a: hue_to_rgb_once(*a), -1, m1m2h) | |
def hsl_to_rgb(hsl): | |
"""Converts HSL colors to RGB. See | |
https://www.w3.org/TR/2018/PR-css-color-3-20180315/#hsl-color. | |
""" | |
h, s, l = tsplit(hsl) | |
m1, m2 = np.zeros_like(h), np.zeros_like(h) | |
m2 += (l <= 0.5) * l * (s + 1) | |
m2 += (l > 0.5) * (l + s - l * s) | |
m1 = l * 2 - m2 | |
r = hue_to_rgb(m1, m2, h + 1/3) | |
g = hue_to_rgb(m1, m2, h) | |
b = hue_to_rgb(m1, m2, h - 1/3) | |
return tstack([r, g, b]) | |
def rgb_to_hsl_once(rgb): | |
def loss(hsl): | |
rgb2 = hsl_to_rgb(hsl) | |
return sum((rgb - rgb2)**2) | |
x0 = np.array([0.5, 0.5, 0.5]) | |
opt = optimize.fmin_bfgs(loss, x0, disp=False) | |
return opt | |
def rgb_to_hsl(rgb): | |
"""Converts RGB colors back to HSL.""" | |
rgb = np.asarray(rgb) | |
hsl = np.apply_along_axis(rgb_to_hsl_once, -1, rgb) | |
hsl[..., 0] %= 1 | |
return np.clip(hsl, 0, 1) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment