From e5557d3f0841bac66d59bd081f71d55c692c0269 Mon Sep 17 00:00:00 2001 From: Louis Capitanchik <contact@louiscap.co> Date: Sun, 28 Apr 2024 14:38:39 +0100 Subject: [PATCH] Add numeric file sort option to atlas builder --- CHANGELOG.md | 6 ++++++ Cargo.lock | 2 +- Cargo.toml | 2 +- src/commands/atlas.rs | 47 +++++++++++++++++++++++++++++++++++++++++-- 4 files changed, 53 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c561f9b..5c435b4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.8.2] - 2024-04-28 + +### Added + +- Added numeric file name sort option to atlas builder + ## [0.8.1] - 2024-04-28 ### Added diff --git a/Cargo.lock b/Cargo.lock index 32f24aa..df714a9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -233,7 +233,7 @@ dependencies = [ [[package]] name = "crunch-cli" -version = "0.8.1" +version = "0.8.2" dependencies = [ "anyhow", "clap", diff --git a/Cargo.toml b/Cargo.toml index 173db32..2eabda7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "crunch-cli" -version = "0.8.1" +version = "0.8.2" edition = "2021" homepage = "https://microhacks.lcr.app/crunch/" diff --git a/src/commands/atlas.rs b/src/commands/atlas.rs index 2ef6004..4611367 100644 --- a/src/commands/atlas.rs +++ b/src/commands/atlas.rs @@ -4,6 +4,7 @@ use etagere::{AllocId, AtlasAllocator, Rectangle, Size}; use image::{image_dimensions, GenericImage, Rgba, RgbaImage}; use rayon::prelude::{IntoParallelIterator, ParallelIterator}; use serde::{Deserialize, Serialize}; +use std::cmp::Ordering; use std::collections::HashMap; use std::fmt::Display; use std::fs::File; @@ -16,7 +17,7 @@ fn default_max_size() -> usize { /// Given a set of images, create a single atlas image and metadata file containing all of the original /// set #[derive(Parser, Serialize, Deserialize, Clone, Debug)] -#[clap(author, version = "0.8.1")] +#[clap(author, version = "0.8.2")] pub struct Atlas { /// A pattern evaluating to one or more image files #[serde(default)] @@ -36,6 +37,13 @@ pub struct Atlas { /// be padded to the correct size before specifying an area #[clap(short = 'a', long = "area")] pub area: Option<usize>, + /// Perform a numeric sort on the names of files being combined. + /// + /// With this flag enabled, the files "104", "5", "2045" would be ordered as "5", "104", "2045" + /// Without this flag, those same files would be ordered by OS determination, typically ""104", "2045", "5" + #[serde(default)] + #[clap(short = 'n')] + pub numeric: bool, } #[derive(Copy, Clone, Hash, Eq, PartialEq)] @@ -108,9 +116,44 @@ impl Atlas { let pattern = glob::glob(self.glob.as_str())?; let mut builder = AtlasBuilder::new((self.max_frame_width, self.max_frame_height)); + let mut pattern = pattern.filter_map(Result::ok).collect::<Vec<PathBuf>>(); + + if self.numeric { + pattern.sort_by(|a, b| { + let a_num: isize = match a + .file_stem() + .and_then(|s| s.to_str()) + .and_then(|s| s.parse().ok()) + { + Some(v) => v, + _ => return Ordering::Equal, + }; + let b_num: isize = match b + .file_stem() + .and_then(|s| s.to_str()) + .and_then(|s| s.parse().ok()) + { + Some(v) => v, + _ => return Ordering::Equal, + }; + a_num.cmp(&b_num) + }); + } else { + pattern.sort_by(|a, b| { + let a_num = match a.file_stem().and_then(|s| s.to_str()) { + Some(v) => v, + _ => return Ordering::Equal, + }; + let b_num = match b.file_stem().and_then(|s| s.to_str()) { + Some(v) => v, + _ => return Ordering::Equal, + }; + a_num.cmp(b_num) + }) + } + let page_content_map: HashMap<usize, Vec<(PathBuf, Rectangle)>> = pattern .into_iter() - .filter_map(Result::ok) .flat_map(|path| { if let Some(fixed) = &self.area { Ok((*fixed as u32, *fixed as u32, path)) -- GitLab