Batch Image Compressor CLI
Command-line tool for bulk image compression — converts high-res photos to WebP/PNG, strips EXIF metadata, and downsizes oversized images to optimize static asset footprints.
A command-line utility for bulk image compression — a single Python file that converts whole folders of high-resolution photos to WebP or PNG at minimum size, built to prepare gallery assets before static hosting.
Highlights
- One script, no setup — a single standalone file with four dependencies, runnable from any command line without a project scaffold.
- iPhone photos work without a conversion step first —
pillow-heifregisters HEIC and HEIF alongside JPG, PNG, BMP, TIFF, GIF and WebP, so the format that phones actually produce is a first-class input rather than an error. - Portrait photos stop coming out sideways — EXIF orientation is applied to the pixels before encoding, because the orientation tag is stripped along with the rest of the metadata and anything relying on it would silently rotate.
- A second, Rust-based compression pass on PNG — after Pillow encodes,
pyoxipngre-optimises the file. An optional zopfli mode squeezes a further 5–10% at 10–50× the runtime, which is documented as a trade-off rather than enabled by default. - Both output formats in one run — WebP and PNG can be generated simultaneously into separate subfolders, which is what makes an A/B comparison practical rather than a second full pass.
- One corrupt file does not end the job — per-image error handling keeps a batch going, and a
tqdmprogress bar shows where it is. - The format guidance is part of the tool — WebP's lossy VP8 codec can be 10–50× smaller on photographs with thousands of colours, while a flat logo under 100 colours is often better served by PNG quantisation. The README states when each choice wins instead of assuming WebP always does.
Key Features
- Batch compression — processes an entire directory in a single command, with configurable input and output folders.
- WebP output — lossy at
quality=82, method=6by default, or near-lossless for pixel-perfect results at a larger size. - PNG output —
quantizemode reduces to a 2–256 colour palette (roughly 60–70% smaller), orlosslessmode keeps pixels identical. - Automatic downscaling — images wider than 1920 px are resized proportionally with a LANCZOS filter.
- Metadata stripping — EXIF is removed to save bytes, after orientation has been applied.
- Eleven CLI flags — format, quality, max width, PNG mode, palette size, zopfli and its iteration count, near-lossless, and the I/O folders are all overridable.
Tech Stack
- Python 3.9+
- Pillow ≥ 10 (decode, resize, encode)
- pillow-heif ≥ 0.16 (HEIC / HEIF input)
- pyoxipng ≥ 9 (Rust-based PNG re-optimisation, optional zopfli)
- tqdm ≥ 4.65 (progress reporting)
Status & Maturity
Complete and stable — a self-contained utility whose behaviour is deterministic and straightforward to verify by inspecting output sizes directly. It has no automated tests, which is the honest state of it: the correctness question here is visual and dimensional rather than logical. Two commits spread across two months reflect a tool that was written, used, and then only revisited when a new input format was needed.
Measured Metrics
| Commits | 2 |
| Date Range | 24 May 2026 – 22 Jul 2026 |
| Lines of code | 859 |
| Automated tests | none |