use datamatrix::{DataMatrix, SymbolList};
use image::{Rgba, RgbaImage};
pub fn encode(
content: &str,
magnification: i32,
rows: i32,
columns: i32,
) -> Result<RgbaImage, String> {
if content.is_empty() {
return Err("DataMatrix: empty content".to_string());
}
let mag = magnification.max(1) as u32;
let symbol_list = if rows > 0 && columns > 0 {
SymbolList::default().enforce_height_in(rows as usize..=rows as usize)
} else {
SymbolList::default().enforce_square()
};
let code = DataMatrix::encode(content.as_bytes(), symbol_list)
.or_else(|_| {
DataMatrix::encode(content.as_bytes(), SymbolList::default().enforce_square())
})
.map_err(|e| format!("DataMatrix encoding failed: {:?}", e))?;
let bitmap = code.bitmap();
let bm_width = bitmap.width() as u32;
let bm_height = bitmap.height() as u32;
let img_width = bm_width * mag;
let img_height = bm_height * mag;
let mut img = RgbaImage::from_pixel(img_width, img_height, Rgba([0, 0, 0, 0]));
let black = Rgba([0, 0, 0, 255]);
for (col, row) in bitmap.pixels() {
let px = col as u32 * mag;
let py = row as u32 * mag;
for dy in 0..mag {
for dx in 0..mag {
if px + dx < img_width && py + dy < img_height {
img.put_pixel(px + dx, py + dy, black);
}
}
}
}
Ok(img)
}