Post
Merlin: Smart Watermarks + Web-Ready Photos from the CLI ๐งโโ๏ธโจ
TL;DR ๐ฏ
If you want a dead-simple, CLI-first way to turn a folder of photos into web-ready JPGs with a watermark that doesnโt disappear into bright skies, Merlinโs your wizard ๐งโโ๏ธ๐ฎ
I built a little Bash tool called Merlin ๐งโโ๏ธ that turns a folder of โraw-ishโ photos into web-ready images: resized, converted to JPG, and watermarked with the right logo color (black or white) based on the brightness behind it. Minimal effort. Maximum โจ.
๐ GitHub repo: https://github.com/corbtastik/merlin
Before / After ๐ผ๏ธ
Same shot โ one without the watermark, one with it:

What Merlin does (a.k.a. โthe spell listโ) ๐ช
Merlin is a Bash script that uses ImageMagick to batch process images in a directory:
- Batch processing: handles
jpg,png, andheicfiles ๐ธ
(HEIC = High Efficiency Image Container) - Web optimization: converts everything to JPG (quality 85) โ
- Resize modes:
fit(default): resize to a target width while keeping aspect ratiocover: center-crop + resize to a 4:5-ish frame (social-friendly) ๐ฑ
(See: Aspect ratio)
- Smart watermarking: samples the bottom-right corner and automatically picks:
- Light background โ black logo
- Dark background โ white logo
- Non-destructive: creates new files like
IMG_1234-merlin.jpg(originals stay untouched) ๐งผโจ
Prerequisites โ
You need ImageMagick v7+ installed (specifically the magick command).
macOS (Homebrew) ๐บ
brew install imagemagick
Ubuntu / Debian ๐ง
sudo apt-get install imagemagick
Quick sanity check:
magick -version
If that prints a version and doesnโt complain, youโre in business ๐
Install ๐งฐ
- Download
merlin.shinto your project folder. - Make it executable:
chmod +x merlin.sh
- Optional: move it into your PATH so you can run it anywhere:
mv merlin.sh /usr/local/bin/merlin
Usage ๐
Basic (default width + fit)
This is the simplest way to run Merlin. It uses the default width (1600px) and fit.
./merlin.sh \
--input ./photos \
--logo-white ./assets/logo-white.png \
--logo-black ./assets/logo-black.png
Advanced (custom output, width, and cover)
Specify an output directory, a custom width, and use cover crop.
./merlin.sh \
--input ./raw-photos \
--output ./web-ready \
--width 1080 \
--style cover \
--logo-white ./assets/logo-white.png \
--logo-black ./assets/logo-black.png
Flags ๐
| Flag | Description | Required? | Default |
|---|---|---|---|
-i, --input |
Directory containing source images | โ | โ |
--logo-white |
Path to white watermark logo | โ | โ |
--logo-black |
Path to black watermark logo | โ | โ |
-o, --output |
Output directory | โ | same as input |
-w, --width |
Target width in pixels | โ | 1600 |
--style |
fit or cover |
โ | fit |
--suffix |
String appended to filenames | โ | merlin |
How it works (the โrealโ magic) ๐ง โจ
1) Auto-orient first ๐
Phones love storing rotation in metadata (thanks, Exif ๐
). Merlin uses -auto-orient so โbottom-rightโ is actually bottom-right.
2) Resize mode ๐
- fit: resize to width, preserve aspect ratio
- cover: crop + resize to fill a 4:5-ish output (great for social posts) ๐ฑ
3) Brightness sampling โ๏ธ๐
Merlin crops a small region (20% width ร 15% height) in the bottom-right, converts it to grayscale, and computes mean brightness. If brightness is > 0.4, it assumes the background is light โ black logo.
4) Composite watermark ๐จ
Merlin overlays the selected logo in the bottom-right with a little padding.
Important: Merlin does not resize your logo. It uses the logo at its native pixel size.
Make your logo files the size you want them to appear on the final image (ex:100x45px).
Output naming ๐ท๏ธ
Merlin avoids overwriting originals by appending a suffix:
- Source:
IMG_1234.HEIC - Output:
IMG_1234-merlin.jpg