Last active
June 28, 2023 15:23
-
-
Save andelf/1dcc50d1c9d4bd8ecf3151e6bafe87c0 to your computer and use it in GitHub Desktop.
HSL color to RGB color conversion for embedded Rust
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
//! color conversion | |
//! | |
//! via https://github.com/emgyrz/colorsys.rs which is not friendly to embedded devices | |
pub const RGB_UNIT_MAX: f32 = 255.0; | |
pub const HUE_MAX: f32 = 360.0; | |
pub const PERCENT_MAX: f32 = 100.0; | |
pub const RATIO_MAX: f32 = 1.0; | |
pub const ALL_MIN: f32 = 0.0; | |
const ONE: f32 = 1.0; | |
const TWO: f32 = 2.0; | |
const SIX: f32 = 6.0; | |
const ONE_THIRD: f32 = ONE / 3.0; | |
const TWO_THIRD: f32 = TWO / 3.0; | |
pub fn bound(r: f32, entire: f32) -> f32 { | |
let mut n = r; | |
loop { | |
let less = n < ALL_MIN; | |
let bigger = n > entire; | |
if !less && !bigger { | |
break n; | |
} | |
if less { | |
n += entire; | |
} else { | |
n -= entire; | |
} | |
} | |
} | |
pub fn bound_ratio(r: f32) -> f32 { | |
bound(r, RATIO_MAX) | |
} | |
fn calc_rgb_unit(unit: f32, temp1: f32, temp2: f32) -> f32 { | |
let mut result = temp2; | |
if SIX * unit < ONE { | |
result = temp2 + (temp1 - temp2) * SIX * unit | |
} else if TWO * unit < ONE { | |
result = temp1 | |
} else if 3.0 * unit < TWO { | |
result = temp2 + (temp1 - temp2) * (TWO_THIRD - unit) * SIX | |
} | |
result * RGB_UNIT_MAX | |
} | |
/// hsl: [1.0, 1.0, 1.0] -> [255.0, 255.0, 255.0] | |
pub fn hsl_to_rgb(hsl: [f32; 3]) -> [f32; 3] { | |
let [h, s, l]: [f32; 3] = hsl; | |
if s == 0.0 { | |
let unit = RGB_UNIT_MAX * l; | |
return [unit, unit, unit]; | |
} | |
let temp1 = if l < 0.5 { l * (ONE + s) } else { l + s - l * s }; | |
let temp2 = TWO * l - temp1; | |
let hue = h; | |
let temp_r = bound_ratio(hue + ONE_THIRD); | |
let temp_g = bound_ratio(hue); | |
let temp_b = bound_ratio(hue - ONE_THIRD); | |
let r = calc_rgb_unit(temp_r, temp1, temp2); | |
let g = calc_rgb_unit(temp_g, temp1, temp2); | |
let b = calc_rgb_unit(temp_b, temp1, temp2); | |
[r, g, b] | |
} |
Author
andelf
commented
Jun 5, 2023
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment