personal_site/scripts/colour_to_alpha.py

46 lines
1.3 KiB
Python

# Run me with uv run scripts/colour_to_alpha.py INPUT_PATH -o [OUTPUT_PATH]
# /// script
# requires-python = ">=3.11"
# dependencies = [
# "click",
# "numpy",
# "pillow",
# ]
# ///
from pathlib import Path
import click
import numpy as np
from PIL import Image
@click.command()
@click.argument('input_path', type=click.Path(exists=True, dir_okay=False, path_type=Path))
@click.option('--output', '-o', type=click.Path(dir_okay=False, path_type=Path), help="Path to save the output image.")
def process_image(input_path, output):
output_path = output or input_path
# Convert to 64bit floats from 0 - 1
color = np.asarray(Image.open(input_path).convert("RGB")).astype(np.float64) / 255.0
white = np.array([1., 1., 1.])
alpha = 1 - np.min(color, axis=2)
premultiplied_new_color = (color - (1 - alpha)[:, :, None] * white[None, None, :])
new_color = np.divide(
premultiplied_new_color,
alpha[:, :, None],
out=np.zeros_like(premultiplied_new_color),
where=alpha[:, :, None] != 0
)
new_RGBA = np.concatenate([new_color, alpha[:, :, None]], axis=2)
img = Image.fromarray((new_RGBA * 255).astype(np.uint8), mode="RGBA")
img.save(output_path)
click.echo(f"Saved processed image to: {output_path}")
if __name__ == "__main__":
process_image()