use crate::Result;
#[derive(Clone, Debug)]
pub struct Template {
pub rgb: Vec<u8>,
pub width: usize,
pub height: usize,
}
impl Template {
pub fn load(path: impl AsRef<std::path::Path>) -> Result<Self> {
let img = image::open(path)?;
let rgb = img.to_rgb8();
let (width, height) = (rgb.width() as usize, rgb.height() as usize);
Ok(Template {
rgb: rgb.into_raw(),
width,
height,
})
}
pub fn from_rgb(rgb: Vec<u8>, width: usize, height: usize) -> Self {
assert_eq!(rgb.len(), width * height * 3, "template 字节数与尺寸不符");
Template { rgb, width, height }
}
pub fn content_key(&self) -> u64 {
use std::hash::{Hash, Hasher};
let mut h = std::collections::hash_map::DefaultHasher::new();
self.width.hash(&mut h);
self.height.hash(&mut h);
self.rgb.hash(&mut h);
h.finish()
}
pub fn to_gray(&self) -> Vec<u8> {
let mut gray = Vec::with_capacity(self.width * self.height);
for px in self.rgb.chunks_exact(3) {
let r = px[0] as u32;
let g = px[1] as u32;
let b = px[2] as u32;
gray.push(((r * 299 + g * 587 + b * 114) / 1000) as u8);
}
gray
}
}