use image::{GenericImage, GenericImageView, Pixel, Rgba, RgbaImage}; use num_traits::cast::ToPrimitive; use crate::{OutputFormat, SpriteData}; pub fn extrude( image: impl GenericImage, tile_size: u32, pad_x: u32, pad_y: u32, space_x: u32, space_y: u32, _extrude: bool, ) -> anyhow::Result<OutputFormat> { log::info!( "Image loaded with size {} x {}", image.width(), image.height() ); let columns = image.width() / tile_size; let rows = image.height() / tile_size; log::info!("Inferred sheet contains {} columns", columns); log::info!("Inferred sheet contains {} rows", rows); let mut views = Vec::with_capacity((columns * rows) as usize); for x in 0..columns { for y in 0..rows { let img_x = x * tile_size; let img_y = y * tile_size; let payload = SpriteData { data: image.view(img_x, img_y, tile_size, tile_size), x: img_x, y: img_y, tx: x, ty: y, width: tile_size, height: tile_size, }; views.push(payload); } } let new_width = (pad_x * 2 + space_x * columns) + image.width(); let new_height = (pad_y * 2 + space_y * rows) + image.height(); log::info!( "Using new image width {} / height {}", new_width, new_height ); let mut new_image = RgbaImage::new(new_width, new_height); let (new_image_x, new_image_y, new_image_width, new_image_height) = new_image.bounds(); for x in new_image_x..new_image_width { for y in new_image_y..new_image_height { new_image.put_pixel(x, y, Rgba::from([0, 0, 0, 0])); } } for sprite in views.iter() { let (img_x, img_y, width, height) = sprite.data.bounds(); for x in 0..width { for y in 0..height { let pix = sprite.data.get_pixel(x, y).to_rgba(); let p = Rgba::from([ pix.0[0].to_u8().unwrap(), pix.0[1].to_u8().unwrap(), pix.0[2].to_u8().unwrap(), pix.0[3].to_u8().unwrap(), ]); new_image.put_pixel( pad_x + (sprite.tx * space_x) + img_x + x, pad_y + (sprite.ty * space_y) + img_y + y, p, ); } } } Ok(new_image) }