Skip to content
Snippets Groups Projects
Verified Commit a58d483e authored by Louis's avatar Louis :fire:
Browse files

Simplify image extrusion, support pixel-clone extrusion

parent 80781d51
No related branches found
No related tags found
No related merge requests found
......@@ -5,6 +5,13 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [Unreleased]
### Added
- Support for `--extrude` param in `extrude` command
## [0.5.0] - 2023-02-22
### Added
- `split` command for taking a sprite sheet and converting it into individual tiles
### Changed
- Moved all arguments into subcommands, for a less confusing end user experience
......
use crate::utils::{RgbaOutputFormat, SpriteData};
use clap::Parser;
use image::{GenericImage, GenericImageView, Pixel, Rgba, RgbaImage};
use image::flat::View;
use image::math::Rect;
use image::{DynamicImage, GenericImage, GenericImageView, Pixel, Rgba, RgbaImage};
use num_traits::cast::ToPrimitive;
use serde::{Deserialize, Serialize};
use std::ops::Deref;
#[inline(always)]
fn tile_size() -> u32 {
......@@ -44,7 +47,10 @@ pub struct Extrude {
}
impl Extrude {
pub fn run(&self, image: &impl GenericImage) -> anyhow::Result<RgbaOutputFormat> {
pub fn run(
&self,
image: &impl GenericImage<Pixel = Rgba<u8>>,
) -> anyhow::Result<RgbaOutputFormat> {
log::info!(
"Image loaded with size {} x {}",
image.width(),
......@@ -84,32 +90,59 @@ impl Extrude {
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]));
}
}
let mut new_image = RgbaImage::from_pixel(new_width, new_height, 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(),
]);
let target_x = self.padding + img_x + (sprite.tx * self.space_x);
let target_y = self.padding + img_y + (sprite.ty * self.space_y);
new_image.copy_from(sprite.data.deref(), target_x, target_y)?;
new_image.put_pixel(
self.padding + (sprite.tx * self.space_x) + img_x + x,
self.padding + (sprite.ty * self.space_y) + img_y + y,
p,
);
}
if self.extrude {
// Left Side
new_image.copy_within(
Rect {
x: target_x,
y: target_y,
width: 1,
height,
},
target_x.saturating_sub(1),
target_y,
);
// Right Side
new_image.copy_within(
Rect {
x: target_x + width - 1,
y: target_y,
width: 1,
height,
},
target_x + width,
target_y,
);
// Top Side
new_image.copy_within(
Rect {
x: target_x,
y: target_y,
width,
height: 1,
},
target_x,
target_y.saturating_sub(1),
);
// Bottom Side
new_image.copy_within(
Rect {
x: target_x,
y: target_y + height - 1,
width,
height: 1,
},
target_x,
target_y + height,
);
}
}
......
......@@ -10,10 +10,14 @@ use lab::Lab;
pub struct SpriteData<'a, T: GenericImage> {
pub data: SubImage<&'a T>,
#[allow(dead_code)]
/// Horizontal pixel coordinate of this sprite within the parent image
pub x: u32,
#[allow(dead_code)]
/// Vertical pixel coordinate of this sprite within the parent image
pub y: u32,
/// "Tile X" - The horizontal grid position of this Sprite within a Spritesheet
pub tx: u32,
/// "Tile Y" - The vertical grid position of this Sprite within a Spritesheet
pub ty: u32,
#[allow(dead_code)]
pub width: u32,
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment