|
| 1 | +/// Author : https://github.com/ali77gh\ |
| 2 | +/// References:\ |
| 3 | +/// RGB: https://en.wikipedia.org/wiki/RGB_color_model\ |
| 4 | +/// CMYK: https://en.wikipedia.org/wiki/CMYK_color_model\ |
| 5 | +
|
| 6 | +/// This function Converts RGB to CMYK format |
| 7 | +/// |
| 8 | +/// ### Params |
| 9 | +/// * `r` - red |
| 10 | +/// * `g` - green |
| 11 | +/// * `b` - blue |
| 12 | +/// |
| 13 | +/// ### Returns |
| 14 | +/// (C, M, Y, K) |
| 15 | +pub fn rgb_to_cmyk(rgb: (u8, u8, u8)) -> (u8, u8, u8, u8) { |
| 16 | + // Safety: no need to check if input is positive and less than 255 because it's u8 |
| 17 | + |
| 18 | + // change scale from [0,255] to [0,1] |
| 19 | + let (r, g, b) = ( |
| 20 | + rgb.0 as f64 / 255f64, |
| 21 | + rgb.1 as f64 / 255f64, |
| 22 | + rgb.2 as f64 / 255f64, |
| 23 | + ); |
| 24 | + |
| 25 | + match 1f64 - r.max(g).max(b) { |
| 26 | + 1f64 => (0, 0, 0, 100), // pure black |
| 27 | + k => ( |
| 28 | + (100f64 * (1f64 - r - k) / (1f64 - k)) as u8, // c |
| 29 | + (100f64 * (1f64 - g - k) / (1f64 - k)) as u8, // m |
| 30 | + (100f64 * (1f64 - b - k) / (1f64 - k)) as u8, // y |
| 31 | + (100f64 * k) as u8, // k |
| 32 | + ), |
| 33 | + } |
| 34 | +} |
| 35 | + |
| 36 | +#[cfg(test)] |
| 37 | +mod tests { |
| 38 | + use super::*; |
| 39 | + |
| 40 | + macro_rules! test_rgb_to_cmyk { |
| 41 | + ($($name:ident: $tc:expr,)*) => { |
| 42 | + $( |
| 43 | + #[test] |
| 44 | + fn $name() { |
| 45 | + let (rgb, cmyk) = $tc; |
| 46 | + assert_eq!(rgb_to_cmyk(rgb), cmyk); |
| 47 | + } |
| 48 | + )* |
| 49 | + } |
| 50 | + } |
| 51 | + |
| 52 | + test_rgb_to_cmyk! { |
| 53 | + white: ((255, 255, 255), (0, 0, 0, 0)), |
| 54 | + gray: ((128, 128, 128), (0, 0, 0, 49)), |
| 55 | + black: ((0, 0, 0), (0, 0, 0, 100)), |
| 56 | + red: ((255, 0, 0), (0, 100, 100, 0)), |
| 57 | + green: ((0, 255, 0), (100, 0, 100, 0)), |
| 58 | + blue: ((0, 0, 255), (100, 100, 0, 0)), |
| 59 | + } |
| 60 | +} |
0 commit comments