#[cfg(debug_assertions)]
macro_rules! debug_println {
($($args:tt)*) => { println!($($args)*) };
}
mod processor {
use image::{imageops::FilterType, GenericImageView, ImageError, ImageFormat};
use std::path::{Path, PathBuf};
pub enum SqueezeFactor {
X1_33,
X1_5,
X1_75,
X2,
}
impl SqueezeFactor {
fn value(&self) -> f32 {
match *self {
SqueezeFactor::X1_33 => 1.33,
SqueezeFactor::X1_5 => 1.5,
SqueezeFactor::X1_75 => 1.75,
SqueezeFactor::X2 => 2.0,
}
}
}
pub fn desqueeze_image(
image_path: &str,
output_path: &str,
image_format: Option<ImageFormat>,
squeeze_factor: SqueezeFactor,
) -> Result<String, ImageError> {
debug_println!("Identifying file name...");
let image_path = Path::new(image_path);
let target_image_format = image_format
.unwrap_or_else(|| {
image::ImageFormat::from_path(image_path).unwrap_or(ImageFormat::Png)
})
.extensions_str()
.first()
.unwrap_or(&"png")
.to_string();
let file_name = image_path
.file_stem()
.unwrap_or_else(|| image_path.as_os_str())
.to_str()
.unwrap_or("")
.to_string();
let output_path = Path::new(output_path);
debug_println!("{}", output_path.to_string_lossy());
debug_println!("Checking if output directory exists...");
if !output_path.try_exists()? {
debug_println!("Creating output directory...");
std::fs::create_dir(output_path)?;
}
debug_println!("Checking if outputh path is directory...");
let output_file_path: PathBuf;
if output_path.is_dir() {
debug_println!("Output path is directory");
output_file_path = output_path.join(format!("{}.{}", file_name, target_image_format));
debug_println!("Output path: {}", output_file_path.to_string_lossy());
} else {
debug_println!("Output path is not directory. Creating a new directory...");
output_file_path = output_path.join(format!("/{}.{}", file_name, target_image_format));
debug_println!("Output path: {}", output_file_path.to_string_lossy());
}
debug_println!("Desqueezing {}...", file_name);
let image = image::open(image_path)?;
let (width, height) = image.dimensions();
let mut width = width as f32;
let mut height = height as f32;
if width > height {
width *= squeeze_factor.value();
} else if height > width {
height *= squeeze_factor.value();
} else {
debug_println!("Do not desqueeze square images");
}
let path_ref = output_file_path.as_path();
debug_println!("{}", path_ref.to_string_lossy());
let new_image = image.resize_exact(width as u32, height as u32, FilterType::Nearest);
new_image.save(path_ref)?;
return Ok(path_ref.to_string_lossy().to_string());
}
}
#[cfg(test)]
mod processor_tests {
use super::processor;
#[test]
fn should_desqueeze_landscape_image() {
let result = processor::desqueeze_image(
"src/tests/squeezedLandscape.jpeg",
"src/tests/output/",
None,
processor::SqueezeFactor::X1_33,
);
assert_eq!(result.is_ok(), true);
std::fs::remove_file("src/tests/output/squeezedLandscape.jpg").unwrap_or_else(|error| {
println!("Error: {}", error);
return ();
});
}
#[test]
fn should_desqueeze_portrait_image() {
let result = processor::desqueeze_image(
"src/tests/squeezedPortrait.jpeg",
"src/tests/output/",
None,
processor::SqueezeFactor::X1_33,
);
assert_eq!(result.is_ok(), true);
std::fs::remove_file("src/tests/output/squeezedPortrait.jpg").unwrap_or_else(|error| {
println!("Error: {}", error);
return ();
});
}
}