Skip to content
Snippets Groups Projects
extrude.rs 1.97 KiB
Newer Older
Louis's avatar
Louis committed
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)
}