ImageMagick for Photographers: Batch Image Processing on a Mac

For batch image processing on a Mac — converting formats, resizing, stripping metadata, managing color profiles — ImageMagick covers ground that graphical apps and macOS’s built-in tools can’t reach. Here’s how to install it, which delegates to add for modern formats, and the critical difference between its destructive and non-destructive commands.

ImageMagick for Photographers: Batch Image Processing on a Mac
Text & Photos By David Coleman
Last Revised & Updated:

I MAY get commissions for purchases made through links in this post.

Have Camera Will Travel // Newsletter

Practical field notes, hands-on gear tests.

When you need to process large numbers of image files on a Mac — resizing, converting formats, stripping metadata, forcing color profile conversions — ImageMagick is worth knowing about.

Graphical apps have their place, but for batch operations at scale, a command-line tool that runs quietly and efficiently in the background is hard to beat and much less likely to hang.

A quick bit of history

ImageMagick was originally created in 1987 by John Cristy at DuPont as a way to programmatically handle image format conversion — a problem that was genuinely hard in an era of proprietary formats and constrained hardware. Since then it’s evolved into the invisible engine powering countless other image applications.

A useful mental model: think of it as one half of a command-line tandem. ExifTool handles the metadata layer — everything embedded invisibly in the file — while ImageMagick handles the actual pixels and color rendering.

Why SIPS isn’t always enough

macOS comes with a built-in command-line image tool called sips (Scriptable Image Processing System), and it’s genuinely useful for quick tasks — resizing a folder of JPEGs, converting a PNG to TIFF, basic format changes. If that’s all you need, sips works fine without installing anything.

Where it falls short is format breadth and flexibility. It converts HEIC fine on recent versions of macOS, but it can’t read camera raw formats worth mentioning, has limited ICC profile support, and can’t be extended. ImageMagick fills those gaps — and then some — with a much wider range of supported formats and a delegate system that lets you add support for new file types as you need them.

Installing ImageMagick with Homebrew

ImageMagick doesn’t ship with macOS, so it needs to be installed. Homebrew is the cleanest route — it keeps things easy to update and is consistent with how other command-line image tools like ExifTool are installed.

brew install imagemagick

If you don’t have Homebrew installed yet, the ExifTool installation guide covers the Homebrew setup in detail — the process is identical.

The commands worth knowing first

The basic syntax is consistent throughout: magick [input file] [operators] [output file]. Here are the operations that come up most often in a photography workflow.

Format conversion and quality control

Converting a master TIFF to a web-ready JPEG while controlling compression is one of the most common tasks. The -quality flag sets JPEG compression on a 1 — 100 scale:

Antarctica-Photo by David Coleman

Have Camera Will Travel // Newsletter

Practical field notes, hands-on gear tests, and the fun of exploring the world with a camera in hand.

magick master_edit.tif -quality 85 web_ready.jpg

Resizing with aspect ratio preserved

ImageMagick maintains the aspect ratio by default — it fits the image within the specified dimensions without distorting it. To fit within a 1920×1080 bounding box:

magick input.jpg -resize 1920x1080 output.jpg

To constrain only the width and let the height scale freely, omit the height value: -resize 1920x.

Color space conversion for web

When exporting from Lightroom in a wide-gamut working space like ProPhoto RGB, conversion to sRGB is necessary before putting images on the web — browsers that aren’t color-managed will render the wide-gamut file with blown-out or flat colors otherwise.

magick input.tif -colorspace sRGB output.jpg

Worth noting: for a fully color-managed conversion, specifying the source ICC profile gives ImageMagick the information it needs to do the conversion math correctly. The command above relabels the color space and works well in most cases, but if color accuracy is critical — print output, for instance — a full ICC-based conversion pipeline is the more reliable approach.

Adding support for modern formats

A standard Homebrew installation handles the common formats, but some file types require external libraries — called delegates — to parse and encode correctly. PDF files, for instance, will throw an error until the right delegate is installed.

  • HEIC/HEIF and AVIF (iPhone and modern camera formats): current Homebrew builds of ImageMagick already include this one (via libheif), so HEIC generally works out of the box. If yours doesn’t, brew install libheif adds it.
  • PDF, EPS, and AI (vector/document formats): ImageMagick needs Ghostscript to rasterize vector data. brew install ghostscript
  • RAW files: brew install libraw adds support for most camera RAW formats. ImageMagick’s RAW processing is basic compared to a dedicated converter — most useful for batch extraction or format bridging rather than quality editing.

To check exactly which formats your installation supports, and whether they’re readable, writable, or both:

magick -list format

Look for rw (read/write), r (read only), or w (write only) next to each format name.

Safe copies vs. in-place overwrites

How you invoke ImageMagick determines what happens to your files on disk — and getting it wrong can mean lost originals with no undo.

The magick command — non-destructive

The standard magick command reads the input, processes it in memory, and writes a new output file. The original is untouched. This is the right choice for most single-file or careful batch operations — strip metadata, convert color space, resize, all in one pass:

magick input.tif -strip -colorspace sRGB -resize 1920x output.jpg

The mogrify command — fast but destructive

mogrify processes files in place — it reads the file, applies the operation, and overwrites the original. No backup, no undo. It’s significantly faster than writing new copies when working with thousands of files, but it should only ever be run on files that are already backed up or duplicated.

To batch resize every JPEG in the current folder to a maximum width of 2048px:

magick mogrify -resize '2048x>' *.jpg

The > modifier is a useful safety flag — it tells ImageMagick to only downsize images that are already larger than 2048px, leaving smaller images untouched. The quotation marks around '2048x>' are not optional. Without them, the shell treats > as a redirect — and in the zsh shell macOS uses by default, > *.jpg truncates every JPEG in the folder to zero bytes before ImageMagick even runs. I’ve tested it; it’s as destructive as it sounds. Without the > modifier itself, smaller images get upscaled, which is almost never what you want.

Rule of thumb: use magick when the originals matter, mogrify only on files you’ve already backed up or duplicated.

There’s also a middle path: mogrify with the -path flag writes the processed copies into a separate folder and leaves the originals alone — batch speed without the risk:

mkdir resized
magick mogrify -path resized -resize '2048x>' *.jpg

Command recipes for common photography tasks

Here are recipes for jobs that come up regularly in a photography workflow. Every one has been tested as written — including the quoting, which matters (see above). Commands that write a new output file leave your original untouched; the batch ones write into a separate folder for the same reason.

What you want to doCommand
Convert a HEIC to JPEGmagick photo.heic photo.jpg
Batch-convert a folder of HEICs to JPEGs (originals untouched)mkdir jpgs
magick mogrify -path jpgs -format jpg *.heic
Square thumbnails, filled and center-croppedmagick input.jpg -resize '512x512^' -gravity center -extent 512x512 thumb.jpg
Bake the orientation flag into the pixelsmagick input.jpg -auto-orient output.jpg
Watermark a logo into the bottom-right cornermagick input.jpg logo.png -gravity southeast -geometry +40+40 -composite output.jpg
Add a white bordermagick input.jpg -bordercolor white -border 40 output.jpg
Two images side by sidemagick before.jpg after.jpg +append compare.jpg (use -append to stack vertically)
Contact sheet of a foldermagick montage -font /System/Library/Fonts/Helvetica.ttc *.jpg -thumbnail 300x300 -tile 4x -geometry +5+5 sheet.jpg
Combine images into a single PDFmagick *.jpg photos.pdf
Animated GIF from a series of stillsmagick -delay 60 -loop 0 *.jpg animation.gif

A note on the contact sheet: Homebrew’s ImageMagick ships without a configured font, so montage errors out until you point it at one. The Helvetica path in the recipe exists on every Mac.

Checking two versions of an image for color shifts

This one gets its own section because it answers a question that comes up more often than you’d think: did that app quietly change my colors? Any time the same photo passes through two different pipelines — a raw processor like DxO PureRAW versus Lightroom’s own rendering, an optimizer, a format conversion — ImageMagick can tell you how much changed, where, and in which direction. I used exactly this approach when comparing PureRAW’s output against camera originals for my before-and-after series.

One requirement first: the two files must be the same pixel dimensions. If they aren’t, resize one to match before comparing — the commands below will still emit a number for mismatched sizes, but it’s meaningless.

How much changed, as one number:

magick compare -metric RMSE before.jpg after.jpg null:

The number in parentheses is the one to read: 0 means identical, 1 means completely different. For calibration: simply re-saving a JPEG — no edits at all — scores around 0.001 from recompression alone, while a color shift small enough that you’d have to look twice scores around 0.02. Anything above roughly 0.05 you’ll see immediately.

Where it changed, as a picture:

magick compare before.jpg after.jpg diff.png

That writes an image where unchanged areas are faded out and changed pixels are highlighted in red. Uniform red everywhere means a global shift (color, exposure); red concentrated in one area means a local change.

Which direction it moved: compare the average red, green, and blue values of each file:

magick before.jpg -format "R %[fx:round(mean.r*255)]  G %[fx:round(mean.g*255)]  B %[fx:round(mean.b*255)]" info:

Run it on both files and read the two lines together. If the after file’s red average is higher and blue is lower, the image warmed up — that’s the whole diagnosis. It won’t catch shifts that cancel out across the frame, but for the common case — a pipeline nudging everything in one direction — it names the culprit in plain numbers.

Sizing images for social media

These produce upload-ready files: sized for the platform, converted to sRGB, metadata stripped, and saved at a quality level that survives the platform’s own recompression. Two patterns to know: platforms with a fixed frame (Instagram, Pinterest) get a fill-and-crop; platforms that accept any shape (Facebook, X) get a fit-to-long-edge that never crops. Sizes are current as I write this — platforms do change them; my Instagram size guide tracks that platform in more detail.

Platform & formatCommand
Instagram portrait (3:4, 1080×1440)magick input.jpg -auto-orient -resize '1080x1440^' -gravity center -extent 1080x1440 -colorspace sRGB -strip -quality 90 ig-portrait.jpg
Instagram square (1080×1080)magick input.jpg -auto-orient -resize '1080x1080^' -gravity center -extent 1080x1080 -colorspace sRGB -strip -quality 90 ig-square.jpg
Stories / Reels (9:16, 1080×1920)magick input.jpg -auto-orient -resize '1080x1920^' -gravity center -extent 1080x1920 -colorspace sRGB -strip -quality 90 story.jpg
Facebook (2048px long edge, no crop)magick input.jpg -auto-orient -resize '2048x2048>' -colorspace sRGB -strip -quality 85 fb.jpg
X / Twitter (1600px long edge, no crop)magick input.jpg -auto-orient -resize '1600x1600>' -colorspace sRGB -strip -quality 85 x.jpg
Pinterest (2:3, 1000×1500)magick input.jpg -auto-orient -resize '1000x1500^' -gravity center -extent 1000x1500 -colorspace sRGB -strip -quality 90 pin.jpg

The pieces are the same every time: -auto-orient bakes the rotation in before the platform can lose it, -strip drops the metadata (including GPS), and the fill-and-crop pattern crops from the center — if your subject is off-center, crop deliberately in an editor instead. One Instagram-specific note: since the 2025 grid change, profiles preview everything at 3:4 — the older 4:5 portrait size still uploads fine but gets trimmed top and bottom in the grid, which is why 3:4 is now the recommended shape.

Keeping ImageMagick updated

ImageMagick is actively developed, with updates adding support for new formats, fixing bugs, and occasionally changing command behavior. With Homebrew, staying current is straightforward:

brew upgrade imagemagick

Or to update all your Homebrew-installed tools at once:

brew upgrade

This last one is my preferred route. If you’ve installed delegates like libheif, ghostscript, or libraw, those update through the same command — Homebrew handles the whole stack. It’s worth running brew upgrade periodically, particularly after a new macOS release, since system library changes can occasionally break delegate compatibility.

Found this helpful? Personalize your search results.
Add as Preferred Source