From 8f5a5b170f4d7ea30a09788d75ac5de93eaa203e Mon Sep 17 00:00:00 2001 From: lifegpc Date: Sun, 10 Aug 2025 09:36:47 +0800 Subject: [PATCH] Add auto detect image type --- src/main.rs | 29 +++++++++++++++++++++++++---- src/types.rs | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 58 insertions(+), 4 deletions(-) diff --git a/src/main.rs b/src/main.rs index 33b5956..4db41db 100644 --- a/src/main.rs +++ b/src/main.rs @@ -752,7 +752,16 @@ pub fn export_script( return Ok(types::ScriptResult::Ok); } let img_data = script.export_image()?; - let out_type = arg.image_type.unwrap_or(types::ImageOutputType::Png); + let out_type = arg.image_type.unwrap_or_else(|| { + if root_dir.is_some() { + types::ImageOutputType::Png + } else { + output + .as_ref() + .and_then(|s| types::ImageOutputType::try_from(std::path::Path::new(s)).ok()) + .unwrap_or(types::ImageOutputType::Png) + } + }); let f = if filename == "-" { String::from("-") } else { @@ -1152,7 +1161,14 @@ pub fn import_script( } #[cfg(feature = "image")] if script.is_image() { - let out_type = arg.image_type.unwrap_or(types::ImageOutputType::Png); + let out_type = arg.image_type.unwrap_or_else(|| { + if root_dir.is_some() { + types::ImageOutputType::Png + } else { + types::ImageOutputType::try_from(std::path::Path::new(&imp_cfg.output)) + .unwrap_or(types::ImageOutputType::Png) + } + }); let out_f = if let Some(root_dir) = root_dir { let f = std::path::PathBuf::from(filename); let mut pb = std::path::PathBuf::from(&imp_cfg.output); @@ -1488,8 +1504,13 @@ pub fn create_file( typ )); } - let data = - utils::img::decode_img(arg.image_type.unwrap_or(types::ImageOutputType::Png), input)?; + let data = utils::img::decode_img( + arg.image_type.unwrap_or_else(|| { + types::ImageOutputType::try_from(std::path::Path::new(input)) + .unwrap_or(types::ImageOutputType::Png) + }), + input, + )?; let output = match output { Some(output) => output.to_string(), None => { diff --git a/src/types.rs b/src/types.rs index 148a384..67b6ec6 100644 --- a/src/types.rs +++ b/src/types.rs @@ -494,6 +494,39 @@ pub enum ImageOutputType { Webp, } +#[cfg(feature = "image")] +impl TryFrom<&str> for ImageOutputType { + type Error = anyhow::Error; + + /// Try to convert a extension string to an `ImageOutputType`. + /// Extensions are case-insensitive. + fn try_from(value: &str) -> Result { + match value.to_ascii_lowercase().as_str() { + "png" => Ok(ImageOutputType::Png), + #[cfg(feature = "image-jpg")] + "jpg" => Ok(ImageOutputType::Jpg), + #[cfg(feature = "image-jpg")] + "jpeg" => Ok(ImageOutputType::Jpg), + #[cfg(feature = "image-webp")] + "webp" => Ok(ImageOutputType::Webp), + _ => Err(anyhow::anyhow!("Unsupported image output type: {}", value)), + } + } +} + +#[cfg(feature = "image")] +impl TryFrom<&std::path::Path> for ImageOutputType { + type Error = anyhow::Error; + + fn try_from(value: &std::path::Path) -> Result { + if let Some(ext) = value.extension() { + Self::try_from(ext.to_string_lossy().as_ref()) + } else { + Err(anyhow::anyhow!("No extension found in path")) + } + } +} + #[cfg(feature = "image")] impl AsRef for ImageOutputType { fn as_ref(&self) -> &str {