bat_img
Fast, multithreaded batch image processor — available as a standalone
command-line tool installable via pip.
The binary is a native Rust executable (no Python overhead at runtime). The Python package is simply a convenient delivery mechanism so you can install bat_img the same way you install any other command-line tool.
Installation
pip install bat_img
brew install libheif # for HEIC/HEIF support
Pre-built binaries are provided for:
| Platform | Architecture |
|---|---|
| macOS | Apple Silicon |
| Linux | x86-64 (glibc 2.17+, compatible with most distros) |
| Windows | x86-64 |
After installation, the bat_img command is available in your terminal.
Quick start
# Strip GPS location from all iPhone photos (in-place)
bat_img -i ~/Pictures/iPhone --strip-gps
# Resize all JPEGs to 1920 px wide, save to ./web/
bat_img -i ./photos -r 1920x0 -o ./web
# Convert HEIC → WebP at quality 85, resize to 2048 px wide
bat_img -i ./iphone_photos -r 2048x0 -f webp -q 85 -o ./web
# Strip ALL metadata, sharpen — 8 threads, recurse
bat_img -i ./raw -R --strip-all --sharpen -t 8 -o ./export
Features
| Feature | Flag |
|---|---|
| In-place processing — overwrite originals | (omit --output) |
| Print image metadata (dimensions, size, format, date/time, etc.) | --info |
| Strip GPS location from EXIF | --strip-gps |
| Strip ALL metadata (EXIF, IPTC, XMP) | --strip-all |
| Resize (width, height, or both) | -r 1920x0 |
| No-upscale guard | --no-upscale |
| Resize filter | --filter lanczos3 |
| Add solid border | --border 20 --border-color "#fff" |
| Rotate 90 / 180 / 270° | --rotate 90 |
| Flip horizontal / vertical | --flip-h / --flip-v |
| Brightness adjustment | --brightness 10 |
| Contrast adjustment | --contrast 15 |
| Sharpen | --sharpen |
| Grayscale | --grayscale |
| Format conversion incl. HEIC | -f heic / webp / png / jpeg / tiff |
| JPEG / WebP quality | -q 85 |
| Filename prefix / suffix | --prefix web_ --suffix _sm |
| Parallel threads | -t 8 |
| Dry-run preview | --dry-run |
| Recursive directory walk | -R |
Usage
bat_img [OPTIONS] --input <INPUT>...
All options
-i, --input <INPUT>... Input: file path, glob pattern, or directory (e.g. ./photos, "*.jpg", ./img/photo.png)
-o, --output <OUTPUT> Output directory. When omitted, each input file is processed in-place (the original is overwritten)
-R, --recursive Recurse into subdirectories when input is a directory
--info Print image metadata (dimensions, size, format, date/time, etc.)
--strip-gps Strip GPS location data from EXIF metadata
--strip-all Strip ALL EXIF/IPTC/XMP metadata (implies --strip-gps)
-r, --resize <WxH> Resize image. Format: WIDTHxHEIGHT (e.g. 1920x1080). Use 0 for auto (e.g. 1920x0 = fit width, 0x1080 = fit height)
--filter <FILTER> Resize filter algorithm [default: lanczos3] [possible values: nearest, triangle, catmull-rom, gaussian, lanczos3]
--no-upscale Do not upscale images smaller than the target size
--border <PIXELS> Add a border of N pixels on each side
--border-color <COLOR> Border color as CSS hex (#rrggbb) or name (white, black, red…) [default: white]
--rotate <DEGREES> Rotate image clockwise by degrees (90, 180, 270)
--flip-h Flip image horizontally (mirror left-right)
--flip-v Flip image vertically (mirror top-bottom)
--brightness <VALUE> Brightness adjustment (-100 to +100)
--contrast <VALUE> Contrast adjustment (-100 to +100)
--sharpen Apply sharpening filter
--grayscale Convert to grayscale
-f, --format <FORMAT> Output format (defaults to same as input) [possible values: jpeg, png, webp, tiff, bmp, gif, heic, heif]
-q, --quality <1-100> JPEG/WebP output quality (1–100), required for non-HEIC output. Default is 90 if not set. HEIC file is encoded with the default encoder
--suffix <SUFFIX> Filename suffix appended before extension (e.g. "_edited" → photo_edited.jpg) [default: ""]
--prefix <PREFIX> Filename prefix prepended (e.g. "web_" → web_photo.jpg) [default: ""]
-t, --threads <THREADS> Number of threads to use (default: physical CPUs qty on macOS; logical CPUs qty on others) [default: 8]
--overwrite Overwrite existing output files (default: skip)
--quiet Suppress all output except errors
--dry-run Dry-run: show what would be done without processing
-h, --help Print help
-V, --version Print version
In-place mode
Omitting --output overwrites each original file in place. A temp file is
written first and then atomically renamed over the original, so the source
is never corrupted if something goes wrong.
# Show all image files meta data
bat_img -i ./photos --info
# Strip GPS from every HEIC file recursively — no copies made
bat_img -i ~/Pictures -R --strip-gps
# Resize all JPEGs to 2048 px wide, in-place
bat_img -i ./photos -r 2048x0
Note: in-place mode cannot change the file format (e.g. HEIC → WebP).
Use --output when changing formats.
Examples
# Add a 20 px black border to all PNGs
bat_img -i ./screenshots --border 20 --border-color black -o ./bordered
# Rotate scans 90° clockwise and convert to grayscale
bat_img -i ./scans --rotate 90 --grayscale -o ./processed
# Convert HEIC → JPEG at quality 90, resize to fit 1920×1080
bat_img -i ./iphone_photos -f jpeg -q 90 -r 1920x1080 -o ./jpegs
# Dry-run — see what would happen without writing anything
bat_img -i ./photos -r 800x600 --strip-gps --dry-run
HEIC support
bat_img can read and write HEIC/HEIF files natively, including:
- Decoding HEIC photos from iPhone / iPad
- Re-encoding back to HEIC while preserving the original codec (HEVC / AV1)
and file size (unless
--qualityis specified) - Converting HEIC to any other supported format with
-f jpeg,-f webp, etc.
License
bat_img is distributed under MIT License. Please see details in LICENSE.
Metadata
Release files for bat-img 1.1.4
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| bat_img-1.1.4.tar.gz | 5.3 kB | Details |
Built distributions (wheels)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| bat_img-1.1.4-py3-none-win_amd64.whl | Python 3 | none | Windows x86-64 | Details |
| bat_img-1.1.4-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl | Python 3 | none | Linux glibc 2.17+ x86-64 | Details |
| bat_img-1.1.4-py3-none-macosx_11_0_arm64.whl | Python 3 | none | macOS 11.0+ ARM64 | Details |
Total release size: 5.3 MB
Release files / bat_img-1.1.4.tar.gz
| Download URL | bat_img-1.1.4.tar.gz |
|---|---|
| Size | 5.3 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
0ce063e4fa63b8703b60ca47c19367170ebec5b2ae248ccd5ca67b720d71cf3e
|
|
BLAKE2b-256 checksum How to use checksums |
75280dd401c0403067dc4fe846076b50cfccd9d527133322961bd82fcd4a6b7f
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 4, 2026.
Transparency logRelease files / bat_img-1.1.4-py3-none-win_amd64.whl
| Download URL | bat_img-1.1.4-py3-none-win_amd64.whl |
|---|---|
| Size | 2.8 MB |
| Tags | Python 3 Windows x86-64 |
|
SHA-256 checksum How to use checksums |
cf76501e8ee4258d91a3c2f52058092f9c1da7721457ed3ac4a3572a25c82e9b
|
|
BLAKE2b-256 checksum How to use checksums |
a0c2a80a1e65ab4d30a43acd411b0e8b74dc26ed4debfee0323d4a388d3414b5
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 4, 2026.
Transparency logRelease files / bat_img-1.1.4-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
| Download URL | bat_img-1.1.4-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl |
|---|---|
| Size | 1.4 MB |
| Tags | Linux glibc 2.17+ x86-64 Python 3 |
|
SHA-256 checksum How to use checksums |
1a7b0c0270239dc1b747d0b5a0fbf00ac5dc5da5b1a8b5d3bf6245963754a57a
|
|
BLAKE2b-256 checksum How to use checksums |
64bdc7a6c7f2b66d0c98c102f3c8b32740232522bc33cb7088c90ad6bfb3da93
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 4, 2026.
Transparency logRelease files / bat_img-1.1.4-py3-none-macosx_11_0_arm64.whl
| Download URL | bat_img-1.1.4-py3-none-macosx_11_0_arm64.whl |
|---|---|
| Size | 1.2 MB |
| Tags | Python 3 macOS 11.0+ ARM64 |
|
SHA-256 checksum How to use checksums |
75c32923a7d5226f8b3906dd77b8f30b9ff8e956eb59dd24c230aa1e6d398eff
|
|
BLAKE2b-256 checksum How to use checksums |
75fd7d97cee4b556f83c316796dd20cecf2ba245af5b213b923a9faa90833a58
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 4, 2026.
Transparency log