Skip to content
Snippets Groups Projects
remap.rs 1.48 KiB
Newer Older
use clap::Parser;
Louis's avatar
Louis committed
use image::{GenericImage, Pixel, Rgba};
use num_traits::ToPrimitive;
use serde::{Deserialize, Serialize};
Louis's avatar
Louis committed
use crunch_cli::utils::{new_image, BasicRgba, OutputFormat, PaletteMap};
Louis's avatar
Louis committed
/// Convert the colour space of an image to that of a given palette file
#[derive(Debug, Clone, Parser, Serialize, Deserialize)]
#[clap(author, version = "0.3.0")]
pub struct Remap {
Louis's avatar
Louis committed
	/// The path to the image file
	#[serde(default)]
	pub input: String,
Louis's avatar
Louis committed
	/// The path to write the recoloured image
	#[serde(default)]
	pub output: String,

	/// The path to the palette file containing the output colours
	#[clap(short, long)]
	pub palette: String,
}

impl Remap {
	pub fn remap_image(
		image: impl GenericImage,
Louis's avatar
Louis committed
		mappings: PaletteMap,
	) -> anyhow::Result<OutputFormat> {
		let mut output = new_image(image.width(), image.height());
		for (x, y, pixel) in image.pixels() {
			let pixel = pixel.to_rgba();

			if pixel.0[3].to_u8().unwrap() == 0 {
				output.put_pixel(x, y, Rgba::from(BasicRgba::transparent()));
				continue;
			}

			let data = Rgba::from([
				pixel.0[0].to_u8().unwrap(),
				pixel.0[1].to_u8().unwrap(),
				pixel.0[2].to_u8().unwrap(),
				pixel.0[3].to_u8().unwrap(),
			]);
			let basic = BasicRgba::from(data);

			match mappings.get(&basic) {
				Some(mapped_data) => output.put_pixel(
					x,
					y,
					Rgba::from(BasicRgba {
						a: basic.a,
						..*mapped_data
					}),
				),
				None => output.put_pixel(x, y, Rgba::from(BasicRgba::transparent())),
			};
Louis's avatar
Louis committed
		}

		Ok(output)
Louis's avatar
Louis committed
	}
}