diff --git a/CHANGELOG.md b/CHANGELOG.md
index 348a34dba88bbfffeaf72d9fc4d0d0d2cdcc856b..00207cd44e88572c410f69316dca85f122dcdb9c 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -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
 
diff --git a/src/commands/extrude.rs b/src/commands/extrude.rs
index fdff8c9969d9c6d38cd1d263de04b11e08a746e4..1bbff08b098e26424883bf8ce4a51b1ce0e00048 100644
--- a/src/commands/extrude.rs
+++ b/src/commands/extrude.rs
@@ -1,8 +1,11 @@
 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,
+				);
 			}
 		}
 
diff --git a/src/utils.rs b/src/utils.rs
index edef97e1567ef32d88100ffda3625a586c67bb42..eb21cbe93e57279b23bdf0cc5b357e96bb352325 100644
--- a/src/utils.rs
+++ b/src/utils.rs
@@ -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,