diff --git a/Cargo.lock b/Cargo.lock index 1aea4f7..231cda7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -968,7 +968,7 @@ dependencies = [ [[package]] name = "spritter" -version = "0.5.3" +version = "0.6.0" dependencies = [ "clap", "env_logger", diff --git a/Cargo.toml b/Cargo.toml index 6fa6185..47ced08 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "spritter" -version = "0.5.3" +version = "0.6.0" edition = "2021" authors = ["fgardt "] description = "Spritesheet generator for factorio" diff --git a/README.md b/README.md index dfc8486..1e27d3a 100644 --- a/README.md +++ b/README.md @@ -50,6 +50,9 @@ Options: When set the tile resolution will be set to 64 unless specified otherwise. --no-crop Set when the sprites should not be cropped + -a, --crop-alpha + Sets the max alpha value to consider a pixel as transparent [0-255]. + Use a higher value in case your inputs have slightly transparent pixels and don't crop nicely. [default: 0] -s, --scale Set a scaling factor to rescale the used sprites by. Values < 1.0 will shrink the sprites. Values > 1.0 will enlarge them. [default: 1] diff --git a/src/image_util.rs b/src/image_util.rs index 8ab5836..e0851f5 100644 --- a/src/image_util.rs +++ b/src/image_util.rs @@ -68,7 +68,7 @@ fn load_image_from_file(path: &Path) -> ImgUtilResult { Ok(image) } -pub fn crop_images(images: &mut Vec) -> ImgUtilResult<(f64, f64)> { +pub fn crop_images(images: &mut Vec, limit: u8) -> ImgUtilResult<(f64, f64)> { if images.is_empty() { return Err(ImgUtilError::NoImagesToCrop); } @@ -89,13 +89,13 @@ pub fn crop_images(images: &mut Vec) -> ImgUtilResult<(f64, f64)> { let mut x = image .enumerate_pixels() - .filter_map(|(x, _, pxl)| if pxl[3] > 0 { Some(x) } else { None }) + .filter_map(|(x, _, pxl)| if pxl[3] > limit { Some(x) } else { None }) .collect::>(); x.sort_unstable(); let mut y = image .enumerate_pixels() - .filter_map(|(_, y, pxl)| if pxl[3] > 0 { Some(y) } else { None }) + .filter_map(|(_, y, pxl)| if pxl[3] > limit { Some(y) } else { None }) .collect::>(); y.sort_unstable(); @@ -156,8 +156,16 @@ pub fn crop_images(images: &mut Vec) -> ImgUtilResult<(f64, f64)> { } // calculate how the center point shifted relative to the original image - let shift_x = -((f64::from(raw_width - cropped_width) / 2.0) - f64::from(min_x)); - let shift_y = -((f64::from(raw_height - cropped_height) / 2.0) - f64::from(min_y)); + let mut shift_x = -((f64::from(raw_width - cropped_width) / 2.0) - f64::from(min_x)); + let mut shift_y = -((f64::from(raw_height - cropped_height) / 2.0) - f64::from(min_y)); + + if shift_x == 0.0 { + shift_x = 0.0; + } + + if shift_y == 0.0 { + shift_y = 0.0; + } trace!("shifted by ({shift_x}, {shift_y})"); diff --git a/src/main.rs b/src/main.rs index 4890d23..5cc3b93 100644 --- a/src/main.rs +++ b/src/main.rs @@ -103,6 +103,11 @@ struct SpritesheetArgs { #[clap(long, action)] pub no_crop: bool, + /// Sets the max alpha value to consider a pixel as transparent [0-255]. + /// Use a higher value in case your inputs have slightly transparent pixels and don't crop nicely. + #[clap(short = 'a', long, default_value_t = 0, verbatim_doc_comment)] + pub crop_alpha: u8, + /// Set a scaling factor to rescale the used sprites by. /// Values < 1.0 will shrink the sprites. Values > 1.0 will enlarge them. #[clap(short, long, default_value_t = 1.0, verbatim_doc_comment)] @@ -468,7 +473,7 @@ fn generate_spritesheet( let (shift_x, shift_y) = if args.no_crop { (0.0, 0.0) } else { - image_util::crop_images(&mut images)? + image_util::crop_images(&mut images, args.crop_alpha)? }; #[allow(clippy::unwrap_used)]