Files
pixstrip/pixstrip-core/src/operations/resize.rs
lashman a29256921e Wire resize algorithm selection, overwrite behavior, and fix rotation/flip scope
- Add ResizeAlgorithm enum (Lanczos3/CatmullRom/Bilinear/Nearest) to core
- Thread algorithm selection from UI ComboRow through ProcessingJob to resize_image
- Add OverwriteBehavior enum (AutoRename/Overwrite/Skip) to core
- Implement overwrite handling in executor with auto-rename suffix logic
- Wire overwrite behavior from output step through to processing job
- Fix rotation/flip to apply when resize step is enabled, not just adjustments
2026-03-06 15:17:59 +02:00

75 lines
2.3 KiB
Rust

use fast_image_resize::{images::Image, Resizer, ResizeOptions, ResizeAlg, FilterType};
use crate::error::{PixstripError, Result};
use crate::types::Dimensions;
use super::{ResizeConfig, ResizeAlgorithm};
pub fn resize_image(
src: &image::DynamicImage,
config: &ResizeConfig,
) -> Result<image::DynamicImage> {
resize_image_with_algorithm(src, config, ResizeAlgorithm::default())
}
pub fn resize_image_with_algorithm(
src: &image::DynamicImage,
config: &ResizeConfig,
algorithm: ResizeAlgorithm,
) -> Result<image::DynamicImage> {
let original = Dimensions {
width: src.width(),
height: src.height(),
};
let target = config.target_for(original);
if target.width == original.width && target.height == original.height {
return Ok(src.clone());
}
let src_rgba = src.to_rgba8();
let (src_w, src_h) = (src_rgba.width(), src_rgba.height());
let src_image = Image::from_vec_u8(
src_w,
src_h,
src_rgba.into_raw(),
fast_image_resize::PixelType::U8x4,
)
.map_err(|e| PixstripError::Processing {
operation: "resize".into(),
reason: format!("Failed to create source image: {}", e),
})?;
let mut dst_image = Image::new(
target.width,
target.height,
fast_image_resize::PixelType::U8x4,
);
let mut resizer = Resizer::new();
let alg = match algorithm {
ResizeAlgorithm::Lanczos3 => ResizeAlg::Convolution(FilterType::Lanczos3),
ResizeAlgorithm::CatmullRom => ResizeAlg::Convolution(FilterType::CatmullRom),
ResizeAlgorithm::Bilinear => ResizeAlg::Convolution(FilterType::Bilinear),
ResizeAlgorithm::Nearest => ResizeAlg::Nearest,
};
let options = ResizeOptions::new().resize_alg(alg);
resizer
.resize(&src_image, &mut dst_image, &options)
.map_err(|e| PixstripError::Processing {
operation: "resize".into(),
reason: format!("Resize failed: {}", e),
})?;
let result_buf: image::RgbaImage =
image::ImageBuffer::from_raw(target.width, target.height, dst_image.into_vec())
.ok_or_else(|| PixstripError::Processing {
operation: "resize".into(),
reason: "Failed to create output image buffer".into(),
})?;
Ok(image::DynamicImage::ImageRgba8(result_buf))
}