use super::constants;
use image::imageops;
use image::GrayImage;
use image::DynamicImage;
pub struct Image {
width: u32,
height: u32,
pixels: Vec<bool>,
}
fn resize_image(img: &DynamicImage) -> DynamicImage {
img.resize(constants::MAX_X_WIDTH/2 + constants::MAX_X_WIDTH/16, std::u32::MAX, imageops::FilterType::Nearest)
}
fn get_image(path: &str) ->
Result<DynamicImage, String> {
return match image::open(path) {
Ok(img) => Ok(img),
Err(_) => Err(String::from("Could not open image")),
}
}
fn buffer_to_bool_vec(buffer: &GrayImage) -> Vec<bool> {
let mut vec: Vec<bool> = Vec::new();
for pixel in buffer.pixels() {
vec.push(pixel[0] == 0);
}
return vec;
}
pub fn image_from_dynamic(buffer: &image::DynamicImage) -> Result<Image, String> {
let mut buffer = resize_image(buffer).into_luma8();
imageops::dither(&mut buffer, &image::imageops::colorops::BiLevel);
let vec = buffer_to_bool_vec(&buffer);
return match Image::new(buffer.width(), buffer.height(), vec) {
Ok(img) => Ok(img),
Err(_) => Err("Could not create image from buffer".to_string()),
}
}
pub fn image_from_path(path: &str) -> Result<Image, String> {
let img = match get_image(path) {
Ok(img) => img,
Err(err) => return Err(err),
};
match image_from_dynamic(&img) {
Ok(e) => return Ok(e),
Err(err) => return Err(err),
}
}
impl Image {
pub fn new(width : u32, height: u32, image: Vec<bool>) -> Result<Image, String> {
if width > constants::MAX_X_WIDTH {
return Err(format!("Width {} exceeds maximum width of 1024",
width));
}
if image.len() != (width * height) as usize {
return Err(format!("Image size {} does not match width {} and height {} area {}",
image.len(),
width,
height,
width * height));
}
Ok(
Image {
width: width/8,
height,
pixels: image,
}
)
}
pub fn export(&self ) -> Vec<u8> {
let mut to_return = Vec::new();
to_return.push(constants::GS); to_return.push(0x76); to_return.push(0x30); to_return.push(0); to_return.push((self.width % 256) as u8); to_return.push((self.width / 256) as u8); to_return.push((self.height % 256) as u8); to_return.push((self.height / 256) as u8);
let mut curr: u8 = 0;
let mut count = 0;
for i in 0..self.pixels.len() {
if self.pixels[i] {
curr |= 1 << (7 - count);
}
count += 1;
if count == 8 {
to_return.push(curr);
curr = 0;
count = 0;
}
}
to_return
}
}