use bytes::Bytes; use image::{codecs::jpeg::JpegEncoder, imageops::FilterType}; use thiserror::Error; use crate::Encoding; pub fn try_resize_local_file( width: u32, height: u32, path: &str, encoding: Encoding, quality: u8, ) -> Result, image::error::ImageError> { let img = image::open(path)?; let resized = img.resize(width, height, FilterType::Lanczos3); match encoding { Encoding::Jpeg => { let mut buffer = Vec::new(); let mut encoder = JpegEncoder::new_with_quality(&mut buffer, quality); encoder.encode_image(&resized)?; Ok(Some(buffer.into())) } Encoding::Webp => { if let Ok(encoder) = webp::Encoder::from_image(&resized) { let memory = encoder.encode(quality.into()); let bytes = memory.to_vec(); Ok(Some(bytes.into())) } else { Ok(None) } } } } #[derive(Debug, Error)] pub enum ResizeImageError { #[error(transparent)] Image(#[from] image::error::ImageError), #[error(transparent)] Join(#[from] tokio::task::JoinError), } pub async fn try_resize_local_file_async( width: u32, height: u32, path: &str, encoding: Encoding, quality: u8, ) -> Result, ResizeImageError> { let path = path.to_owned(); Ok( moosicbox_task::spawn_blocking("image: Resize local file", move || { try_resize_local_file(width, height, &path, encoding, quality) }) .await??, ) }