cheat sheet

ImageMagick

Comprehensive ImageMagick 7 reference covering magick, identify, mogrify, composite, montage, format conversion, resize, crop, rotate, color adjustments, effects, drawing, text, PDF operations, policy.xml hardening, and batch processing.

ImageMagick — Image Manipulation

What it is

ImageMagick is a free, open-source suite of command-line tools — maintained at imagemagick.org — for creating, editing, compositing, and converting raster and vector images across 200+ formats including JPEG, PNG, TIFF, WebP, HEIC, SVG, and PDF. It handles tasks ranging from a simple format conversion to complex multi-layer compositing and batch transformations that would otherwise require a GUI editor. Reach for ImageMagick when you need scriptable, server-side, or batch image processing; for interactive editing, a GUI tool like GIMP is more practical.

IM 6 vs IM 7: ImageMagick 7 uses a single magick binary as the unified entry point. IM 6 ships separate commands (convert, identify, mogrify, …). On IM 7 the legacy names are deprecated shims and are omitted in some 7.x packaging configs (Fedora/RHEL ImageMagick7, Alpine, several Docker images) — scripts that hard-code convert will fail with "command not found" on those systems. Always prefer magick <subcommand> for new work. The current series at the time of writing is 7.1.2-23 (May 2026); 7.2 has not been released. This guide uses IM 7 syntax with IM 6 equivalents noted.

Installation

bash
# macOS
brew install imagemagick

# Ubuntu / Debian
sudo apt install imagemagick

# Arch
sudo pacman -S imagemagick

# Fedora
sudo dnf install ImageMagick

# Verify
magick --version                   # IM 7
convert --version                  # IM 6

# Policy file (Ubuntu/Debian) — may need to allow PDF processing:
# Edit /etc/ImageMagick-6/policy.xml or /etc/ImageMagick-7/policy.xml
# Change <policy domain="coder" rights="none" pattern="PDF" />
# to     <policy domain="coder" rights="read|write" pattern="PDF" />

Output:

text
# magick --version
Version: ImageMagick 7.1.1-15 Q16-HDRI x86_64 21910 https://imagemagick.org
Copyright: (C) 1999 ImageMagick Studio LLC
License: https://imagemagick.org/script/license.php
Features: Cipher DPC HDRI OpenMP(4.5)
Delegates (built-in): bzlib fontconfig freetype heic jng jp2 jpeg lcms lqr lzma openexr png tiff webp xml zlib

# convert --version
Version: ImageMagick 6.9.12-98 Q16 x86_64 18115 https://legacy.imagemagick.org
Copyright: (C) 1999 ImageMagick Studio LLC

Configuration

ImageMagick reads its XML configuration files at startup from a system-wide directory and an optional per-user override. The system path is /etc/ImageMagick-7/ (or /etc/ImageMagick-6/ on IM 6); the per-user override is ~/.config/ImageMagick/. Files in the user directory take precedence over the system ones with the same name, which lets you loosen or tighten settings without sudo.

bash
# Locate the config files actually being used
magick -list configure | grep -E '^(CONFIGURE_PATH|SHARE_PATH)'
magick -debug Configure -list policy 2>&1 | grep Searching | head -10

# System-wide config directory (Linux/macOS Homebrew varies)
ls /etc/ImageMagick-7/
# colors.xml      english.xml      log.xml          policy.xml       type.xml
# delegates.xml   locale.xml       mime.xml         thresholds.xml   type-ghostscript.xml

# Per-user override (highest precedence) — create as needed
mkdir -p ~/.config/ImageMagick
cp /etc/ImageMagick-7/policy.xml ~/.config/ImageMagick/policy.xml

# Verify which policy file is loaded
magick -list policy | head -20

Output:

text
# magick -list policy | head -20
Path: /etc/ImageMagick-7/policy.xml
  Policy: Resource
    name: memory
    value: 256MiB
  Policy: Resource
    name: disk
    value: 1GiB
  Policy: Coder
    rights: None
    pattern: PDF
  Policy: Coder
    rights: None
    pattern: PS
FilePurpose
policy.xmlSecurity policy — coder/resource/path/module limits (most-edited file)
delegates.xmlExternal commands used to read/write formats (Ghostscript, librsvg, …)
colors.xmlNamed color aliases
type.xml / type-ghostscript.xmlFont search paths and aliases
thresholds.xmlDither and posterise threshold maps
log.xmlLog event filters and output format
mime.xmlMIME-type → format mapping
locale.xml, english.xmlMessage catalogues

policy.xml — security hardening

policy.xml is the gatekeeper between user input and ImageMagick's coder/delegate machinery. Each <policy> element scopes a rule to a domain (coder, delegate, module, filter, path, resource, cache) and either grants rights (read, write, read|write, none) or sets a value for a resource limit. The last matching rule wins, so put broad denies first and exceptions afterwards.

Starting with 7.1.1-16, the upstream tarball ships four pre-built templates you can select at build time with --with-security-policy={open,limited,secure,websafe}, or copy from config/ directly:

TemplateIntent
open (default)Permissive — assumes ImageMagick runs behind a firewall or in a container
limitedDisables high-risk coders (PS, PDF, MVG, MSL) and HTTP, keeps common formats
secureTight resource limits + most coders disabled; flip on only what you need
websafeRead/write restricted to GIF, JPEG, PNG, WebP; no filters or indirect reads
xml
<!-- /etc/ImageMagick-7/policy.xml — hardened example for a web-facing service -->
<policymap>
  <!-- Resource ceilings: starve a malicious upload of memory/CPU -->
  <policy domain="resource" name="memory"   value="256MiB"/>
  <policy domain="resource" name="map"      value="512MiB"/>
  <policy domain="resource" name="width"    value="16KP"/>
  <policy domain="resource" name="height"   value="16KP"/>
  <policy domain="resource" name="area"     value="128MP"/>
  <policy domain="resource" name="disk"     value="1GiB"/>
  <policy domain="resource" name="time"     value="60"/>      <!-- seconds -->
  <policy domain="resource" name="thread"   value="2"/>
  <policy domain="resource" name="throttle" value="0"/>

  <!-- Coders: block scriptable / delegate-heavy formats -->
  <policy domain="coder" rights="none" pattern="PS"/>
  <policy domain="coder" rights="none" pattern="PS2"/>
  <policy domain="coder" rights="none" pattern="PS3"/>
  <policy domain="coder" rights="none" pattern="EPS"/>
  <policy domain="coder" rights="none" pattern="PDF"/>
  <policy domain="coder" rights="none" pattern="XPS"/>
  <policy domain="coder" rights="none" pattern="MSL"/>
  <policy domain="coder" rights="none" pattern="MVG"/>
  <policy domain="coder" rights="none" pattern="SVG"/>
  <policy domain="coder" rights="none" pattern="LABEL"/>

  <!-- Delegates: block shell-level external commands -->
  <policy domain="delegate" rights="none" pattern="HTTPS"/>
  <policy domain="delegate" rights="none" pattern="HTTP"/>
  <policy domain="delegate" rights="none" pattern="URL"/>
  <policy domain="delegate" rights="none" pattern="SHOW"/>
  <policy domain="delegate" rights="none" pattern="WIN"/>

  <!-- Paths: block stdin/stdout/fd pseudo-files and @-prefixed indirect reads -->
  <policy domain="path"   rights="none" pattern="@*"/>
  <policy domain="path"   rights="none" pattern="|*"/>
  <policy domain="path"   rights="none" pattern="-"/>
  <policy domain="path"   rights="none" pattern="fd:*"/>     <!-- IM 7.1.2 advisory, Feb 2026 -->

  <!-- Module: forbid loading user-provided coder modules -->
  <policy domain="module" rights="none" pattern="{PS,PDF,XPS}"/>
</policymap>

Feb 2026 advisory (GHSA-xwc6-v6g8-pw2h): The shipped secure template did not block fd: pseudo-filenames (e.g. fd:0, fd:1), letting an attacker read from stdin or write to stdout through coder paths. Add <policy domain="path" rights="none" pattern="fd:*"/> even if you start from policy-secure.xml.

bash
# Re-enable PDF only (e.g. to rasterise trusted internal documents)
# Edit /etc/ImageMagick-7/policy.xml, change the PDF coder line to:
# <policy domain="coder" rights="read|write" pattern="PDF" />

# Confirm a coder is blocked
magick -list policy | grep -A1 PDF
# Coder
#   rights: None
#   pattern: PDF

# Validate the live policy against an external evaluator (Doyensec)
# Upload your policy.xml to https://imagemagick-secevaluator.doyensec.com/
# or run the open-source evaluator locally:
#   git clone https://github.com/doyensec/imagemagick-security-policy-evaluator
#   python3 imagemagick-security-policy-evaluator/evaluator.py /etc/ImageMagick-7/policy.xml

Output: (none — exits 0 on success)

delegates.xml — external commands

delegates.xml defines the shell command lines ImageMagick uses to hand off formats it cannot decode natively — Ghostscript for PostScript/PDF, librsvg or Inkscape for SVG, dcraw for camera RAW, and so on. Override an entry (for example to swap rsvg-convert for inkscape) by copying the relevant <delegate> block into ~/.config/ImageMagick/delegates.xml and editing the command= attribute.

bash
# List active delegates
magick -list delegate | head -20

# Find which external binary handles PDF
magick -list delegate | grep -A1 -i pdf

Output: (none — exits 0 on success)

Core commands (IM 7)

IM 7IM 6 equivalentPurpose
magick input … outputconvertConvert / process images
magick identifyidentifyRead image metadata
magick mogrifymogrifyIn-place batch processing
magick compositecompositeOverlay images
magick montagemontageCreate contact sheets
magick comparecompareVisual diff between images
magick streamstreamStream raw pixels
magick importimportScreen capture (X11)

Identify — inspect images

magick identify reads an image's metadata — format, dimensions, color depth, colorspace, and profile information — without fully decoding pixel data. Use it to audit a batch of images or extract specific properties via format strings for scripting.

bash
magick identify image.png              # format, size, depth
magick identify -verbose image.png     # full metadata dump
magick identify -ping image.png        # fast: dimensions only, no decode

# Specific properties
magick identify -format "%f: %wx%h %[colorspace]\n" *.jpg
magick identify -format "%i %m %wx%h %[fx:w*h]\n" *.png

# Multi-frame (GIF, TIFF, PDF)
magick identify animation.gif          # shows each frame
magick identify 'document.pdf[0]'      # first page only

# Useful format codes:
# %f filename   %m format    %w width    %h height
# %z depth      %r type      %b filesize  %n number of frames
# %[colorspace] colorspace   %[profile:icc] ICC profile
# %[fx:expr]    evaluated expression

# Check if image has transparency
magick identify -format "%[channels]\n" image.png

Output:

text
# magick identify image.png
image.png PNG 1920x1080 1920x1080+0+0 8-bit sRGB 2.34MB 0.000u 0:00.001

# magick identify -verbose image.png
Image: image.png
  Format: PNG (Portable Network Graphics)
  Mime type: image/png
  Class: DirectClass
  Geometry: 1920x1080+0+0
  Resolution: 72x72
  Print size: 26.6667x15
  Units: PixelsPerInch
  Colorspace: sRGB
  Type: TrueColor
  Depth: 8-bit
  Channel depth:
    Red: 8-bit
    Green: 8-bit
    Blue: 8-bit
  Filesize: 2.34MB
  Number pixels: 2073600
  …

# magick identify -format "%f: %wx%h %[colorspace]\n" *.jpg
photo1.jpg: 4032x3024 sRGB
photo2.jpg: 3840x2160 sRGB
photo3.jpg: 1920x1080 sRGB

# magick identify -ping image.png
image.png PNG 1920x1080 1920x1080+0+0 8-bit sRGB 0.000u 0:00.000

# magick identify -format "%[channels]\n" image.png
rgba

Format conversion

ImageMagick auto-detects the input format from the file header and writes the output format based on the output file's extension, so a simple magick input.png output.jpg is all that's needed for most conversions. For multi-page sources like PDFs and GIFs, each page or frame becomes a separate numbered output file unless you select specific pages with bracket notation.

bash
# Basic: input format auto-detected from extension
magick input.png output.jpg
magick input.jpg output.png
magick input.png output.webp
magick input.tiff output.png
magick input.heic output.jpg         # HEIC → JPEG (macOS)
magick input.svg output.png          # SVG → PNG (needs librsvg or inkscape)

# Multi-page / animation
magick input.pdf output.png          # all pages → output-0.png, output-1.png …
magick 'input.pdf[0]' output.png     # first page only
magick 'input.pdf[0-2]' out.png      # pages 0, 1, 2
magick *.jpg animation.gif           # images → animated GIF
magick frame*.png -delay 10 animation.gif  # with frame delay (10/100s)

# Force format (regardless of extension)
magick -format PNG input.dat output.out

# Specify quality
magick input.png -quality 85 output.jpg     # JPEG/WebP quality (0-100)
magick input.png -quality 9  output.png     # PNG compression (0-9)

# Strip metadata (EXIF, profiles) — smaller file size
magick input.jpg -strip output.jpg

Output: (none — exits 0 on success)

Geometry syntax

Many options accept a geometry string WxH+X+Y:

SyntaxMeaning
800x600Fit within 800×600, preserve aspect ratio
800x600!Exact 800×600, ignore aspect ratio
800x600>Only shrink if larger than 800×600
800x600<Only enlarge if smaller than 800×600
800x600^Fill 800×600, may crop
50%Scale to 50% of original
800xWidth 800, height proportional
x600Height 600, width proportional
+50+30Offset: 50px from left, 30px from top
800x600+10+20Resize and position

Resize & scale

-resize resamples the image to a new size using a configurable filter (Lanczos by default), preserving the aspect ratio unless you append !. -thumbnail is faster for generating small previews because it skips some processing steps, while -scale and -sample do nearest-neighbor scaling with no filtering, which is ideal for pixel art or when speed matters more than quality.

bash
# Fit within bounding box (preserves aspect ratio)
magick input.jpg -resize 800x600 output.jpg

# Exact size (distorts if aspect ratio differs)
magick input.jpg -resize 800x600! output.jpg

# Width only, height proportional
magick input.jpg -resize 800x output.jpg

# Height only, width proportional
magick input.jpg -resize x600 output.jpg

# Only shrink (never enlarge)
magick input.jpg -resize '1920x1080>' output.jpg

# Only enlarge (never shrink)
magick input.jpg -resize '800x600<' output.jpg

# Fill and crop to exact size
magick input.jpg -resize 800x600^ -gravity center -extent 800x600 output.jpg

# Scale (fast, no filtering — pixel art / thumbnails)
magick input.png -scale 200% output.png
magick input.png -scale 128x128 icon.png

# Sample (nearest-neighbor, fastest)
magick input.png -sample 50% output.png

# High-quality resize filters
magick input.jpg -filter Lanczos -resize 800x output.jpg
magick input.jpg -filter Mitchell -resize 800x output.jpg

# Percentage
magick input.jpg -resize 50% output.jpg
magick input.jpg -resize 150% output.jpg

# Pixel count limit
magick input.jpg -resize '2000000@' output.jpg  # max 2 megapixels

Output: (none — exits 0 on success)

Crop

-crop WxH+X+Y extracts a rectangular region of width W and height H starting at pixel offset (X, Y) from the top-left corner. Combine with -gravity to anchor the crop to a named position (Center, SouthEast, etc.) instead of calculating absolute offsets, and always follow with +repage if you're piping the result into further operations so the canvas offset is reset.

bash
# Crop to WxH from offset X,Y
magick input.jpg -crop 400x300+50+100 output.jpg

# Crop centered (gravity + extent)
magick input.jpg -gravity center -crop 400x300+0+0 output.jpg

# Crop from corners
magick input.jpg -gravity NorthWest -crop 400x300+0+0 output.jpg  # top-left
magick input.jpg -gravity SouthEast -crop 400x300+0+0 output.jpg  # bottom-right
magick input.jpg -gravity North     -crop 400x0+0+0   output.jpg  # top strip

# Trim whitespace / border
magick input.png -trim output.png              # auto-trim edges
magick input.png -fuzz 10% -trim output.png   # with fuzz tolerance
magick input.png -trim +repage output.png     # trim + reset canvas

# Tile / split into tiles
magick input.jpg -crop 200x200 tiles_%d.jpg   # tiles at 200x200 grid

# Shave (remove N pixels from all edges)
magick input.jpg -shave 10x10 output.jpg      # remove 10px all sides

Output: (none — exits 0 on success)

Rotate & flip

-rotate turns the image by an arbitrary angle, expanding the canvas to fit the rotated content and filling corners with the background color. -flip mirrors vertically (top-to-bottom) while -flop mirrors horizontally (left-to-right); -auto-orient reads the EXIF orientation tag and applies the correct rotation, which is the right first step when processing camera photos.

bash
magick input.jpg -rotate 90  output.jpg       # 90° clockwise
magick input.jpg -rotate -90 output.jpg       # 90° counter-clockwise
magick input.jpg -rotate 180 output.jpg       # 180°
magick input.jpg -rotate 45  output.jpg       # 45° (canvas expands, corners filled)
magick input.jpg -rotate 45 -background black -flatten output.jpg  # black corners

magick input.jpg -flip   output.jpg           # flip vertically (top↔bottom)
magick input.jpg -flop   output.jpg           # flip horizontally (left↔right)
magick input.jpg -transpose  output.jpg       # transpose (flip along main diagonal)
magick input.jpg -transverse output.jpg       # transverse flip

# Auto-rotate from EXIF orientation
magick input.jpg -auto-orient output.jpg

Output: (none — exits 0 on success)

Color adjustments

These options alter pixel values after the image is decoded, letting you correct exposure, shift white balance, or convert colorspace without touching the source file. -brightness-contrast is the simplest lever; -modulate gives independent control over lightness, saturation, and hue; -level and -normalize stretch or compress the tonal range.

bash
# Brightness / contrast (-100 to +100)
magick input.jpg -brightness-contrast 10x20 output.jpg   # +10 brightness, +20 contrast

# Levels (black-point, gamma, white-point)
magick input.jpg -level 10%,90% output.jpg               # stretch levels
magick input.jpg -level 0%,100%,1.5 output.jpg           # gamma 1.5

# Normalize (auto-stretch levels to full range)
magick input.jpg -normalize output.jpg
magick input.jpg -auto-level output.jpg                   # per-channel normalize

# Gamma
magick input.jpg -gamma 1.5 output.jpg        # lighten
magick input.jpg -gamma 0.7 output.jpg        # darken

# Hue / saturation / lightness
magick input.jpg -modulate 100,150,100 output.jpg   # brightness,saturation,hue
# 100=no change, 150=50% more saturation
magick input.jpg -modulate 110,80,100 output.jpg    # slightly brighter, less saturated

# Colorize
magick input.jpg -colorize 10,0,0 output.jpg        # tint red
magick input.jpg -tint 80 output.jpg                # tint with fill color

# Grayscale
magick input.jpg -colorspace Gray output.jpg
magick input.jpg -colorspace Gray -type Grayscale output.jpg  # force gray type

# Sepia
magick input.jpg -sepia-tone 80% output.jpg

# Invert
magick input.jpg -negate output.jpg

# White balance / color correction
magick input.jpg -white-balance output.jpg

# Curves (via fx)
magick input.jpg -function Polynomial "0.5,0,0.5" output.jpg

Output: (none — exits 0 on success)

Filters & effects

ImageMagick's filter and effect options modify pixel neighborhoods rather than individual pixel values, producing blur, sharpening, noise, and artistic transformations. -blur 0xS and -gaussian-blur 0xS are controlled by their sigma value; -unsharp is the standard choice for sharpening because it avoids the halos that -sharpen can introduce at high strengths.

bash
# Blur
magick input.jpg -blur 0x3 output.jpg           # Gaussian, sigma=3
magick input.jpg -blur 0x8 output.jpg           # stronger blur
magick input.jpg -gaussian-blur 0x5 output.jpg  # explicit Gaussian
magick input.jpg -radial-blur 20 output.jpg     # radial motion blur
magick input.jpg -motion-blur 0x10+45 output.jpg  # motion blur at 45°

# Sharpen
magick input.jpg -sharpen 0x1.5 output.jpg      # moderate sharpen
magick input.jpg -unsharp 0x1+1+0.05 output.jpg # unsharp mask (best quality)
# -unsharp radius x sigma + amount + threshold

# Noise
magick input.jpg +noise Gaussian output.jpg     # add Gaussian noise
magick input.jpg +noise Impulse output.jpg      # add salt-and-pepper noise
magick input.jpg -noise 3 output.jpg            # reduce noise (median filter)

# Edge detection
magick input.jpg -edge 1 output.jpg
magick input.jpg -emboss 0x1 output.jpg         # emboss effect
magick input.jpg -charcoal 1 output.jpg         # charcoal sketch

# Artistic
magick input.jpg -paint 3 output.jpg            # oil painting effect
magick input.jpg -sketch 0x20+120 output.jpg    # pencil sketch
magick input.jpg -swirl 90 output.jpg           # swirl distortion
magick input.jpg -wave 10x100 output.jpg        # wave distortion
magick input.jpg -implode 0.5 output.jpg        # implode
magick input.jpg -implode -1 output.jpg         # explode

# Vignette
magick input.jpg -vignette 0x20+5+5 output.jpg

# Pixelate (mosaic)
magick input.jpg -scale 5% -scale 2000% output.jpg  # pixelate trick

# Posterize
magick input.jpg -posterize 4 output.jpg        # reduce color levels

# Solarize
magick input.jpg -solarize 50% output.jpg

# Spread (random pixel displacement)
magick input.jpg -spread 5 output.jpg

Output: (none — exits 0 on success)

Drawing & shapes

The -draw option accepts an MVG (Magick Vector Graphics) mini-language for placing geometric primitives — circles, rectangles, lines, polygons, and ellipses — directly onto an image or a freshly created canvas. Set -fill and -stroke before -draw to control interior and outline colors; use -strokewidth to adjust line thickness.

bash
# Draw on existing image (no canvas needed)
magick input.jpg -fill red -draw "circle 100,100 100,150" output.jpg

# Rectangle
magick input.jpg -fill blue -draw "rectangle 10,10 200,100" output.jpg

# Line
magick input.jpg -stroke red -strokewidth 3 -draw "line 0,0 200,200" output.jpg

# Polygon
magick input.jpg -fill yellow -draw "polygon 100,10 150,80 50,80" output.jpg

# Ellipse (cx,cy rx,ry start_angle,end_angle)
magick input.jpg -fill none -stroke green -strokewidth 2 \
  -draw "ellipse 200,200 100,60 0,360" output.jpg

# Create a new canvas with shapes
magick -size 400x400 xc:white \
  -fill red   -draw "circle 200,200 200,300" \
  -fill blue  -draw "rectangle 50,50 150,150" \
  output.png

# Rounded rectangle
magick -size 300x200 xc:white \
  -fill skyblue -draw "roundrectangle 20,20 280,180 20,20" \
  output.png

Output: (none — exits 0 on success)

Text annotations

-annotate renders text onto an image using the current font, point size, fill, and gravity settings; it's the higher-level alternative to -draw "text …" because it supports rotation, gravity alignment, and offset placement in a single option. For watermarking or captioning, pair -gravity with -annotate to position text relative to an edge rather than computing absolute pixel coordinates.

bash
# Add text to image
magick input.jpg -font Arial -pointsize 40 -fill white \
  -draw "text 20,50 'Hello World'" output.jpg

# With gravity
magick input.jpg -gravity South -font Arial -pointsize 36 \
  -fill white -annotate +0+20 "Caption" output.jpg

# With background box
magick input.jpg -gravity South \
  -background '#0008' -fill white -font Arial -pointsize 28 \
  -annotate +0+10 " My Caption " output.jpg

# Stroke (outline text)
magick input.jpg -gravity Center -font Arial -pointsize 60 \
  -stroke black -strokewidth 2 -fill white \
  -annotate 0 "WATERMARK" output.jpg

# Transparent watermark (no input image, just create)
magick -size 800x600 xc:white \
  -font Helvetica -pointsize 72 \
  -fill "rgba(128,128,128,0.5)" \
  -gravity center -annotate 30 "DRAFT" \
  watermark.png

# List available fonts
magick -list font | grep -i "Font:"

Output:

text
# magick -list font | grep -i "Font:"
  Font: Arial
  Font: Arial-Black
  Font: Arial-Bold
  Font: Arial-BoldItalic
  Font: Arial-Italic
  Font: Courier
  Font: Courier-Bold
  Font: Helvetica
  Font: Times-Roman
  …

Composite — overlay images

magick composite (or -composite in a pipeline) layers one image on top of another using a compositing operator such as Over, Multiply, Screen, or Dissolve. -gravity and -geometry control where the overlay lands; the compose mode determines how overlapping pixels are blended, from simple alpha-over to photoshop-style blend modes.

bash
# Overlay logo on image
magick composite -gravity SouthEast logo.png input.jpg output.jpg

# With offset
magick composite -geometry +10+10 overlay.png background.jpg output.jpg

# With compose modes
magick composite -compose Multiply  overlay.png base.jpg output.jpg
magick composite -compose Screen    overlay.png base.jpg output.jpg
magick composite -compose Overlay   overlay.png base.jpg output.jpg
magick composite -compose Dissolve -dissolve 50 fg.png bg.jpg output.jpg

# Mask compositing
magick composite -compose CopyOpacity mask.png input.png output.png

# IM 7 equivalent
magick base.jpg overlay.png -gravity SouthEast -composite output.jpg
magick bg.jpg fg.png -geometry +10+10 -compose Screen -composite out.jpg

Output: (none — exits 0 on success)

Montage — contact sheets

magick montage arranges multiple images into a grid (contact sheet), with each thumbnail scaled to fit the geometry you specify. -tile controls the column×row layout, -geometry sets the thumbnail size and inter-image spacing, and -label adds a filename or custom caption beneath each thumbnail.

bash
# Simple grid from multiple images
magick montage *.jpg output.jpg

# Control tile layout
magick montage *.jpg -tile 4x3 -geometry 200x150+5+5 contact.jpg
# 4 columns, 3 rows, each thumb 200x150, 5px gap

# With labels
magick montage *.jpg -tile 4x -geometry 200x150+5+5 -label '%f' contact.jpg

# Custom background, font
magick montage *.jpg -tile 3x -geometry 300x200+10+10 \
  -background black -fill white -font Arial -pointsize 12 \
  -label '%t' contact.jpg

# Single strip
magick montage img1.jpg img2.jpg img3.jpg -tile x1 -geometry 200x150+2+0 strip.jpg

Output: (none — exits 0 on success)

Compare — visual diff

magick compare produces a highlighted difference image showing where two images diverge, and can compute numeric quality metrics such as PSNR (signal-to-noise ratio), SSIM (structural similarity), AE (absolute error pixel count), and MSE. Use it to verify that a compression or resizing step has not introduced unacceptable quality loss.

bash
magick compare image1.jpg image2.jpg diff.jpg     # highlight differences
magick compare -metric PSNR image1.jpg image2.jpg null:  # PSNR score
magick compare -metric SSIM image1.jpg image2.jpg null:  # SSIM score
magick compare -metric AE image1.jpg image2.jpg null:    # absolute error count
magick compare -metric MSE image1.jpg image2.jpg diff.png  # mean square error

Output:

text
# magick compare -metric PSNR image1.jpg image2.jpg null:
32.4156

# magick compare -metric SSIM image1.jpg image2.jpg null:
0.971842

# magick compare -metric AE image1.jpg image2.jpg null:
14823

Canvas & gradients

xc:color creates a blank canvas filled with a single color, while gradient: and radial-gradient: generate smooth linear and radial color transitions between two colors. These pseudo-image sources are used as starting points for compositing, testing, or building backgrounds without needing a pre-existing image file.

bash
# Solid color canvas
magick -size 800x600 xc:white output.png
magick -size 800x600 xc:#1a1a2e output.png
magick -size 800x600 xc:"rgba(0,0,0,0)" transparent.png  # transparent

# Gradients
magick -size 800x400 gradient:blue-red output.png         # horizontal blue→red
magick -size 800x400 gradient:"#ff0000-#0000ff" out.png
magick -size 400x400 radial-gradient:white-black out.png  # radial

# Plasma (random colorful)
magick -size 800x400 plasma: output.png
magick -size 800x400 plasma:red-blue output.png

# Pattern
magick -size 400x400 pattern:checkerboard output.png
magick -size 400x400 pattern:crosshatch output.png
magick -list pattern                                       # list patterns

Output:

text
# magick -list pattern
bricks
checkerboard
circles
crosshatch
crosshatch45
fishscales
gray0
gray100
…

Borders & frames

-border WxH adds a solid-color margin of width W and height H around the image using the -bordercolor value. -frame creates a raised or sunken 3D-style frame using highlight and shadow edges, while -extent with -gravity center is the most flexible approach when you want to pad the canvas to a specific total size.

bash
# Add solid border
magick input.jpg -border 10x10 -bordercolor black output.jpg
magick input.jpg -border 5x20 -bordercolor white output.jpg  # asymmetric

# Add padding (extend canvas)
magick input.jpg -gravity center -background white -extent 1000x800 output.jpg

# Frame
magick input.jpg -frame 5x5+2+2 output.jpg      # raised frame effect

# Shadow
magick input.png \( +clone -background black -shadow 80x3+5+5 \) \
  +swap -background white -layers merge +repage output.png

Output: (none — exits 0 on success)

Transparency & alpha

PNG and WebP support an alpha channel; JPEG does not. -alpha set enables the alpha channel on an image that lacks one, while -transparent color makes pixels of a specific color fully transparent — useful for removing solid-color backgrounds. Use -flatten with a -background color to collapse transparency when converting to a format that doesn't support it.

bash
# Remove white background → transparent PNG
magick input.jpg -fuzz 5% -transparent white output.png

# Remove background with flood-fill
magick input.png -fuzz 10% -fill none -draw "color 0,0 floodfill" output.png

# Set overall opacity
magick input.png -alpha set -channel A -evaluate set 50% output.png

# Add alpha channel
magick input.jpg -alpha set output.png

# Remove alpha channel (flatten to white background)
magick input.png -background white -flatten output.jpg

# Mask transparency
magick input.png mask.png -compose CopyOpacity -composite output.png

Output: (none — exits 0 on success)

PDF operations

ImageMagick rasterizes PDFs via Ghostscript, so it must be installed separately and the system's ImageMagick policy file must allow PDF access. -density sets the DPI at which the PDF is rendered before any other operations — 150 DPI is adequate for screen use and 300 DPI for print-quality output.

bash
# PDF → PNG (one file per page)
magick -density 150 document.pdf page.png      # 150 DPI → page-0.png, page-1.png
magick -density 300 document.pdf -quality 90 page.jpg  # 300 DPI JPEG

# Specific pages
magick -density 150 'document.pdf[0]' page1.png
magick -density 150 'document.pdf[0-4]' pages.png

# PNG → PDF
magick image.png output.pdf
magick *.png -compress jpeg -quality 85 output.pdf  # multiple images → PDF

# Multi-image PDF
magick page1.jpg page2.jpg page3.jpg -compress Zip output.pdf

# Reduce PDF size (rasterize at lower DPI)
magick -density 150 -compress jpeg -quality 70 input.pdf compressed.pdf

# PDF info
magick identify -verbose 'document.pdf[0]' | grep -E "Geometry|Resolution|Type"

Output:

text
# magick identify -verbose 'document.pdf[0]' | grep -E "Geometry|Resolution|Type"
  Geometry: 1654x2339+0+0
  Resolution: 150x150
  Type: TrueColor

mogrify — in-place batch processing

mogrify modifies files in place. Always work on a copy or use --path to redirect output.

bash
# Resize all JPEGs in-place
magick mogrify -resize 1280x720 *.jpg

# Convert all PNGs to JPEG (creates new .jpg files alongside originals)
magick mogrify -format jpg *.png

# Output to a different directory (preserve originals)
mkdir -p resized
magick mogrify -resize 800x -path ./resized/ *.jpg

# Batch: convert, resize, quality
magick mogrify -resize 1920x1080\> -quality 85 -format jpg -path ./web/ *.png

# Strip EXIF from all JPEGs
magick mogrify -strip *.jpg

# Auto-orient all images (fix EXIF rotation)
magick mogrify -auto-orient *.jpg

# Sharpen all images
magick mogrify -unsharp 0x1+0.5+0.05 *.jpg

# Add watermark text to all images
magick mogrify -gravity SouthEast -fill "rgba(255,255,255,0.6)" \
  -font Arial -pointsize 20 -annotate +10+10 "© 2026" *.jpg

# Convert all HEIC to JPEG
magick mogrify -format jpg -path ./converted/ *.HEIC

Output: (none — exits 0 on success)

Append — combine images

-append stacks images vertically (top to bottom) and +append concatenates them horizontally (left to right), scaling or aligning as needed. This is simpler than using montage or composite when you just want to tile a fixed set of images into a single strip without specifying geometry.

bash
# Stack vertically
magick -append top.jpg bottom.jpg stacked.jpg

# Concatenate horizontally
magick +append left.jpg right.jpg side-by-side.jpg

# Multiple images
magick +append img1.jpg img2.jpg img3.jpg strip.jpg
magick -append img1.jpg img2.jpg img3.jpg column.jpg

Output: (none — exits 0 on success)

Common recipes

bash
# Create thumbnail with exact 200x200 square crop
magick input.jpg -thumbnail 200x200^ -gravity center -extent 200x200 thumb.jpg

# Convert HEIC photos to JPEG (macOS)
for f in *.heic *.HEIC; do
  magick "$f" -quality 85 "${f%.*}.jpg"
done

# Resize images, only shrink (never upscale), preserve folder
find photos/ -name "*.jpg" | while read f; do
  magick "$f" -resize '2048x2048>' -quality 85 "$f"
done

# Add white border + drop shadow
magick input.jpg \
  -bordercolor white -border 15 \
  \( +clone -background gray50 -shadow 60x4+4+4 \) \
  +swap -background white -layers merge output.png

# Create favicon set from source image
magick icon.png -resize 16x16  favicon-16.png
magick icon.png -resize 32x32  favicon-32.png
magick icon.png -resize 48x48  favicon-48.png
magick favicon-16.png favicon-32.png favicon-48.png favicon.ico

# Optimise JPEG for web (resize + strip + 85% quality)
magick input.jpg -resize '1920x1080>' -strip -quality 85 -interlace Plane output.jpg

# Progressive JPEG
magick input.jpg -interlace Plane output.jpg

# Convert image sequence to GIF with loop
magick -delay 8 -loop 0 frames/*.png animation.gif

# Optimize GIF
magick animation.gif -layers optimize optimized.gif
magick animation.gif -coalesce -layers Optimize out.gif

# Posterize + grayscale (stylized look)
magick input.jpg -colorspace Gray -posterize 6 output.jpg

# Blur background (fake tilt-shift)
magick input.jpg \
  \( +clone -blur 0x8 \) \
  -compose src-over \
  \( -size "%[fx:w]x%[fx:h]" gradient:white-black \) \
  -composite output.jpg

# Remove image background to PNG (white background removal)
magick input.jpg -fuzz 15% -transparent white output.png

# Stack images side by side with a separator line
magick +append left.jpg \( -size 4x%[left.jpg height] xc:gray \) right.jpg result.jpg

# Spritesheet: combine icons into one image
magick +append icon*.png spritesheet.png

# Compare two images, output highlighted diff
magick compare -highlight-color red -lowlight-color white img1.jpg img2.jpg diff.jpg

# Batch rename + convert with sequential numbering
i=1
for f in *.jpg; do
  magick "$f" -resize 800x "output_$(printf '%03d' $i).jpg"
  i=$((i+1))
done

Output: (none — exits 0 on success)

Useful options reference

OptionDescription
-resize WxHResize preserving aspect ratio
-crop WxH+X+YCrop region
-rotate degRotate (expands canvas)
-flip / -flopVertical / horizontal mirror
-quality NJPEG/WebP quality 0–100
-stripRemove EXIF/profiles
-auto-orientFix orientation from EXIF
-gravity dirAnchor point (NW, N, NE, W, Center, E, SW, S, SE)
-extent WxHResize canvas (pad or crop)
-background colorFill color for new canvas area
-fill colorFill color for drawing
-stroke colorStroke color
-strokewidth NStroke width
-font nameFont for text
-pointsize NFont size
-annotate deg textDraw rotated text
-blur RxSGaussian blur (radius × sigma)
-sharpen RxSSharpen
-unsharp RxS+A+TUnsharp mask
-colorspace GrayConvert to grayscale
-normalizeStretch contrast to full range
-level B,W,GSet black/white point + gamma
-modulate B,S,HAdjust brightness/saturation/hue
-negateInvert image
-alpha setEnable alpha channel
-flattenFlatten layers onto background
-layers optimizeOptimize GIF layers
-density NDPI for PDF/PS input
-compress typeOutput compression
-interlace PlaneProgressive JPEG
-define jpeg:size=Hint for faster JPEG decode
-thumbnail WxHFast resize for thumbnails
-fuzz N%Color matching tolerance
-trimRemove border/whitespace
+repageReset canvas offset after trim/crop

Alternatives

ImageMagick is the most format-complete and feature-rich image toolkit available, but it is not the fastest and not always the safest default for high-throughput web pipelines. The main 2026-relevant alternatives are libvips (and its bindings) for raw throughput, Sharp for Node.js, Pillow / Pillow-SIMD for Python scripting, and ffmpeg for video frames and some image batch work. Reach for ImageMagick when you need its breadth (200+ formats, MVG drawing, montage, compare, IM scripts); reach for libvips/Sharp when you are resizing or recompressing millions of photos.

ToolStrengthsTrade-offsBest for
ImageMagick200+ formats, scriptable MVG, drawing, montage, compare, broad effects libraryHighest memory/CPU per op; default policy.xml may need hardeningFormat conversion variety, complex compositing, scripting, one-offs
libvips (vips CLI)Demand-driven streaming pipeline — ~4–8× faster than IM on resize, low memorySmaller format set, terser CLI, less drawing capabilityBulk resize, thumbnail farms, ETL of image collections
Sharp (Node.js → libvips)Easiest libvips API, async, ~40–50× faster than Jimp, ~6M weekly npm downloadsNode-only; format set limited to libvips delegatesServer-side image APIs, build pipelines, Next.js / Astro asset transforms
Pillow / Pillow-SIMDPure Python API, ubiquitous in data-science stacksSlower than libvips; threading limited by GILNotebook work, ML preprocessing, ad-hoc Python scripts
GraphicsMagickIM 5 fork — faster on some ops, lower memory, narrower feature setLags IM on modern formats (HEIC, AVIF) and security fixesLegacy IM 5–era scripts, embedded/resource-tight servers
ffmpegExcellent video → frame extraction, can do basic resize/cropAwkward for non-video stills, no MVG/drawingVideo screenshots, animated GIF/WebP encoding, cross-format batch
VIPS Python (pyvips)libvips speed from PythonDifferent mental model (lazy pipeline) than PillowPython services that outgrow Pillow performance
bash
# Quick libvips equivalent for the most common ImageMagick op (resize-and-strip)
vips thumbnail input.jpg output.jpg 800 --strip
# vs
magick input.jpg -resize 800x -strip output.jpg

# Sharp (Node.js) — async, libvips under the hood
node -e "
const sharp = require('sharp');
sharp('input.jpg').resize(800).toFile('output.jpg');
"

Output: (none — exits 0 on success)

Picking a default in 2026: for a new web service that resizes user uploads, start with Sharp (Node) or pyvips (Python) and keep magick available for the long-tail formats they don't handle. For a workstation or a server doing diverse one-off jobs, ImageMagick is still the right default — just install with a hardened policy.xml and prefer the magick binary.

Sources