Skip to content

Commit

Permalink
feat: split all images found recursively in a directory
Browse files Browse the repository at this point in the history
  • Loading branch information
rymdtian committed Apr 9, 2024
1 parent fe0bb56 commit cd02c5e
Show file tree
Hide file tree
Showing 3 changed files with 106 additions and 47 deletions.
51 changes: 51 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,4 @@ categories = ["command-line-utilities"]
[dependencies]
clap = { version = "4.5.4", features = ["derive"] }
image = "0.25.1"
walkdir = "2.5.0"
101 changes: 54 additions & 47 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,15 @@ use clap::Parser;
use image::*;
use std::path::PathBuf;
use std::{fs, process, vec};
use walkdir::WalkDir;

/// Command-line arguments for splix.
#[derive(Parser)]
struct Cli {
/// Path of the image to convert.
#[arg(short, long)]
image: PathBuf,
/// Path of the image(s) to convert.
/// Specify the path of an image, or a directory of images.
#[arg(short, long, visible_alias = "image", verbatim_doc_comment)]
images: PathBuf,

/// The number of rows to split the image into.
/// Specify an integer, or a list of integers:
Expand Down Expand Up @@ -43,15 +45,27 @@ struct Cli {
///
/// * `Ok(())` if the arguments are valid, otherwise returns an error message.
fn validate_args(cli: &Cli) -> Result<(), String> {
let image_path = cli.image.clone();
let img_dir = cli.images.clone();
let rows = &cli.rows;
let cols = &cli.cols;

// Validate image
if let Err(_) = image::open(&image_path) {
let mut is_valid_image_found = false;
for entry in WalkDir::new(&img_dir) {
match entry {
Ok(entry) => {
if image::open(entry.path()).is_ok() {
is_valid_image_found = true;
break;
}
}
Err(_) => continue,
}
}

if !is_valid_image_found {
return Err(format!(
"splix: image: The provided file '{}' is not a valid image",
image_path.display()
"splix: image: The provided file or directory '{}' is not or does not contain a valid image",
img_dir.display()
));
}

Expand Down Expand Up @@ -89,8 +103,7 @@ fn validate_args(cli: &Cli) -> Result<(), String> {
/// # Returns
///
/// A vector of split images.
fn split_image(img_path: &PathBuf, rows: &Vec<u32>, cols: &Vec<u32>) -> Vec<DynamicImage> {
let mut img = image::open(img_path).unwrap();
fn split_image(mut img: DynamicImage, rows: &Vec<u32>, cols: &Vec<u32>) -> Vec<DynamicImage> {
let mut split_images = Vec::new();
let (width, height) = img.dimensions();

Expand Down Expand Up @@ -217,19 +230,6 @@ fn save_images(
}
}

#[cfg(test)]
mod tests {
use super::*;

#[test]
fn test_split_image_correct_number_of_images() {
let path = &PathBuf::from("./assets/16x16.png");
assert!(split_image(path, &vec![3], &vec![5]).len() == 15);
assert!(split_image(path, &vec![1], &vec![1]).len() == 1);
assert!(split_image(path, &vec![16], &vec![16]).len() == 256);
}
}

fn main() {
let cli = Cli::parse();

Expand All @@ -238,32 +238,39 @@ fn main() {
return;
}

let img_path = cli.image;
let img_dir = cli.images;
let rows = cli.rows.unwrap_or(vec![1]);
let cols = cli.cols.unwrap_or(vec![1]);
let output_directory = cli.output_dir.unwrap_or(PathBuf::from("splixed-images"));

let img_file_name = img_path.file_stem().unwrap().to_string_lossy();
let img_format = io::Reader::open(&img_path).unwrap().format().unwrap();
let img_format_str = img_format.extensions_str()[0];

let split_images = split_image(&img_path, &rows, &cols);

save_images(
&split_images,
&output_directory,
&img_file_name,
&img_format,
img_format_str,
if rows.len() > 1 {
rows.len()
} else {
rows[0] as usize
},
if cols.len() > 1 {
cols.len()
} else {
cols[0] as usize
},
);
for entry in WalkDir::new(&img_dir) {
match entry {
Ok(entry) => {
if let Ok(img) = image::open(entry.path()) {
let split_images = split_image(img, &rows, &cols);
let img_file_name = &entry.path().file_stem().unwrap().to_string_lossy();
let img_format = &ImageFormat::from_path(entry.path()).unwrap();
let img_format_str = img_format.extensions_str()[0];
save_images(
&split_images,
&output_directory,
img_file_name,
img_format,
img_format_str,
if rows.len() > 1 {
rows.len()
} else {
rows[0] as usize
},
if cols.len() > 1 {
cols.len()
} else {
cols[0] as usize
},
)
}
}
Err(_) => continue,
}
}
}

0 comments on commit cd02c5e

Please sign in to comment.