Il naissait un poulain sous les feuilles de bronze..
Mon seul désir. Musée de Cluny, Paris.
Just needed a tool to quickly proofread some snaps. The script concatenates images with shared alphabetic prefixes into horizontally stitched strips.
Contents - click to expand
- Groups files by alphabetic prefix + sequential numeric suffix ordering.
- Supports common image formats: JPG, PNG, WEBP, BMP, TIFF.
- Optional page-height configuration: scale images taller than the page height while preserving aspect ratio; otherwise uses the tallest image in the group.
- Vertical centering and configurable background color.
- Saves stitched images with a
_stitched.pngprefix.
- Python 3.x
- Pillow
- regex (the third-party
regexmodule)
Install dependencies:
pip install pillow regex-
Put source images into
INPUT_DIR. -
Adjust configuration at top of the script if needed:
INPUT_DIR,OUTPUT_DIRPAGE_HEIGHT(Noneto auto-use max height in group, or set integer pixels)BACKGROUND_COLOR(RGB tuple)SUPPORTED_EXT(tuple of supported image extensions)
-
Run:
python assemble.pyOutput files are written into OUTPUT_DIR (default: output_images).
At top of the script:
INPUT_DIR = "input"
OUTPUT_DIR = "output_images"
PAGE_HEIGHT = None # or PAGE_HEIGHT = 1200
BACKGROUND_COLOR = (255,255,255)
SUPPORTED_EXT = (".jpg", ".jpeg", ".png", ".webp", ".bmp", ".tiff")Files:
input/photo1.jpginput/photo2.jpginput/logo.png
Result:
output_images/photo_stitched.png(photo1 + photo2 stitched)output_images/logo_stitched.png(single-image stitched output)
Achieved through a regex to split the filename (without extension) into:
prefix: one or more letters, marks, whitespace, underscore or hyphen- an optional numeric
numsuffix
Examples:
imgA12.jpg→ prefiximgA, num12photo_3.png→ prefixphoto_, num3sample.bmp→ prefixsample, num0
Note
Files without a supported extension are ignored.
collect_images: scansINPUT_DIRand returns files with supported extensions.group_files: groups files by prefix, sorts each group by numeric suffix then filename for deterministic ordering.stitch_group:- Loads images with Pillow and converts to RGBA.
- Determines page height:
PAGE_HEIGHTif set, otherwise max image height in the group. - Resizes images taller than page height to match page height (preserves aspect ratio).
- Computes canvas width as sum of image widths (ensures canvas width ≥ canvas height).
- Pastes images side-by-side, vertically centered, onto an RGBA canvas using
BACKGROUND_COLOR. - Converts to RGB and saves as PNG named
groupname + _stitched.pnginOUTPUT_DIR.
- Script prints warnings for unreadable files and prints saved output paths.
- "Input directory not found": ensure
INPUT_DIRexists or update the path. - "No images found": verify supported extensions and that files are not hidden.
- Corrupt/unopenable images: script prints a warning and skips them.
- If Unicode filenames cause issues, ensure your environment supports UTF-8 and that the
regexmodule is installed.
- Horizontal-only stitching: images are concatenated side-by-side (landscape orientation assumed).
PAGE_HEIGHTonly scales images that are taller than the target height; shorter images are not padded vertically (they are centered).- The grouping regex focuses on letter/mark characters plus optional digits; unusual naming schemes may produce unexpected groups.
- Output is flattened to RGB PNG; alpha becomes composited over
BACKGROUND_COLOR.
Creative Commons Zero v1.0 Universal.
🀆
