Toolbox

ImageMagick Recipes

Note: These recipes use ImageMagick v7.0+.

Recipes

Crop an image to a certain aspect ratio

The command below crops an image to a square by shaving off the excess from the long side:

magick my_image.jpg -gravity Center -crop 1:1 my_image_cropped.jpg

The order of the arguments here matters — think of it as a sort of pipeline:

To crop a whole set of images in bulk, we use a modified command:

mkdir -p cropped && \
magick './*.jpg' \
-set filename:name "%t" \
-gravity Center \
-crop 1:1 \
"cropped/%[filename:name].jpg"

The command above makes a cropped copy of each JPEG image in the current folder and places it with its original name under a cropped subfolder.

Some key parts:

The command is not particularly fast, and it takes a while for any output to show up. For 600-ish images around 2000x2000px, it took about 20 minutes on my machine, and output began at about the 12 minute mark. For more incremental output, we can go through each image in the folder in Bash rather than ImageMagick:

mkdir -p cropped && \
for img in *.jpg; do magick $img -gravity Center -crop 1:1 "cropped/$img.jpg"; done

This will run the crop command on an image at a time, so you'll notice the cropped sub-folder fill up steadily. Using Bash we can avoid the -set parameter and just use our $img identifier.

Resize an image to fit a certain size

In the example below, we resize an image so that it fits within a 1000px × 1000px box, while maintaining its aspect ratio (analogous to using object-fit: contain in CSS):

magick my_image.jpg \
-gamma .45455 \
-resize 1000x1000 \
-unsharp 1.8x1.3+0.4+0 \
-gamma 2.2 \
my_image_resized.jpg

We use the -gamma option to decode the image to linear encoding, and then change it back to 2.2 after the resize — this is mentioned in the ImageMagick docs for -resize, but I'm not sure why it's necessary.

After resize we sharpen the image using the -unsharp option. Its arguments are a bit abstruse, but I found an article on the topic with some good rules of thumb.

Find out the dimensions of an image

To suffix image filenames with their width and height:

find . -type f -iname "*.png" | \
xargs -L1 magick identify -format "%i\n%d/%t-%wx%h.%e\n" | \
xargs -L2 mv

To produce HTML <img> tags for images, including width and height attributes:

find . -type f -iname "*.jpg" | xargs -L1 magick identify -format "<img src='%i' alt='' width='%w' height='%h'/>\n"

I have this alias in my .zshrc file:

# Generate <a><img></a> HTML markup for image files with ImageMagick.
# Sample usage: img images/*.png
alias img="magick identify -format \"<a href='%i'><img class='cover' src='%i' alt='' width='%w' height='%h'/></a>\n\""

Further reading

See also: ImageMagick command-line reference