use std::path::Path; use clap::ValueEnum; use image::io::Reader; use image::{ImageError, ImageFormat, RgbaImage}; use serde::{Deserialize, Serialize}; use thiserror::Error; #[derive( Copy, Clone, PartialEq, Eq, PartialOrd, Ord, ValueEnum, Debug, Serialize, Deserialize, Default, )] pub enum PaletteFormat { #[serde(alias = "txt")] Txt, #[default] #[serde(alias = "png")] Png, #[serde(alias = "columns")] Columns, } #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, ValueEnum, Debug)] pub enum Format { Png, Jpg, Gif, Ico, Tga, Tiff, Bmp, } impl Format { pub fn as_image_format(&self) -> ImageFormat { use Format::*; match self { Png => ImageFormat::Png, Jpg => ImageFormat::Jpeg, Gif => ImageFormat::Gif, Ico => ImageFormat::Ico, Tga => ImageFormat::Tga, Tiff => ImageFormat::Tiff, Bmp => ImageFormat::Bmp, } } } #[derive(Error, Debug)] pub enum ImageLoadingError { #[error("Failed to load image data; {0}")] IoError(#[from] std::io::Error), #[error("Failed to process image; {0}")] ImageError(#[from] ImageError), } pub fn load_image( path: impl ToString, format: Option<Format>, ) -> anyhow::Result<RgbaImage, ImageLoadingError> { let mut image = Reader::open(path.to_string())?; let file = match format { Some(format) => { image.set_format(format.as_image_format()); image.decode()?.into_rgba8() } None => image.with_guessed_format()?.decode()?.into_rgba8(), }; Ok(file) } pub fn make_paths<T: AsRef<Path>>(path: T) -> anyhow::Result<(), std::io::Error> { if let Some(target) = path.as_ref().parent() { std::fs::create_dir_all(target) } else { Ok(()) } }