use anyhow::{Context, Result};
use image::{DynamicImage, ImageFormat};
use std::fs;
use std::path::Path;
use crate::cli::Cli;
pub fn optimize_png(
input_path: &Path,
output_path: &Path,
args: &Cli,
resized_img: Option<DynamicImage>,
) -> Result<()> {
if let Some(img) = resized_img {
img.save_with_format(output_path, ImageFormat::Png)?;
} else {
fs::copy(input_path, output_path)?;
}
let optimization_level = if args.png_optimization_level == "max" {
6
} else {
match args.png_optimization_level.parse::<u8>() {
Ok(level) if level <= 6 => level,
_ => {
return Err(anyhow::anyhow!(
"Invalid oxipng optimization level: {}. Valid values are 0-6 or 'max'",
args.png_optimization_level
));
}
}
};
let mut options = oxipng::Options::from_preset(optimization_level);
options.optimize_alpha = true;
options.fast_evaluation = true;
options.strip = oxipng::StripChunks::Safe;
if args.no_zopfli {
options.deflate = oxipng::Deflaters::Libdeflater { compression: 12 };
} else {
options.deflate = oxipng::Deflaters::Zopfli {
iterations: args.zopfli_iterations,
};
}
let input_file = oxipng::InFile::Path(output_path.to_path_buf());
let output_file = oxipng::OutFile::Path {
path: Some(output_path.to_path_buf()),
preserve_attrs: true,
};
oxipng::optimize(&input_file, &output_file, &options).context("Failed to optimize PNG")?;
Ok(())
}