use image::{GenericImageView, ImageBuffer, Rgba};
use std::path::Path;
pub fn split_image<P: AsRef<Path>>(image_path: P) -> Result<Vec<ImageBuffer<Rgba<u8>, Vec<u8>>>, image::ImageError> {
let img = image::open(image_path)?;
let (width, height) = img.dimensions();
let sub_width = width / 3;
let sub_height = height / 3;
let mut sub_images = Vec::new();
for y in 0..3 {
for x in 0..3 {
let sub_img = img.crop_imm(
x * sub_width,
y * sub_height,
sub_width,
sub_height
);
sub_images.push(sub_img.to_rgba8());
}
}
Ok(sub_images)
}
pub fn split_image_with_size<P: AsRef<Path>>(
image_path: P,
sub_width: u32,
sub_height: u32,
) -> Result<Vec<ImageBuffer<Rgba<u8>, Vec<u8>>>, image::ImageError> {
let img = image::open(image_path)?;
let (width, height) = img.dimensions();
let num_cols = (width + sub_width - 1) / sub_width;
let num_rows = (height + sub_height - 1) / sub_height;
let mut sub_images = Vec::new();
for y in 0..num_rows {
for x in 0..num_cols {
let x_pos = x * sub_width;
let y_pos = y * sub_height;
let actual_width = (width - x_pos).min(sub_width);
let actual_height = (height - y_pos).min(sub_height);
let sub_img = img.crop_imm(
x_pos,
y_pos,
actual_width,
actual_height
);
sub_images.push(sub_img.to_rgba8());
}
}
Ok(sub_images)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_split_image() {
let result = split_image("tests/test_image.png");
assert!(result.is_ok());
let sub_images = result.unwrap();
assert_eq!(sub_images.len(), 9);
}
#[test]
fn test_split_image_with_size() {
let result = split_image_with_size("tests/test_image.png", 100, 100);
assert!(result.is_ok());
let sub_images = result.unwrap();
assert!(sub_images.len() > 0);
}
}