image-alpha-utils is a Python-based utility designed for sophisticated manipulation of image transparency (alpha channels). It empowers users to programmatically add or modify alpha channels by intelligently interpreting the brightness information from a grayscale version of an image. This allows for precise control over which parts of an image become transparent and to what degree.
This tool is part of the twat collection of image processing utilities, integrating with the image_utils_plugin_host ecosystem.
image-alpha-utils is valuable for a diverse range of users:
- Developers & Scripters: Easily integrate advanced alpha channel manipulation into Python scripts and applications for automated image processing workflows.
- Graphic Designers & Digital Artists: Achieve nuanced transparency effects, prepare images for layering in design projects, or create consistent visual styles across multiple images.
- Data Scientists & Researchers: Useful for preprocessing image datasets where transparency can encode important information or mask irrelevant regions.
- Anyone needing precise, content-aware control over image transparency: If you need to make parts of images see-through based on their light/dark areas, this tool provides a powerful and automatable solution.
- Content-Aware Transparency: Creates alpha masks based on the image's own grayscale characteristics, leading to natural-looking transparency effects.
- Precise Control: Offers fine-grained adjustments for how light and dark areas translate to opacity/transparency through adjustable black and white points.
- Automation & Batch Processing: As a CLI tool and Python library, it's perfect for processing many images consistently and efficiently.
- Versatile Integration: Use it as a standalone command-line tool for quick modifications or import it as a library into your Python projects for deeper integration.
- Consistent Effects: Ensure uniform transparency application across a series of images.
- Image Preparation: Ideal for preparing images for web (e.g., transparent PNGs), game development, or complex graphic design compositions.
- Extensible: As part of the
twatecosystem, it's designed to work alongside other image utilities.
You can install image-alpha-utils directly from PyPI:
pip install image-alpha-utilsFor developers looking to contribute or work with the source code, the project uses Hatch for environment and project management. After cloning the repository:
# Install hatch if you haven't already
pip install hatch
# Create and activate development environment
hatch shellimage-alpha-utils can be used both as a command-line interface (CLI) tool (imagealpha) and as a Python library.
The imagealpha command allows you to process images directly from your terminal.
Basic Syntax:
imagealpha [INPUT_PATH] [OUTPUT_PATH] [OPTIONS]INPUT_PATH: Path to the input image file (e.g.,input.jpg,photo.png). Use-to read image data from standard input (stdin).OUTPUT_PATH: Path to save the output PNG image. Use-to write image data to standard output (stdout). The output is always a PNG file to support alpha channels.
Key Options:
--color <name|hex|rgb_tuple>: Specifies the fill color for the RGB channels of the output image. The alpha channel is derived from the input image's grayscale data.- Examples:
--color red,--color "#00FF00",--color "(0,0,255)"(note the quotes for tuples). - Default:
"black".
- Examples:
--white_point <float>: Sets the white threshold for grayscale normalization (range 0.0-1.0, or >1 for percentage). Pixels in the normalized grayscale mask brighter than this value will become fully opaque in the standard alpha mask (or fully transparent if--negativeis used).- Default:
0.9(meaning the brightest 10% of the adjusted tonal range becomes fully opaque). - If
white_point > 1, it's treated as a percentage. For example,white_point=10means the brightest 10% of the pixel value range (after auto-contrast) will be mapped to pure white in the mask. This corresponds to an internal threshold of1.0 - (percentage / 100.0).
- Default:
--black_point <float>: Sets the black threshold for grayscale normalization (range 0.0-1.0, or >1 for percentage). Pixels in the normalized grayscale mask darker than this value will become fully transparent in the standard alpha mask (or fully opaque if--negativeis used).- Default:
0.1(meaning the darkest 10% of the adjusted tonal range becomes fully transparent). - If
black_point > 1, it's treated as a percentage. For example,black_point=10(10%) corresponds to an internal threshold of0.1.
- Default:
--negative: Inverts the interpretation of the alpha mask.- By default (if
--negativeis not set), darker areas of the normalized grayscale image become more transparent in the final image. - If
--negativeis set, lighter areas of the normalized grayscale image become more transparent.
- By default (if
CLI Examples:
-
Basic Conversion: Convert
input.jpgtooutput.pngwith a black base color and alpha derived frominput.jpg's grayscale version.imagealpha input.jpg output.png
-
Specify Output Color & Pipe to Stdout: Make the image red, with transparency, and pipe it to another command or file.
imagealpha input.webp - --color "red" > red_transparent_image.png
-
Adjust Thresholds & Use Negative Mask: Read from stdin, make darker areas more opaque (lighter areas more transparent), and adjust sensitivity. Here, pixel values in the mask below 20% lightness become fully opaque, and above 80% lightness become fully transparent.
cat source_image.png | imagealpha - result.png --black_point 0.2 --white_point 0.8 --negativeOr using percentages for thresholds:
cat source_image.png | imagealpha - result.png --black_point 20 --white_point 80 --negative -
Using a Specific RGB Color Tuple:
imagealpha landscape.jpg transparent_landscape.png --color "(70,130,180)" # Steel blue
To see all available options and their defaults, run imagealpha -- --help.
You can integrate image-alpha-utils directly into your Python scripts for more complex workflows.
Core Function: igray2alpha
The main function you'll use is igray2alpha.
from PIL import Image
from image_alpha_utils import igray2alpha # Core processing function
from image_alpha_utils import parse_color # Optional: if you need to validate colors separately
# 1. Load your input image using Pillow
try:
input_image = Image.open("path/to/your/image.jpg")
except FileNotFoundError:
print("Error: Input image not found.")
exit()
# 2. Process the image
# Example 1: Basic usage (black color, default thresholds)
# Darker areas of input_image's grayscale version become more transparent.
output_image_default = igray2alpha(img=input_image)
output_image_default.save("output_default_alpha.png")
# Example 2: Custom color, adjusted thresholds, and negative mask
# Lighter areas of input_image's grayscale version become more transparent.
# Color is set to a shade of blue.
# Grayscale values below 0.2 become fully opaque in the (inverted) mask.
# Grayscale values above 0.8 become fully transparent in the (inverted) mask.
custom_output_image = igray2alpha(
img=input_image,
color="navy", # Can be name, hex like "#000080", or RGB tuple (0, 0, 128)
white_point=0.8, # Pixels brighter than this (in normalized gray) define opaque limit for negative mask
black_point=0.2, # Pixels darker than this (in normalized gray) define transparent limit for negative mask
negative=True # Lighter areas of the mask become more transparent
)
custom_output_image.save("output_custom_alpha.png")
# Example 3: Using percentage-based thresholds
# Darkest 5% of tones become fully transparent, brightest 15% become fully opaque.
# Color is light gray.
subtle_output_image = igray2alpha(
img=input_image,
color=(211, 211, 211), # Light gray
white_point=15, # Corresponds to 0.85: brightest 15% are opaque
black_point=5, # Corresponds to 0.05: darkest 5% are transparent
negative=False # Darker areas become transparent
)
subtle_output_image.save("output_subtle_alpha.png")
print("Images processed and saved.")Parameters for igray2alpha:
img (PIL.Image.Image): The input image, opened with Pillow.color (str | tuple[int,int,int]): The fill color for the RGB channels. Accepts color names (e.g.,"blue"), hex strings (e.g.,"#0000FF"), or RGB tuples (e.g.,(0, 0, 255)). Default:"black".white_point (float): White threshold for grayscale normalization (0.0-1.0, or >1 for percentage). See CLI option description or function docstring for details. Default:0.9.black_point (float): Black threshold for grayscale normalization (0.0-1.0, or >1 for percentage). See CLI option description or function docstring for details. Default:0.1.negative (bool): IfFalse(default), darker areas of the normalized grayscale mask make the output image more transparent. IfTrue, lighter areas make it more transparent. Default:False.
This section delves into the internal workings of image-alpha-utils, its architecture, and guidelines for contributors.
The primary image processing is handled by the igray2alpha function (located in src/image_alpha_utils/gray2alpha.py). Here's a step-by-step breakdown:
-
Grayscale Conversion:
- The input
PIL.Image.Imageobject is first converted to a grayscale representation usingimg.convert('L'). This creates an image where each pixel has a single luminosity value.
- The input
-
Grayscale Normalization (
normalize_grayscalefunction):- The grayscale image undergoes contrast normalization to prepare it as an effective mask. This crucial step uses the
white_pointandblack_pointparameters. - Auto-Contrast: Initially,
ImageOps.autocontrast()is applied to the grayscale image. This remaps pixel values to expand the tonal range, typically making the darkest pixel black and the lightest pixel white. - Thresholding:
white_point: Defines the luminosity value (in the auto-contrasted image, scaled 0.0-1.0) above which pixels will be mapped to pure white (255) in the final mask.- If
white_pointis provided as a value > 1 (e.g., 10 for 10%), it's interpreted as a percentage of the brightest end of the spectrum to saturate to white. The internal threshold becomes1.0 - (white_point / 100.0). For example,white_point=10results in an effective threshold of0.9.
- If
black_point: Defines the luminosity value (scaled 0.0-1.0) below which pixels will be mapped to pure black (0) in the final mask.- If
black_pointis provided as a value > 1 (e.g., 5 for 5%), it's interpreted as a percentage of the darkest end of the spectrum to saturate to black. The internal threshold becomesblack_point / 100.0. For example,black_point=5results in an effective threshold of0.05.
- If
- It's required that
0 <= black_point < white_point <= 1after any percentage conversion. - Pixels with luminosity values between
black_pointandwhite_pointare linearly scaled to span the full 0-255 range.
- The result of this step is a new grayscale image (
Imagemode 'L') whose pixel values are precisely tuned to serve as an alpha mask.
- The grayscale image undergoes contrast normalization to prepare it as an effective mask. This crucial step uses the
-
Alpha Image Creation (
create_alpha_imagefunction):- A new RGBA image (
Imagemode 'RGBA') is created with the same dimensions as the input image. - Color Application: The RGB channels of this new image are uniformly filled with the
colorspecified by the user. This color is parsed by theparse_colorfunction, which supports CSS color names, hex strings (e.g.,"#RRGGBB"), and Python tuples(R, G, B). - Alpha Channel Application: The normalized grayscale image from step 2 is used as the alpha mask.
- The
negativeflag determines how this mask is applied:- If
negative=False(default): The normalized mask is inverted (ImageOps.invert(mask)). This means that originally darker areas in the normalized mask (which correspond to darker areas in the input image's grayscale version after normalization) become more opaque (higher alpha values) in the output image. White areas in the inverted mask (originally black in normalized mask) become fully transparent (alpha 0). - If
negative=True: The normalized mask is used directly. Darker areas in the normalized mask result in more transparent (lower alpha values) pixels in the output image. White areas in the mask (originally white in normalized mask) become fully opaque (alpha 255).
- If
- The
- The final RGBA image, with the chosen color and the derived alpha channel, is then returned.
- A new RGBA image (
src/image_alpha_utils/gray2alpha.py: This is the main module containing all core logic.igray2alpha(...): The central Python function for library use. It orchestrates the grayscale conversion, normalization, and alpha image creation.gray2alpha(...): The wrapper function exposed to the command line viapython-fire. It handles image loading (viaopen_image), callsigray2alpha, and image saving (viasave_image).normalize_grayscale(img, white_point, black_point): Performs contrast adjustment and thresholding on a grayscale image.create_alpha_image(mask, color, negative): Creates an RGBA image, filling it with the specifiedcolorand using the providedmask(after optional inversion) as the alpha channel.parse_color(color_spec): Converts various color representations (names, hex, RGB tuples) into a standard(R, G, B)tuple.open_image(source): Utility to open an image from a file path orstdin.save_image(img, destination): Utility to save an image to a file path orstdout(always in PNG format).cli(): The entry point for theimagealphacommand-line script.
src/image_alpha_utils/: Contains the main package source code.__init__.py: Makes the package importable and exports key functions likeigray2alphaandparse_color.gray2alpha.py: Core logic module as described above.__version__.py: Dynamically generated by Hatch-VCS to store the package version.
tests/: Contains all unit and integration tests for the project, written usingpytest.pyproject.toml: The heart of the project's build system and packaging configuration (PEP 621). It defines:- Project metadata (name, version, dependencies, authors, etc.).
- Build system requirements (Hatch).
- Entry points (for CLI scripts like
imagealphaand for plugin registration). - Development dependencies and scripts for testing, linting, and type checking.
- Configuration for tools like Ruff (linter/formatter) and MyPy (type checker).
README.md: This file – providing user and developer documentation.CLAUDE.md: Contains specific instructions and context for AI-assisted development (like the one you're reading from!).LICENSE: Contains the MIT License text.old/: As noted inCLAUDE.md, this directory contains a collection of older, standalone image processing scripts. While they might offer historical context or inspiration,image-alpha-utilsis the current, packaged tool for alpha manipulation.
This project adheres to modern Python development practices. If you wish to contribute, please follow these guidelines (largely managed by Hatch and defined in pyproject.toml):
- Build System & Environment: The project uses Hatch.
- Activate the development environment:
hatch shell - Hatch scripts manage common tasks (see below).
- Activate the development environment:
- Testing:
pytestis used for testing.- Run all tests:
hatch run test - Run tests with coverage:
hatch run test-cov - Tests are located in the
tests/directory and should be written for any new functionality or bug fix.
- Run all tests:
- Linting and Formatting: Ruff is used for both linting and code formatting to ensure a consistent style.
- Check for linting issues and format code:
hatch run lint(this typically runsruff checkandruff format). - Format code only:
hatch run fmt(or a similar script defined inpyproject.toml, e.g.,hatch run stylemight include formatting). - Configuration is in the
[tool.ruff]section ofpyproject.toml.
- Check for linting issues and format code:
- Type Safety: The project uses strict static type checking with MyPy.
- Run type checking:
hatch run type-check(orhatch run lint:allor similar, checkpyproject.toml). - All functions and methods must have comprehensive type hints.
- MyPy configuration is in the
[tool.mypy]section ofpyproject.toml.
- Run type checking:
- Dependencies: Project dependencies are managed in
pyproject.tomlunder[project.dependencies]and[project.optional-dependencies]. - Plugin System Integration:
image-alpha-utilsis designed as a plugin for theimage_utils_plugin_hostsystem (part of the broadertwatcollection).- The entry point is defined in
pyproject.tomlunder[project.entry-points."image_utils_plugin_host.plugins"]. This allows theigray2alphafunction to be discovered and used by the host application.
- The entry point is defined in
- Version Control: Git is used for version control. Versioning is managed by
hatch-vcs. - Commits and Pull Requests:
- Ensure all tests pass locally before committing.
- Ensure code is formatted and passes linting and type checks.
- Write clear and descriptive commit messages.
- For new features or significant changes, consider opening an issue first to discuss the changes.