Skip to content

Repository files navigation

autotone.sh — Intelligent Batch Photo Enhancer

A self-contained, cross-platform command-line tool that analyzes each photo and applies the right correction automatically — like Lightroom's Auto Tone, but adaptive: it measures exposure, white balance, contrast and saturation per image and decides the treatment, instead of stamping a blind preset on everything.

It is built for photographic, wedding-grade quality and is non-destructive: your originals are never touched — results are written to a separate folder.

🖥️ Prefer clicking to typing? There's also a desktop GUI — a small cross-platform app (macOS / Windows) that drives this same engine with a live preview. Grab a ready-to-run build from the Releases page. See Desktop GUI.

TL;DR — just run it

chmod +x autotone.sh          # once
./autotone.sh ./photos        # auto-corrects every photo into ./photos/edited

No flags needed. AUTO analyzes each photo on its own and applies the right white balance, exposure, contrast, colour, shadow/highlight recovery and noise reduction. Everything below is for when you want to take the wheel.


  • 🧠 Adaptive AUTO — per-image white balance, exposure, contrast and vibrance, with automatic shadow/highlight recovery.
  • 🔬 Colour-correct pipeline — ICC-aware input (Display P3 / Adobe RGB → sRGB), linear-light white balance & blends, contrast on Lab luminance (no hue drift), vibrance instead of flat saturation, full Q16-HDRI headroom clipped only at export.
  • 🎨 Creative looks — warm, cold, film, vivid, soft, matte, punch, sepia, vintage, bokeh, dream, cinema, infrared.
  • Black & White — channel-mixer B&W with darkroom filters (neutral / portrait / landscape / red / infrared), plus B&W that keeps one color.
  • 🌓 Recovery & denoise — Lightroom-style --shadows/--highlights and edge-preserving luminance --denoise (auto-strength).
  • 🔭 Lens corrections — dependency-free --defringe (chromatic aberration) and --devignette (corner darkening); full --lens via lensfun if installed.
  • 💾 Presets — save a look once (--preset-save), reuse it across shoots (--preset-load).
  • 📦 Smart compression — TinyPNG/TinyJPG-style: turn 10 MB photos into a few KB/MB. Hit a byte budget (--target-size) or squeeze visually-lossless (--compress).
  • 📥 Flexible input — a folder or an explicit list of files (relative/absolute).
  • 🔍 Smart upscaling — Real-ESRGAN (AI) if installed, high-quality Lanczos otherwise.
  • ✂️ Smart cropping — content-aware trim or a target aspect ratio.
  • 💎 Quality first — 16-bit internal pipeline, no clipping, optional lossless output.
  • 🛠 Self-contained — detects missing tools and offers to install them.

Table of contents


Desktop GUI

Don't want to live in the terminal? autotone ships with a lightweight cross-platform desktop app that drives the exact same engine — it shells out to autotone.sh for the real render, so output is byte-identical to the CLI.

  • 🖱️ Point-and-click — drag in a folder, browse the strip, click look chips.
  • 👁️ Live preview — a fast, representative preview of each look on a proxy of your photo (the full adaptive pipeline still runs at export).
  • ✂️ Interactive crop — draw a pixel crop on the active image, or pick a ratio (4:5, 1:1, 16:9, auto) that applies to the whole batch.
  • 🪶 Tiny — built with Tauri v2 (system webview + a small Rust core), so the bundle is a few MB, not a bundled browser.
  • 🔒 No duplicated colour science — the GUI never reimplements the pipeline and never modifies the script. See the isolation contract.

Get it

Download a build for macOS or Windows from the Releases page — no toolchain needed. ImageMagick still has to be on your PATH (the same dependency as the CLI; the app detects it and tells you if it's missing).

Or build it yourself:

cd gui
npm install
npm run tauri dev      # hot-reload dev app
npm run tauri build    # native bundle in src-tauri/target/release/bundle

Full details — layout, IPC bridge commands, and known v1 limits — live in gui/README.md.


Requirements

Tool Required? Used for
ImageMagick 7 (magick) ✅ Yes (IM6 convert also works) The whole pipeline
Real-ESRGAN (realesrgan-ncnn-vulkan) ⬜ Optional Best-quality AI upscaling
exiftool ⬜ Optional Faithful EXIF/IPTC/XMP copy to outputs

ImageMagick Q16-HDRI is recommended (more headroom, no clipping). The script warns if you have a non-HDRI build but still works.

The script runs on macOS, Linux and Windows (Git Bash / WSL / MSYS2).

Installation

# Make it executable once:
chmod +x autotone.sh

If ImageMagick is missing, the script detects your package manager (brew, apt-get, dnf, pacman, zypper, apk, choco, scoop, winget) and offers to install it. Use -y to auto-confirm.

Manual installs if you prefer:

# macOS
brew install imagemagick
brew install realesrgan-ncnn-vulkan   # optional, for AI upscaling
brew install exiftool                 # optional, for metadata

# Debian / Ubuntu
sudo apt-get install imagemagick libimage-exiftool-perl

# Windows
winget install ImageMagick.ImageMagick

Quick start

# Auto-correct every image in a folder (results land in ./wedding/edited)
./autotone.sh ./wedding

# Auto-correct the current folder
./autotone.sh

# Auto-correct two specific files
./autotone.sh photo1.jpg /abs/path/photo2.cr2

Modes

Select with -m / --mode (default: auto).

Mode What it does
auto Smart, wedding-grade correction. The baseline for everything.
warm Auto correction + warmer, golden tone.
cold Auto correction + cooler, editorial tone.
film Auto correction + soft filmic curve, faded blacks, gentle desat.
vivid Auto correction + bolder color and contrast.
soft Auto correction + gentle, low-contrast portrait look.
matte Auto correction + matte/flat shadows (fashion look).
punch Auto correction + high clarity and pop (extra sharpening).
sepia Warm monochrome sepia — the classic darkroom print tone.
vintage Aged/antique look: faded & yellowed tones with a soft corner vignette.
bokeh Fake shallow depth-of-field — centered subject stays sharp, background blurs.
dream Soft ethereal glow (Orton effect) — lovely for portraits, weddings, flowers.
cinema Teal-orange cinematic color grade (shadows → teal, highlights → orange).
infrared Surreal false-color infrared simulation (foliage glows, skies darken).
bw Photographic black & white via a channel mixer (see --bw-filter).
bw-accent Black & white that keeps one color (see --accent).
none No tonal edit — useful with --upscale, --crop and/or compression only.

All creative looks are built on top of the adaptive AUTO base, so a warm photo is still correctly exposed and white-balanced first, then warmed.

Use -s / --strength (0–2, default 1.0) to dial any look up or down.

Black & white filters (--bw-filter)

A flat luminance mix renders skin and blue sky at nearly the same grey. Real B&W character comes from the channel mix — exactly like a darkroom contrast filter or Lightroom's B&W sliders. Pick one with --bw-filter (mode bw):

./autotone.sh -m bw --bw-filter portrait  headshot.jpg   # bright, smooth skin
./autotone.sh -m bw --bw-filter landscape valley.jpg     # deep sky, light foliage
./autotone.sh -m bw --bw-filter red        skyline.jpg   # dramatic dark skies
./autotone.sh -m bw --bw-filter infrared   forest.jpg    # glowing foliage, black sky
./autotone.sh -m bw                        any.jpg        # neutral (default)
Filter Renders Good for
neutral balanced, natural greys (default) general use
portrait reds/oranges lighter → bright, smooth skin faces, weddings
landscape greens up, blues down → light foliage, deep sky scenery
red heavy red weight → dramatic dark skies, bright skin architecture, drama
infrared green-dominant → glowing foliage, near-black sky surreal/fine-art

All filters produce a true neutral (R=G=B) image with darkroom contrast.

Keeping a color (bw-accent)

./autotone.sh -m bw-accent --accent red  bouquet.jpg
./autotone.sh -m bw-accent --accent blue dress.jpg
./autotone.sh -m bw-accent --accent 210  custom-hue.jpg   # any hue 0–360

Accepted names: red orange yellow green cyan blue magenta, or a hue in degrees.

The selection isn't hue-only. A pixel is kept in color only when all three hold: its hue is near the accent, its saturation is above a floor (so dull greys that share the hue are not kept), and its luminance is in a sane mid-range (so near-black shadows and blown highlights are ignored). The resulting mask is then morphologically cleaned (small holes closed, specks removed) and feathered for a soft edge. In practice: a vivid red rose survives, the dull reddish pew behind it does not.

Heads-up — it's color-based, not subject-based. There is no true subject detection in pure ImageMagick. bw-accent isolates a vivid, distinct color very well, but if two objects share that saturated color, both are kept. For real subject isolation you'd need an AI segmentation model (out of scope here).


Options

-m, --mode <mode>        Treatment to apply (see Modes). Default: auto
    --accent <color>     Color to keep in bw-accent: red|orange|yellow|green|
                         cyan|blue|magenta or a hue 0-360. Default: red
    --bw-filter <f>      B&W channel mix for mode 'bw': neutral|portrait|
                         landscape|red|infrared. Default: neutral
-s, --strength <0-2>     Look intensity multiplier. Default: 1.0
-o, --out <dir>          Output directory. Default: <input>/edited
-f, --format <fmt>       Output: jpg|png|tiff|webp. Default: keep (jpg for RAW)
    --lossless           Lossless output (PNG/TIFF). Implies max quality.
    --upscale <2|3|4>    Smart upscale (Real-ESRGAN if installed, else Lanczos)
    --crop <auto|W:H>    Smart crop: 'auto' (content-aware) or ratio e.g. 4:5
    --compress           Visually-lossless squeeze (best quality, least bytes)
    --target-size <S>    Shrink each image to fit a byte budget (e.g. 500KB, 1MB)
    --max-dim <px>       Cap the long edge to <px> (downscale only)
    --strip              Strip ALL metadata for the smallest possible files
    --shadows <0-100>    Lift shadow detail (overrides auto recovery)
    --highlights <0-100> Recover highlight detail (overrides auto recovery)
    --denoise <lvl>      Luminance noise reduction: auto|low|med|high.
                         Default: auto (skips clean shots). --denoise '' = off.
    --no-auto-recovery   Disable AUTO's automatic shadow/highlight recovery
    --lens               Per-lens correction via lensfun CLI (darktable) if present
    --defringe           Reduce lateral chromatic aberration (no dependency)
    --devignette         Lighten optical corner darkening (no dependency)
    --preset-save <file> Save the current look/treatment flags to a file
    --preset-load <file> Apply flags from a file first; later flags override
-r, --recursive          Recurse into subfolders for a folder input
-j, --jobs <N>           Process N images in parallel. Default: 1
    --no-metadata        Do not copy EXIF/IPTC/XMP to outputs
-y, --yes                Auto-confirm dependency installation
-n, --dry-run            Analyze and print the plan; write nothing
-q, --quiet              Less output
-h, --help               Show help

Input handling

You can pass, in any combination:

  • A folder — all supported images inside it (add -r to recurse).
  • One or more files — relative or absolute paths.

Supported extensions: jpg jpeg png tif tiff heic heif webp bmp and common RAW (dng cr2 cr3 nef arw raf orf rw2) when ImageMagick has the delegate. The tool automatically skips its own edited/ output folder and de-duplicates inputs.


How AUTO works

For every image the tool runs a measure → correct → re-measure → correct loop, so each adjustment is sized to what the photo actually needs.

  1. Colour management — if the file carries an embedded ICC profile (Display P3, Adobe RGB, ProPhoto…), it is transformed to sRGB via that profile before any editing, so wide-gamut pixels are read correctly instead of rendering desaturated. The output is then tagged sRGB. (Untagged files are treated as sRGB.) Point the tool at a specific sRGB profile with the AUTOTONE_SRGB_ICC environment variable.
  2. Analyze the original — global channel means, plus a separate set of means over only the near-neutral, well-exposed pixels (the ones that reveal the illuminant), plus the share of crushed-shadow and clipped-highlight pixels.
  3. White balance — two axes — illuminant estimate from those neutral pixels, not a blind gray-world average. A bride's white dress, a red-brick wall or a blue dance floor no longer fools it: the cast is read from the genuinely grey parts of the frame and only those. (When a scene has no neutral pixels, it falls back to global gray-world.) It corrects both temperature (warm↔cool) and tint (green↔magenta) — the second axis matters under fluorescent/LED light. The correction runs in linear light so it's even across the tonal range, eases off smoothly on scenes that are genuinely warm or cool (golden hour, blue hour) to preserve mood, and is skipped entirely on monochrome/grayscale inputs (a B&W scan has no cast to fix).
  4. Exposure — a true linear-light multiply in stops (not a gamma curve), sized to move scene luminance to a print-friendly target, followed by a one-sided highlight shoulder that rolls the top end off like film when brightening — so a lifted exposure keeps highlight separation instead of clipping to paper-white. Clamped to a safe ±~1.6 stops.
  5. Shadow / highlight recovery — gentle, masked recovery in linear light, auto-sized from the histogram (or set explicitly; see below).
  6. Re-analyze the corrected image — measure real contrast and saturation now.
  7. Contrast — a sigmoidal curve sized to the photo's true contrast, applied on the L channel of Lab so it doesn't drag hue or inflate saturation.
  8. Vibrance — reshapes the saturation channel so muted tones lift more than already-vivid ones (protects skin and avoids the garish over-saturation a flat saturation slider produces).
  9. Optional denoise — edge-preserving luminance noise reduction (see below).
  10. Sharpening + color-safe export — output-sharpen sized for the final dimensions (always after any downscale), sRGB output, 300 DPI tag.

Colour correctness. The operations that are only valid in linear light — the WB channel multiply, the exposure gain, all blurs (glow/bokeh), and screen/multiply blends — are wrapped in a linear-RGB conversion. Contrast runs on Lab luminance and saturation as a vibrance curve, so neither shifts hue. On a Q16-HDRI build the pipeline keeps full headroom (no intermediate clamping) and clips only once, at the 8-bit export, so pushed highlights stay recoverable through the whole chain.

The targets live at the top of the script (TARGET_LUM, TARGET_SAT, TARGET_SD) and the safety clamps next to them — see Tuning the defaults.

Shadow/highlight recovery & denoise

./autotone.sh --shadows 40 ./backlit          # lift crushed shadows
./autotone.sh --highlights 50 ./bright_sky     # recover blown highlights
./autotone.sh --denoise auto ./high_iso        # auto-strength noise reduction
./autotone.sh -m auto --no-auto-recovery ./set # turn AUTO's recovery off
  • --shadows / --highlights (0–100) — explicit Lightroom-style recovery. Setting either disables the automatic picker for that run.
  • In AUTO (and the look modes), recovery is applied automatically at a gentle amount derived from how much detail is crushed/clipped — well-exposed frames get essentially nothing. Disable with --no-auto-recovery.
  • --denoise auto|low|med|high — edge-preserving (Kuwahara) noise reduction on the luminance channel only, so colour detail and hue are preserved, with a light micro-contrast restore afterwards. auto is the default: it estimates noise from the image's high-frequency energy and applies a matched level, skipping clean shots entirely — so the zero-config user gets denoising only when it helps. Pass --denoise '' (empty) to turn it off. (In mode=none denoise is off unless you ask for it explicitly, keeping none a true pass-through.)

Lens / optical corrections

./autotone.sh --defringe ./prime_lens          # kill purple/green edge fringes
./autotone.sh --devignette ./wideangle         # lighten dark corners
./autotone.sh --defringe --devignette ./shoot  # both
./autotone.sh --lens ./shoot                   # full per-lens correction (if available)
  • --defringe and --devignette are dependency-free ImageMagick fixes: the first re-registers the R/B channels to reduce lateral chromatic aberration (colour fringes near edges); the second screen-blends an inverse radial mask to lift optical corner darkening while leaving the centre untouched.
  • --lens does a full per-lens correction (geometry, vignette, TCA) from the EXIF lens model if a lensfun-backed CLI (darktable-cli) is installed. If it isn't, the tool says so and continues — use --defringe/--devignette for the dependency-free path.

Presets

Save a look once, reuse it across shoots:

# Dial in a look, save just the treatment flags (not paths/output):
./autotone.sh -m cinema -s 1.2 --shadows 30 --max-dim 1600 \
              --preset-save looks/cinematic.preset sample.jpg

# Apply it to a whole folder later:
./autotone.sh --preset-load looks/cinematic.preset ./client_shoot

# Override a single setting — flags after --preset-load win:
./autotone.sh --preset-load looks/cinematic.preset -m bw ./client_shoot

A preset is a plain text file of flag tokens (one per line, # comments allowed), so you can hand-edit or version-control it. It stores only editorial choices — mode, strength, crop, format, recovery, denoise, optical fixes — never input paths or the output directory.


Compression

Turn heavy 10 MB photos into small web/email files — TinyPNG/TinyJPG-style. The guiding principle, borrowed from those tools: spend bytes where the eye notices and nowhere else (chroma subsampling, perceptual quality, adaptive PNG palettes).

Two modes, and you can combine either with any --mode (compression always runs last, on the finished pixels):

--target-size <S> — fit a byte budget

./autotone.sh -m none --target-size 300KB ./big_photos
./autotone.sh -m none --target-size 1MB   -f webp ./shoot

Accepts 500KB, 1MB, 200K, 1.5M, or raw bytes. The script binary-searches the encoder quality to find the highest quality that still fits the budget. If quality alone can't reach it, it progressively downscales until it does — so the budget is a real guarantee, not a best-effort. Each result reports the saving:

✓ [1/1] photo.jpg   mode=none   7.2 MB → 299 KB (−96%)

--compress — visually-lossless squeeze

./autotone.sh -m none --compress ./gallery

No fixed target — just the best quality for the least bytes (perceptual quality tuning, 4:2:0 chroma subsampling for JPEG/WebP, adaptive palette for PNG). Typically 70–95% smaller with no visible loss. If both flags are given, --target-size wins.

--max-dim and --strip (work with both modes)

./autotone.sh -m none --compress --max-dim 2048 --strip ./gallery
  • --max-dim <px> caps the long edge (downscale only) — the single biggest lever on file size. A 6000 px photo capped to 2048 px is dramatically smaller before the codec even runs.
  • --strip removes all metadata (EXIF/IPTC/XMP/thumbnails) for the smallest files, and skips the metadata-copy step.

Format follows -f/--format as usual (jpg, webp, png, tiff). WebP generally gives the best size-for-quality. PNG is content-aware: graphics and screenshots get lossy palette quantization (MB → KB), while photographic PNGs are kept lossless to avoid banding — for those, use -f jpg/-f webp for real shrinkage. In --compress mode a result that would end up larger than the source keeps the original instead.


Upscaling

./autotone.sh --upscale 4 portrait.jpg
  • If realesrgan-ncnn-vulkan is on your PATH, it is used for true AI super-resolution (best detail). On macOS the script can install it via Homebrew.
  • Otherwise it falls back to high-quality Lanczos resampling with a mild post-sharpen — clearly logged so you always know which path ran.

Upscaling happens on a lossless intermediate, so it never compounds JPEG artifacts.

Cropping

./autotone.sh --crop 4:5  portrait.jpg     # center crop to 4:5 (Instagram portrait)
./autotone.sh --crop 16:9 landscape.jpg    # center crop to 16:9
./autotone.sh --crop 1:1  product.jpg      # square
./autotone.sh --crop auto scan.jpg         # trim near-uniform borders (e.g. scans)

Aspect-ratio crops are center crops that only ever remove pixels — never upscale to fill — so there is no quality loss. auto trims uniform borders (handy for scans and screenshots).


Output & quality

  • Internally 16-bit end to end (with an HDRI ImageMagick) — every stage keeps full precision; 8-bit rounding happens only once, at export.
  • No clipping — values are clamped safely; highlights and shadows are protected.
  • Default output mirrors the source format (RAW/HEIC become high-quality JPEG).
  • --lossless writes TIFF (LZW) by default, or pair with -f png/-f webp for lossless PNG/WebP. JPEG quality otherwise defaults to 96.
  • Metadata (EXIF/IPTC/XMP + ICC profile) is copied with exiftool when present (disable with --no-metadata).
  • 300 DPI print tag is set (this only tags density — it does not resample).

Originals are never modified. Re-running skips files already present in the output folder, so interrupted batches resume cleanly.


Examples

# Zero-config: auto-correct the whole folder (results in ./wedding/edited)
./autotone.sh ./wedding

# Whole wedding folder, recursive, 4 in parallel, into a chosen folder
./autotone.sh -r -j 4 -o ~/Deliverables/wedding ./wedding

# All JPEGs in the current folder (glob file list)
./autotone.sh *.jpg

# Warmer and a touch stronger
./autotone.sh -m warm -s 1.3 ./reception

# Black & white: red filter for dramatic skies; portrait mix for faces
./autotone.sh -m bw --bw-filter red    skyline.jpg
./autotone.sh -m bw --bw-filter portrait headshot.jpg

# Keep the red bouquet, everything else B&W
./autotone.sh -m bw-accent --accent red bouquet.jpg

# Creative looks: classic sepia, cinematic teal-orange grade
./autotone.sh -m sepia old_portrait.jpg
./autotone.sh -m cinema -s 1.2 ./trailer

# Instagram post: auto-correct, crop 4:5, cap to 1080 px
./autotone.sh --crop 4:5 --max-dim 1080 -f jpg ./post

# Max-quality deliverable: AI upscale ×4, 4:5 crop, lossless TIFF
./autotone.sh --upscale 4 --crop 4:5 -f tiff portrait.jpg

# Archival lossless export of your selects
./autotone.sh --lossless -f tiff ./selects

# Upscale-only pass, no tonal edit
./autotone.sh -m none --upscale 2 ./scans

# Compression: shrink a folder of 10 MB photos under 300 KB each
./autotone.sh -m none --target-size 300KB ./big_photos

# Visually-lossless squeeze, cap to 2048 px, strip metadata, WebP out
./autotone.sh -m none --compress --max-dim 2048 --strip -f webp ./gallery

# Edit AND shrink in one pass: auto-correct, then fit 1 MB
./autotone.sh -m auto --target-size 1MB ./shoot

# Backlit shots: lift shadows, recover sky, clean high-ISO noise
./autotone.sh --shadows 45 --highlights 35 --denoise auto ./backlit

# Wide-angle prime: clean chromatic aberration and lift the corners
./autotone.sh --defringe --devignette ./prime_lens

# Save a signature look, then apply it to a whole client shoot
./autotone.sh -m cinema -s 1.2 --shadows 30 --preset-save looks/signature.preset hero.jpg
./autotone.sh --preset-load looks/signature.preset ./client_shoot

# Preview the plan: WB source/axes, exposure in stops, recovery, denoise
./autotone.sh -n ./wedding

Reading the dry-run / log line

-n/--dry-run prints exactly what AUTO decided per image, e.g.:

🔍 IMG_2043.jpg   mode=auto WB(neutral) R×0.982 B×1.041 G×0.971 exp×1.32(+0.40EV) sh+18/hl-0 dn=med -> IMG_2043.jpg
Field Meaning
WB(neutral) WB estimated from neutral pixels (WB(global) = gray-world fallback)
R×… B×… temperature (warm↔cool) channel multipliers
G×… tint (green↔magenta) multiplier — shown only when it actually moves
exp×1.32(+0.40EV) linear exposure multiply and its value in stops
sh+18/hl-0 shadow lift / highlight recovery amounts (0 = none)
dn=med denoise level applied (resolved from auto at run time)

The processed-file log adds short tags — · brightened hl-rolloff recovered — so you can see at a glance that a frame was lifted, rolled off at the top, and had shadow/highlight recovery applied.


Tuning the defaults

Open autotone.sh and edit the block at the top:

TARGET_LUM="0.45"   # target brightness (0.43 darker … 0.48 brighter)
TARGET_SAT="0.45"   # target saturation (lower = more sober)
TARGET_SD="0.22"    # target contrast
WB_STRENGTH="0.80"  # white-balance strength (0=off … 1=full)
WB_MIN/WB_MAX       # clamps on the WB channel multipliers
EXP_MIN="0.33"      # exposure multiply clamps — 0.33×…3.0× ≈ ±1.6 stops
EXP_MAX="3.00"      #   (raise EXP_MAX for more aggressive auto-brightening)
QUALITY="96"        # JPEG quality
SHARPEN="0x0.8+0.6+0.008"   # final sharpen ("" to disable)

The *_MIN / *_MAX clamps keep every automatic adjustment inside safe, photographic limits — exposure is a linear multiply (in stops), so EXP_MIN/EXP_MAX bound how far AUTO will push a very dark or very bright frame.


Testing

There are two suites. The unit tests (test/unit.sh) assert the adaptive math (white balance, exposure, recovery, contrast, vibrance) against known golden values — no images, runs in milliseconds. This is the fast guard against silent numeric regressions in the core that decides every pixel:

./test/unit.sh                   # exact-output checks for the compute_* functions

The physical, eyeball-able suite lives at test/run-tests.sh. It runs the bundled sample (test/original.jpeg) through ~45 transformations and writes a differently-named file per case into test/results/, all starting from the same original — so you can open the folder and see exactly what each mode and option does.

./test/run-tests.sh              # run everything → test/results/
./test/run-tests.sh bw           # only cases whose name matches "bw"
./test/run-tests.sh -k bw        # keep prior results, add the bw cases
IMG=~/myshot.jpg ./test/run-tests.sh   # use your own source image

Each line reports the produced file with its pixel and byte size, so you can confirm the run worked and roughly what it changed; open test/results/ in any viewer to compare side by side. The suite covers the zero-config AUTO path, the adaptive knobs (shadows/highlights/recovery), every creative look, all B&W filters and accents, denoise, crops, formats, compression, and a few combined real-world recipes (social post, web gallery, archival master).


Troubleshooting

  • "ImageMagick is required" — let the script install it (-y) or install it manually (see Installation).
  • RAW files won't open — your ImageMagick build needs the RAW delegate (ufraw/libraw/dcraw). Install it, or convert RAW to TIFF first.
  • HEIC won't open — install the libheif delegate for ImageMagick.
  • Non-HDRI warning — results are fine; you just have a bit less headroom. A Q16-HDRI build is ideal.
  • Parallel logs interleave — expected with -j > 1; use -j 1 for tidy logs.

About

Command line tool for batch image processing + optiona GUI on top of ImageMagick

Resources

Contributing

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages