add svg output ability (behind flag)

This commit is contained in:
Henry Schimke
2023-01-12 10:54:58 -06:00
parent 7ddeb49064
commit a17a33e7e3
3 changed files with 88 additions and 23 deletions

View File

@@ -29,12 +29,14 @@ codepage-437 = "0.1.0"
rxing-one-d-proc-derive = "0.3.0" rxing-one-d-proc-derive = "0.3.0"
#rxing-one-d-proc-derive = {path ="../rxing-one-d-proc-derive"} #rxing-one-d-proc-derive = {path ="../rxing-one-d-proc-derive"}
num = "0.4.0" num = "0.4.0"
svg = {version = "0.13", optional = true}
[dev-dependencies] [dev-dependencies]
java-properties = "1.4.1" java-properties = "1.4.1"
java-rand = "0.2.0" java-rand = "0.2.0"
[features] [features]
default = ["image"] default = ["image", "svg_write"]
image = ["dep:image", "dep:imageproc"] image = ["dep:image", "dep:imageproc"]
allow_forced_iso_ied_18004_compliance = [] allow_forced_iso_ied_18004_compliance = []
svg_write = ["dep:svg"]

View File

@@ -679,30 +679,44 @@ impl From<&BitMatrix> for image::DynamicImage {
fn from(value: &BitMatrix) -> Self { fn from(value: &BitMatrix) -> Self {
let mut pixels = image::ImageBuffer::new(value.width, value.height); let mut pixels = image::ImageBuffer::new(value.width, value.height);
for y in 0..value.height { for (x, y, pixel) in pixels.enumerate_pixels_mut() {
for x in 0..value.width { let new_pixel = if value.get(x as u32, y as u32) {
let pixel_value = if value.get(x, y) { u8::MIN } else { u8::MAX }; image::Rgb([0, 0, 0])
let pixel_intrior = [pixel_value, pixel_value, pixel_value]; } else {
let pixel = image::Rgb(pixel_intrior); image::Rgb([u8::MAX, u8::MAX, u8::MAX])
pixels.put_pixel(x, y, pixel); };
} *pixel = new_pixel
} }
pixels.into() pixels.into()
} }
} }
// impl From<BitMatrix> for Vec<u8> { #[cfg(feature = "svg_write")]
// fn from(value: BitMatrix) -> Self { impl From<&BitMatrix> for svg::Document {
// let mut output_vector = Vec::new(); fn from(value: &BitMatrix) -> Self {
// for y in 0..value.getHeight() { let block_size = 1;
// for col in (0..value.getWidth()).step_by(8) { let mut document = svg::Document::new().set(
// let mut byte = 0_u8; "viewBox",
// for x in 0..8 { (
// byte |= u8::from(value.get(col+x, y)) << x 0,
// } 0,
// output_vector.push(byte); value.width as u32 * block_size,
// } value.height as u32 * block_size,
// } ),
// output_vector );
// } for x in 0..value.width {
// } for y in 0..value.height {
if value.get(x, y) {
let block = svg::node::element::Rectangle::new()
.set("x", x * block_size)
.set("y", y * block_size)
.set("width", block_size)
.set("height", block_size);
document = document.add(block);
}
}
}
document
}
}

View File

@@ -1,5 +1,7 @@
use std::{ use std::{
collections::{HashMap, HashSet}, collections::{HashMap, HashSet},
io::Write,
path::PathBuf,
rc::Rc, rc::Rc,
}; };
@@ -152,3 +154,50 @@ pub fn save_image(file_name: &str, bit_matrix: &BitMatrix) -> Result<(), Excepti
)))), )))),
} }
} }
#[cfg(feature = "svg_write")]
pub fn save_svg(file_name: &str, bit_matrix: &BitMatrix) -> Result<(), Exceptions> {
let svg: svg::Document = bit_matrix.into();
match svg::save(file_name, &svg) {
Ok(_) => Ok(()),
Err(err) => Err(Exceptions::IllegalArgumentException(Some(format!(
"could not save file '{}': {}",
file_name, err
)))),
}
}
pub fn save_file(file_name: &str, bit_matrix: &BitMatrix) -> Result<(), Exceptions> {
let path = PathBuf::from(file_name);
let ext: String = if let Some(e) = path.extension() {
e.to_string_lossy().to_string()
} else {
String::default()
};
#[cfg(feature = "svg_write")]
if ext == "svg" {
return save_svg(file_name, bit_matrix);
}
#[cfg(feature = "image")]
if !ext.is_empty() && ext != "txt" {
return save_image(file_name, bit_matrix);
}
match || -> std::io::Result<_> {
let file = std::fs::File::create(path)?;
let mut output = std::io::BufWriter::new(file);
output.write_all(bit_matrix.to_string().as_bytes())?;
output.flush()?;
Ok(())
}() {
Ok(_) => Ok(()),
Err(_) => Err(Exceptions::IllegalArgumentException(Some(format!(
"could not write to '{}'",
file_name
)))),
}
}