#[derive(Clone, Copy, PartialEq, Eq, Debug)]
pub enum PixelFormat {
Rgba8,
Bgra8,
}
#[derive(Clone, Debug)]
pub struct Frame {
pub pixels: Vec<u8>,
pub width: usize,
pub height: usize,
pub format: PixelFormat,
}
impl Frame {
pub fn rgba8(width: usize, height: usize, pixels: Vec<u8>) -> Self {
Frame { width, height, pixels, format: PixelFormat::Rgba8 }
}
pub fn bgra8(width: usize, height: usize, pixels: Vec<u8>) -> Self {
Frame { width, height, pixels, format: PixelFormat::Bgra8 }
}
#[inline]
pub fn stride(&self) -> usize {
self.width * 4
}
#[inline]
pub fn rgb_offsets(&self) -> (usize, usize, usize) {
match self.format {
PixelFormat::Rgba8 => (0, 1, 2),
PixelFormat::Bgra8 => (2, 1, 0),
}
}
pub fn to_gray(&self) -> Vec<u8> {
let (ro, go, bo) = self.rgb_offsets();
let n = self.width * self.height;
let mut gray = vec![0u8; n];
for i in 0..n {
let b = i * 4;
let r = self.pixels[b + ro] as u32;
let g = self.pixels[b + go] as u32;
let bl = self.pixels[b + bo] as u32;
gray[i] = ((r * 299 + g * 587 + bl * 114) / 1000) as u8;
}
gray
}
}