colors_transform/
grayscale.rs1use super::ColorTuple;
2
3pub enum GrayScaleMethod {
4 Average,
5 AverageProminent,
6 Luminance,
7 Rec709,
8 Rec2100
9}
10
11static R_YUV_FACTOR: f32 = 0.299;
12static G_YUV_FACTOR: f32 = 0.587;
13static B_YUV_FACTOR: f32 = 0.114;
14
15static R_REC709_FACTOR: f32 = 0.2126;
16static G_REC709_FACTOR: f32 = 0.7152;
17static B_REC709_FACTOR: f32 = 0.0722;
18
19static R_REC2100_FACTOR: f32 = 0.2627;
20static G_REC2100_FACTOR: f32 = 0.6780;
21static B_REC2100_FACTOR: f32 = 0.0593;
22
23fn rgb_to_grayscale_lum(rgb: &ColorTuple) -> ColorTuple {
24 let (r, g, b) = rgb;
25 (r * R_YUV_FACTOR, g * G_YUV_FACTOR, b * B_YUV_FACTOR)
26}
27
28fn rgb_to_grayscale_rec709(rgb: &ColorTuple) -> ColorTuple {
29 let (r, g, b) = rgb;
30 (r * R_REC709_FACTOR, g * G_REC709_FACTOR, b * B_REC709_FACTOR)
31}
32fn rgb_to_grayscale_rec2100(rgb: &ColorTuple) -> ColorTuple {
33 let (r, g, b) = rgb;
34 (r * R_REC2100_FACTOR, g * G_REC2100_FACTOR, b * B_REC2100_FACTOR)
35}
36
37fn rgb_to_grayscale_avg(rgb: &ColorTuple) -> ColorTuple {
38 let (r, g, b) = rgb;
39 let y = (r + g + b) / 3.0;
40 (y, y, y)
41}
42
43fn rgb_to_grayscale_avg_prom(rgb: &ColorTuple) -> ColorTuple {
44 let (r, g, b) = rgb;
45 let rgb_vec = vec![r, g, b];
46 let max = rgb_vec.iter().fold(std::f32::MIN, |a, &b| a.max(*b));
47 let min = rgb_vec.iter().fold(std::f32::MAX, |a, &b| a.min(*b));
48 let y = (max + min) / 2.0;
49 (y, y, y)
50}
51
52
53pub fn rgb_grayscale(rgb: &ColorTuple, method: GrayScaleMethod) -> ColorTuple {
54 match method {
55 GrayScaleMethod::Average => rgb_to_grayscale_avg(rgb),
56 GrayScaleMethod::AverageProminent => rgb_to_grayscale_avg_prom(rgb),
57 GrayScaleMethod::Luminance => rgb_to_grayscale_lum(rgb),
58 GrayScaleMethod::Rec709 => rgb_to_grayscale_rec709(rgb),
59 GrayScaleMethod::Rec2100 => rgb_to_grayscale_rec2100(rgb),
60 }
61}