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
magickbinary 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-codeconvertwill fail with "command not found" on those systems. Always prefermagick <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
# 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:
# 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.
# 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:
# 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
| File | Purpose |
|---|---|
policy.xml | Security policy — coder/resource/path/module limits (most-edited file) |
delegates.xml | External commands used to read/write formats (Ghostscript, librsvg, …) |
colors.xml | Named color aliases |
type.xml / type-ghostscript.xml | Font search paths and aliases |
thresholds.xml | Dither and posterise threshold maps |
log.xml | Log event filters and output format |
mime.xml | MIME-type → format mapping |
locale.xml, english.xml | Message 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:
| Template | Intent |
|---|---|
open (default) | Permissive — assumes ImageMagick runs behind a firewall or in a container |
limited | Disables high-risk coders (PS, PDF, MVG, MSL) and HTTP, keeps common formats |
secure | Tight resource limits + most coders disabled; flip on only what you need |
websafe | Read/write restricted to GIF, JPEG, PNG, WebP; no filters or indirect reads |
<!-- /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
securetemplate did not blockfd: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 frompolicy-secure.xml.
# 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.
# 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 7 | IM 6 equivalent | Purpose |
|---|---|---|
magick input … output | convert | Convert / process images |
magick identify | identify | Read image metadata |
magick mogrify | mogrify | In-place batch processing |
magick composite | composite | Overlay images |
magick montage | montage | Create contact sheets |
magick compare | compare | Visual diff between images |
magick stream | stream | Stream raw pixels |
magick import | import | Screen 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.
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:
# 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.
# 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:
| Syntax | Meaning |
|---|---|
800x600 | Fit 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 |
800x | Width 800, height proportional |
x600 | Height 600, width proportional |
+50+30 | Offset: 50px from left, 30px from top |
800x600+10+20 | Resize 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.
# 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.
# 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.
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.
# 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.
# 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.
# 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.
# 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:
# 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.
# 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.
# 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.
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:
# 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.
# 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:
# 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.
# 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.
# 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.
# 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:
# magick identify -verbose 'document.pdf[0]' | grep -E "Geometry|Resolution|Type"
Geometry: 1654x2339+0+0
Resolution: 150x150
Type: TrueColor
mogrify — in-place batch processing
mogrifymodifies files in place. Always work on a copy or use--pathto redirect output.
# 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.
# 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
# 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
| Option | Description |
|---|---|
-resize WxH | Resize preserving aspect ratio |
-crop WxH+X+Y | Crop region |
-rotate deg | Rotate (expands canvas) |
-flip / -flop | Vertical / horizontal mirror |
-quality N | JPEG/WebP quality 0–100 |
-strip | Remove EXIF/profiles |
-auto-orient | Fix orientation from EXIF |
-gravity dir | Anchor point (NW, N, NE, W, Center, E, SW, S, SE) |
-extent WxH | Resize canvas (pad or crop) |
-background color | Fill color for new canvas area |
-fill color | Fill color for drawing |
-stroke color | Stroke color |
-strokewidth N | Stroke width |
-font name | Font for text |
-pointsize N | Font size |
-annotate deg text | Draw rotated text |
-blur RxS | Gaussian blur (radius × sigma) |
-sharpen RxS | Sharpen |
-unsharp RxS+A+T | Unsharp mask |
-colorspace Gray | Convert to grayscale |
-normalize | Stretch contrast to full range |
-level B,W,G | Set black/white point + gamma |
-modulate B,S,H | Adjust brightness/saturation/hue |
-negate | Invert image |
-alpha set | Enable alpha channel |
-flatten | Flatten layers onto background |
-layers optimize | Optimize GIF layers |
-density N | DPI for PDF/PS input |
-compress type | Output compression |
-interlace Plane | Progressive JPEG |
-define jpeg:size= | Hint for faster JPEG decode |
-thumbnail WxH | Fast resize for thumbnails |
-fuzz N% | Color matching tolerance |
-trim | Remove border/whitespace |
+repage | Reset 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.
| Tool | Strengths | Trade-offs | Best for |
|---|---|---|---|
| ImageMagick | 200+ formats, scriptable MVG, drawing, montage, compare, broad effects library | Highest memory/CPU per op; default policy.xml may need hardening | Format conversion variety, complex compositing, scripting, one-offs |
libvips (vips CLI) | Demand-driven streaming pipeline — ~4–8× faster than IM on resize, low memory | Smaller format set, terser CLI, less drawing capability | Bulk resize, thumbnail farms, ETL of image collections |
| Sharp (Node.js → libvips) | Easiest libvips API, async, ~40–50× faster than Jimp, ~6M weekly npm downloads | Node-only; format set limited to libvips delegates | Server-side image APIs, build pipelines, Next.js / Astro asset transforms |
| Pillow / Pillow-SIMD | Pure Python API, ubiquitous in data-science stacks | Slower than libvips; threading limited by GIL | Notebook work, ML preprocessing, ad-hoc Python scripts |
| GraphicsMagick | IM 5 fork — faster on some ops, lower memory, narrower feature set | Lags IM on modern formats (HEIC, AVIF) and security fixes | Legacy IM 5–era scripts, embedded/resource-tight servers |
| ffmpeg | Excellent video → frame extraction, can do basic resize/crop | Awkward for non-video stills, no MVG/drawing | Video screenshots, animated GIF/WebP encoding, cross-format batch |
VIPS Python (pyvips) | libvips speed from Python | Different mental model (lazy pipeline) than Pillow | Python services that outgrow Pillow performance |
# 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
- ImageMagick — Releases (GitHub) — 7.1.2-23 (May 2026) is the current series; no 7.2 release.
- ImageMagick — Security Policy — official
open/limited/secure/websafetemplate descriptions and per-domain reference. - policy-secure.xml (source) — the upstream
securetemplate, suitable as a starting point. - GHSA-xwc6-v6g8-pw2h — fd: handler bypass — Feb 2026 advisory;
fd:*must be denied in path policy. - Doyensec ImageMagick Security Policy Evaluator — open-source validator + hosted version.
- Porting to ImageMagick Version 7 — official IM 6 → IM 7 migration notes; explains the
magickunified binary and legacy-command status. - Sharp — Performance benchmarks — head-to-head numbers for Sharp/libvips vs ImageMagick and other Node libraries.
- Best JavaScript image processing libraries 2026 (PkgPulse) — current landscape and WebP/AVIF guidance.
- Fedora — ImageMagick7 transition — distros that drop the legacy
convert/identify/mogrifysymlinks under IM 7.