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 { resize_image_with_algorithm(src, config, ResizeAlgorithm::default()) } pub fn resize_image_with_algorithm( src: &image::DynamicImage, config: &ResizeConfig, algorithm: ResizeAlgorithm, ) -> Result { 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)) }