use clap::Parser; use image::{GenericImage, ImageFormat, Pixel}; use serde::{Deserialize, Serialize}; /// Extract Information About An Image or Spritesheet #[derive(Debug, Clone, Parser, Serialize, Deserialize)] #[clap(author, version = "0.7.0")] pub struct Info { /// The path to the image file #[serde(default)] pub input: String, /// The output path for a JSON formatted information file. Omit to print to stdout #[serde(default)] pub output: Option<String>, /// The size of each tile in the spritesheet. Assumed to be square tiles #[clap(short, long, default_value = None)] #[serde(default)] pub tile_size: Option<u32>, } #[derive(Debug, Clone, Serialize, Deserialize)] pub struct ImageInfo { image_width: u32, image_height: u32, image_format: String, #[serde(skip_serializing_if = "Option::is_none")] tile_width: Option<u32>, #[serde(skip_serializing_if = "Option::is_none")] tile_height: Option<u32>, #[serde(skip_serializing_if = "Option::is_none")] rows: Option<u32>, #[serde(skip_serializing_if = "Option::is_none")] columns: Option<u32>, } impl Info { pub fn run<T: GenericImage>(&self, image: &T) -> anyhow::Result<ImageInfo> where T::Pixel: 'static, <T::Pixel as Pixel>::Subpixel: 'static, { let format = ImageFormat::from_path(&self.input)?; let image_width = image.width(); let image_height = image.height(); let mut image_info = ImageInfo { image_width, image_height, image_format: format!("{:?}", format).to_lowercase(), tile_width: None, tile_height: None, rows: None, columns: None, }; if let Some(tile_size) = self.tile_size { image_info.tile_width = Some(tile_size); image_info.tile_height = Some(tile_size); image_info.rows = Some(image_info.image_height / tile_size); image_info.columns = Some(image_info.image_width / tile_size); } Ok(image_info) } }