skip to content

ImageMagick β€” Image Manipulation

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

14 min read 20 snippets 2d ago intermediate

ImageMagick β€” Image Manipulation#

ImageMagick is a suite of command-line tools for creating, editing, compositing, and converting images. Supports 200+ formats.

IM 6 vs IM 7: ImageMagick 7 uses a single magick command. IM 6 uses separate commands (convert, identify, mogrify, …). Both work β€” IM 7 is preferred. 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" />

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 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

Format conversion#

# 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

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#

# 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

Crop#

# 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

Rotate & flip#

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

Color adjustments#

# 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

Filters & effects#

# 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

Drawing & shapes#

# 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

Text annotations#

# 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:"

Composite β€” overlay images#

# 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

Montage β€” contact sheets#

# 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

Compare β€” visual diff#

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

Canvas & gradients#

# 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

Borders & frames#

# 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

Transparency & alpha#

# 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

PDF operations#

# 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"

mogrify β€” in-place batch processing#

mogrify modifies files in place. Always work on a copy or use --path to 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

Append β€” combine images#

# 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

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

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