1pub struct Color {}
3
4impl Color {
5 pub fn luminance_from_rgba(rgba: &[u8; 4]) -> f64 {
24 let r = rgba[0] as f64 / 255.0;
25 let g = rgba[1] as f64 / 255.0;
26 let b = rgba[2] as f64 / 255.0;
27
28 let yuv = Self::convert_rgb_to_yuv(r, g, b);
29 Self::luminance_from_yuv(&yuv)
30 }
31
32 pub fn convert_rgb_to_yuv(r: f64, g: f64, b: f64) -> [f64; 3] {
44 let y = 0.299 * r + 0.587 * g + 0.114 * b;
45 let u = -0.169 * r - 0.331 * g + 0.500 * b;
46 let v = 0.500 * r - 0.419 * g - 0.081 * b;
47 [y, u, v]
48 }
49
50 pub fn luminance_from_yuv(yuv: &[f64; 3]) -> f64 {
60 yuv[0] }
62}
63
64#[cfg(test)]
65mod tests {
66 use super::Color;
67
68 #[test]
69 fn luminance_black() {
70 let rgba = [0, 0, 0, 255]; let lum = Color::luminance_from_rgba(&rgba);
72 assert!((lum - 0.0).abs() < 1e-6);
73 }
74
75 #[test]
76 fn luminance_white() {
77 let rgba = [255, 255, 255, 255]; let lum = Color::luminance_from_rgba(&rgba);
79 assert!((lum - 1.0).abs() < 1e-6);
80 }
81
82 #[test]
83 fn luminance_gray() {
84 let rgba = [128, 128, 128, 255];
85 let lum = Color::luminance_from_rgba(&rgba);
86 assert!((lum - 0.502).abs() < 0.01);
88 }
89
90 #[test]
91 fn luminance_red() {
92 let rgba = [255, 0, 0, 255];
93 let lum = Color::luminance_from_rgba(&rgba);
94 assert!((lum - 0.299).abs() < 0.01);
96 }
97
98 #[test]
99 fn luminance_green() {
100 let rgba = [0, 255, 0, 255];
101 let lum = Color::luminance_from_rgba(&rgba);
102 assert!((lum - 0.587).abs() < 0.01);
104 }
105
106 #[test]
107 fn luminance_blue() {
108 let rgba = [0, 0, 255, 255];
109 let lum = Color::luminance_from_rgba(&rgba);
110 assert!((lum - 0.114).abs() < 0.01);
112 }
113
114 #[test]
115 fn convert_rgb_to_yuv() {
116 let yuv = Color::convert_rgb_to_yuv(1.0, 0.0, 0.0); assert!((yuv[0] - 0.299).abs() < 0.01);
119 assert!(yuv[1] < 0.0);
121 assert!(yuv[2] > 0.0);
122 }
123
124 #[test]
125 fn luminance_from_yuv_direct() {
126 let yuv = [0.42, 0.1, -0.1];
127 let lum = Color::luminance_from_yuv(&yuv);
128 assert!((lum - 0.42).abs() < 1e-6);
129 }
130}