Batch Resize Images in Linux with ImageMagick

Deepak Prasad
Tested on RHEL 10.2 (Coughlan)
Package ImageMagick 7.1.1-47 (ImageMagick on RHEL-family; imagemagick on Debian and Ubuntu)
Applies to RHEL, Rocky Linux, AlmaLinux, Oracle Linux, CentOS Stream, Fedora, Debian, Ubuntu, and other Linux distributions with ImageMagick installed
Privilege Normal user for read-only checks; write permission on image files and output directories
Scope Batch resize JPG, PNG, and other raster images with magick mogrify and magick, including aspect ratio, non-destructive -path output, mixed extensions, recursive directories, format conversion, and an optional Bash script. Does not cover GUI editors or FFmpeg video frames.
Related guides Install ImageMagick on Ubuntu
find command
Bash for loop
Linux screenshot tools
wget command

ImageMagick can resize every matching image in a directory with one mogrify command. The safest starting point writes into a separate folder and shrinks only images larger than the target:

bash
mkdir -p resized
magick mogrify -path resized -resize '1200x1200>' *.jpg

This shrinks only images larger than 1200×1200, preserves aspect ratio, and writes results under resized/ instead of replacing the source files.

The shorter in-place form overwrites originals:

bash
magick mogrify -resize '1200x1200>' *.jpg

Use that only when you have backups or no longer need the source files.


Quick reference: batch resize images with ImageMagick

Task Command
Set width to 1200 px (may enlarge) magick mogrify -resize 1200x *.jpg
Max width 1200 px, shrink only magick mogrify -resize '1200x>' *.jpg
Fit inside 1200×1200, shrink only magick mogrify -resize '1200x1200>' *.jpg
Resize to 50% magick mogrify -resize 50% *.jpg
Set height to 800 px (may enlarge) magick mogrify -resize x800 *.jpg
Max height 800 px, shrink only magick mogrify -resize 'x800>' *.jpg
Force exact 800×600 (may distort) magick mogrify -resize '800x600!' *.jpg
Save to another folder magick mogrify -path resized -resize '1200x1200>' *.jpg
Convert PNG → JPG magick mogrify -path converted -format jpg *.png
Check dimensions magick identify *.jpg

Install ImageMagick on Linux

Install the ImageMagick package from your distribution repository, then confirm the magick driver is on your PATH.

On Debian and Ubuntu:

bash
sudo apt install imagemagick

On RHEL, Rocky Linux, AlmaLinux, Oracle Linux, CentOS Stream, and Fedora:

bash
sudo dnf install ImageMagick

That RPM name is capitalized on RHEL-family systems. For a fuller Ubuntu walkthrough with removal steps, see install ImageMagick on Ubuntu.

Confirm the version ImageMagick reports:

bash
magick -version
output
Version: ImageMagick 7.1.1-47 Q16-HDRI x86_64 22763 https://imagemagick.org
Copyright: (C) 1999 ImageMagick Studio LLC
License: https://imagemagick.org/script/license.php

ImageMagick 7 uses magick as the main entry point (magick mogrify, magick identify). Older ImageMagick 6 installs may still expose standalone convert and mogrify binaries; the geometry rules are the same, but prefer magick on new systems.


Batch resize images with mogrify

magick mogrify applies the same options to every file you name on the command line. By default it writes back to those paths, so batch jobs need either a backup plan or -path to an output directory.

Resize to a specific width or height

The examples below write to a separate directory, so create it once first:

bash
mkdir -p resized

A width-only geometry sets width to exactly that many pixels and calculates height to preserve aspect ratio:

bash
magick mogrify -path resized -resize 1200x *.jpg

1200x means “width 1200 pixels; height follows the original proportions.” A 2400×1600 file becomes 1200×800, but a 600×400 file becomes 1200×800 as well — ImageMagick enlarges smaller images unless you add >.

Height-only geometry works the same way with a leading x:

bash
magick mogrify -path resized -resize x800 *.jpg

A 1600×2400 portrait becomes 533×800.

Percentage resize scales every dimension equally:

bash
magick mogrify -path resized -resize 50% *.jpg

An 800×600 source becomes 400×300 after a 50% resize.

Resize only images larger than a maximum size

Append > when you want a maximum, not an exact target. ImageMagick preserves aspect ratio by default; > only adds the shrink-only rule and does not change that behavior.

bash
magick mogrify -path resized -resize '1200x>' *.jpg

A 2400×1600 file becomes 1200×800, but a 600×400 file stays 600×400. For a maximum box in both dimensions:

bash
magick mogrify -path resized -resize '1200x1200>' *.jpg

Resize without overwriting originals

By default, mogrify replaces each input file in place. Every -path resized example above writes copies under resized/ and leaves the sources untouched. That -path plus shrink-only geometry pattern is the workflow I recommend for photo exports, web uploads, and email attachments.


Preserve aspect ratio or create exact-size images

Most batch jobs should keep proportions. A few layout cases need identical pixel dimensions on every thumbnail.

Fit inside a width and height

A plain box geometry fits inside the limits while preserving aspect ratio, but it can still enlarge a smaller image:

bash
magick mogrify -path resized -resize 1200x800 *.jpg

For a maximum 1200×800 box that never upscales, append >:

bash
magick mogrify -path resized -resize '1200x800>' *.jpg

Append < when you want to enlarge only images smaller than the box ('1200x800<').

Force exact dimensions

Forcing every thumbnail to identical pixels distorts non-matching aspect ratios:

bash
magick mogrify -path thumbs -resize '800x600!' *.jpg

The ! flag forces width and height even when that stretches the image.

Resize and crop without distortion

A better pattern for cards and grids resizes to cover the box, then crops from the center with -extent:

bash
magick input.jpg -resize '800x600^' -gravity center -extent 800x600 output.jpg

^ fills the target box while preserving aspect ratio; -extent crops the overflow. For bulk output, loop over inputs and write into a separate directory:

bash
mkdir -p thumbs
for img in *.jpg; do
  base=$(basename "$img")
  magick "$img" -resize '800x600^' -gravity center -extent 800x600 "thumbs/$base"
done

Quote "$img" and "thumbs/$base" so filenames with spaces stay intact.


Resize JPG, PNG, and other image formats

Shell globs such as *.jpg do not match .jpeg or .png in the same pass.

Process multiple extensions

A short Bash for loop handles mixed extensions safely:

bash
mkdir -p resized

for img in *.{jpg,jpeg,png}; do
  [ -f "$img" ] || continue
  magick "$img" -resize '1200x1200>' "resized/$img"
done

[ -f "$img" ] || continue skips globs that matched nothing. Each magick call writes one output file, so originals stay in place.

Avoid backtick loops such as for img in `echo $dir/*` and unquoted variables such as convert $file — both break on spaces and shell metacharacters.

Resize and convert formats

Format conversion is secondary to resizing, but mogrify can do both when you publish web-friendly derivatives. Write WebP outputs from JPEG sources:

bash
mkdir -p converted

magick mogrify -path converted -format webp -resize '1200x1200>' *.jpg

PNG to JPG conversion works the same way:

bash
magick mogrify -path converted -format jpg *.png
IMPORTANT

JPEG does not support transparency. If the PNG files contain transparent areas, flatten them onto an explicit background before converting so the resulting color is predictable:

bash
magick mogrify -path converted -background white -alpha remove -alpha off -format jpg *.png

Recursively resize images in subdirectories

Photo libraries often nest folders by year or project. Use find with -print0 and a read loop so paths with spaces stay safe:

text
images/
├── 2025/
├── 2026/
└── products/

Mirror that tree under resized/ by creating the output root first:

bash
mkdir -p resized

find images -type f \( -iname '*.jpg' -o -iname '*.png' \) -print0 |
  while IFS= read -r -d '' img; do
    rel="${img#images/}"
    out="resized/$rel"
    mkdir -p "$(dirname "$out")"
    magick "$img" -resize '1200x1200>' "$out"
  done

Each source path keeps its relative directory structure under resized/. A file named products/item one.jpg lands in resized/products/item one.jpg, preserving the original directory layout.


Verify the resized images

identify prints width and height for every file you pass:

bash
magick identify resized/*.jpg

For a compact before-and-after table, add -format:

bash
magick identify -format '%f %wx%h\n' resized/*.jpg
output
photo-small.jpg 800x600
photo-tall.jpg 800x1200
photo-wide.jpg 1200x800

Compare total disk usage when you need proof the batch saved space:

bash
du -sh images resized
output
236K	images
60K	resized

The exact byte counts depend on your sources; confirm dimensions with identify and folder size with du before you delete originals.


Reusable Bash script for repeated jobs

You do not need a custom script for a one-off folder resize — magick mogrify -path … already covers that. A script helps when you run the same job on incoming exports every week.

Create the script with a quoted heredoc so the shell does not expand $0 or $1 while you paste:

bash
cat > resize-images.sh <<'EOF'
#!/usr/bin/env bash
set -euo pipefail

usage() {
  echo "Usage: $0 SOURCE_DIR OUTPUT_DIR MAX_SIZE" >&2
  exit 1
}

[[ $# -eq 3 ]] || usage

src=$1
out=$2
max=$3

[[ -d "$src" ]] || {
  echo "Source directory not found: $src" >&2
  exit 1
}

mkdir -p "$out"

shopt -s nullglob
for img in "$src"/*.{jpg,jpeg,JPG,JPEG,png,PNG}; do
  [[ -f "$img" ]] || continue
  base=$(basename "$img")
  magick "$img" -resize "${max}x${max}>" "$out/$base"
done
EOF

Make it executable and point it at a source directory and output directory:

bash
chmod +x resize-images.sh
./resize-images.sh ~/photos/inbox ~/photos/web 1200

The script processes files directly inside SOURCE_DIR only; use the recursive find example above when subdirectories also need resizing. It never overwrites sources, quotes paths, and limits geometry with ${max}x${max}> so small icons are not upscaled.


Common ImageMagick resize geometry

Aspect ratio is preserved by default on ordinary -resize geometry. The > flag does not preserve aspect ratio — it only prevents smaller images from being enlarged.

Geometry Meaning
1200x Set width to 1200 px; height scales proportionally (may enlarge)
1200x> Max width 1200 px; shrink only, never enlarge
x800 Set height to 800 px; width scales proportionally (may enlarge)
x800> Max height 800 px; shrink only
1200x800 Fit inside 1200×800; preserve aspect ratio (may enlarge)
1200x800> Max 1200×800 box; shrink only
1200x800< Enlarge only if smaller than the box
800x600! Force exact 800×600; may distort
800x600^ Fill at least 800×600; crop with -extent
50% Scale width and height by 50%

Summary

ImageMagick already solves batch resize on Linux — you do not need a custom parser for the common case. magick mogrify -path resized -resize '1200x1200>' is the safest default: originals stay put, aspect ratio stays intact, and small images are not upscaled.

Plain 1200x or x800 sets an exact width or height and can enlarge smaller files; append > when you mean a maximum. When every thumbnail must be identical pixels, prefer resize with ^ plus -extent over the ! flag that stretches the image. Mixed extensions and recursive directory trees need quoted loops or find -print0, not backtick filename expansion.

Keep a one-line mogrify job for ad hoc folders; reach for the script only when the same resize runs on a schedule. Verify with magick identify and du before you archive or delete source files.


References


Frequently Asked Questions

1. What is the difference between magick mogrify and magick?

magick mogrify applies the same transformation to multiple input files and normally writes back to those filenames, which makes it convenient for batch jobs. magick is the general ImageMagick command and is better when you want explicit input and output filenames or a more complex resize-and-crop pipeline.

2. How do I resize all images in a folder without overwriting the originals?

Create an output directory, then run magick mogrify -path OUTPUT_DIR -resize GEOMETRY *.jpg. mogrify writes each processed file into OUTPUT_DIR and leaves the source files untouched. Add quotes around geometry flags that contain > or ! so the shell does not redirect output.

3. How do I resize only images larger than a target size?

Append > to the geometry string, for example -resize 1200x1200>. ImageMagick shrinks images that exceed the box but does not enlarge smaller ones. Combine with -path when you want originals preserved.

4. Does ImageMagick preserve aspect ratio when batch resizing?

Yes, unless you add ! to force exact dimensions. A width-only geometry such as 1200x sets width to 1200 pixels and calculates height automatically, which can enlarge a smaller image. Append > for shrink-only behavior, for example 1200x> limits width without upscaling. The > flag does not preserve aspect ratio by itself; aspect ratio is the default resize behavior.
Omer Cakmak

Linux Administrator

Highly skilled at managing Debian, Ubuntu, CentOS, Oracle Linux, and Red Hat servers. Proficient in bash scripting, Ansible, and AWX central server management, he handles server operations on OpenStack, KVM, Proxmox, and VMware.

  • Debian
  • Ubuntu
  • Linux
  • Red Hat Enterprise Linux
  • Shell Script
  • System Administration