#[derive(Clone, Copy, Default, Debug, PartialEq)]
pub struct Rgb {
pub r: u8,
pub g: u8,
pub b: u8,
}
impl Rgb {
#[inline]
pub const fn new(r: u8, g: u8, b: u8) -> Self {
Rgb { r, g, b }
}
#[inline]
pub fn grayscale(&self) -> Rgb {
let gray = self.luminosity();
Rgb::new(gray, gray, gray)
}
#[inline]
pub fn lightness(&self) -> u8 {
let Rgb { r, g, b } = *self;
let sum = u16::from(r.max(g).max(b)) + u16::from(r.min(g).min(b));
(sum / 2) as u8
}
#[inline]
pub fn luminosity(&self) -> u8 {
let Rgb { r, g, b } = *self;
((0.2126 * f32::from(r)) + (0.7152 * f32::from(g)) + (0.0722 * f32::from(b))) as u8
}
#[inline]
pub fn average(&self) -> u8 {
let Rgb { r, g, b } = *self;
((u16::from(r) + u16::from(g) + u16::from(b)) / 3) as u8
}
}
pub struct Average {
r_sum: u32,
g_sum: u32,
b_sum: u32,
count: u32,
}
impl Average {
#[inline]
pub fn new() -> Average {
Average {
r_sum: 0,
g_sum: 0,
b_sum: 0,
count: 0,
}
}
#[inline]
pub fn add(&mut self, color: &Rgb) {
self.r_sum += u32::from(color.r);
self.g_sum += u32::from(color.g);
self.b_sum += u32::from(color.b);
self.count += 1;
}
#[inline]
pub fn get(&self) -> Option<Rgb> {
match self.count {
0 => None,
count => {
let r = self.r_sum / count;
let g = self.g_sum / count;
let b = self.b_sum / count;
Some(Rgb::new(r as u8, g as u8, b as u8))
}
}
}
}