use super::image_alignment::ImageAlignment;
use super::image_mode::ImageMode;
use super::image_processor::ImageProcessor;
use crate::models::print_sections::Image as ImageSection;
#[derive(Debug, Clone)]
pub struct Image {
base64_image: String,
alignment: ImageAlignment,
mode: ImageMode,
max_width: u32,
use_dithering: bool,
}
impl Image {
pub fn new(base64_image: &str, max_width: u32) -> Result<Self, String> {
Ok(Self {
base64_image: base64_image.to_string(),
alignment: ImageAlignment::Center,
mode: ImageMode::Normal,
max_width: max_width,
use_dithering: true,
})
}
pub fn set_alignment(mut self, alignment: ImageAlignment) -> Self {
self.alignment = alignment;
self
}
pub fn set_mode(mut self, mode: ImageMode) -> Self {
self.mode = mode;
self
}
pub fn set_use_dithering(mut self, use_dithering: bool) -> Self {
self.use_dithering = use_dithering;
self
}
pub fn get_command(&self) -> Result<Vec<u8>, String> {
let mut output = Vec::new();
let processed_image = ImageProcessor::process_image(
&self.base64_image,
self.max_width,
self.use_dithering
)?;
let (width, height) = processed_image.dimensions();
let image_data = ImageProcessor::image_to_bytes(&processed_image);
output.extend_from_slice(&[0x1B, 0x61, self.alignment.value()]);
let width_bytes = ((width + 7) / 8) as u16;
let x_l = (width_bytes & 0xFF) as u8;
let x_h = ((width_bytes >> 8) & 0xFF) as u8;
let y_l = (height & 0xFF) as u8;
let y_h = ((height >> 8) & 0xFF) as u8;
output.push(0x1D); output.push(0x76); output.push(0x30); output.push(self.mode.value()); output.push(x_l);
output.push(x_h);
output.push(y_l);
output.push(y_h);
output.extend_from_slice(&image_data);
output.extend_from_slice(&[0x1B, 0x61, 0x00]);
Ok(output)
}
}
pub fn process_section(imagen: &ImageSection, paper_width_pixels: i32) -> Result<Vec<u8>, String> {
if imagen.data.is_empty() {
return Err("Image data cannot be empty".to_string());
}
let alignment = match imagen.align.as_str() {
"left" => ImageAlignment::Left,
"center" => ImageAlignment::Center,
"right" => ImageAlignment::Right,
_ => ImageAlignment::Center,
};
let mode = match imagen.size.as_str() {
"normal" => ImageMode::Normal,
"double_width" => ImageMode::DoubleWidth,
"double_height" => ImageMode::DoubleHeight,
"quadruple" => ImageMode::Quadruple,
_ => ImageMode::Normal,
};
let max_width = if imagen.max_width > paper_width_pixels || imagen.max_width <= 0 {
paper_width_pixels as u32
} else {
imagen.max_width as u32
};
let image = Image::new(&imagen.data, max_width)
.map_err(|e| format!("Failed to create image: {}", e))?
.set_alignment(alignment)
.set_mode(mode)
.set_use_dithering(imagen.dithering);
let mut cmd = image.get_command()?;
cmd.extend_from_slice(b"\n");
Ok(cmd)
}
impl Image {
}