Batch Resize Images using Linux Command Line and Imagemagick

Large images means a large page size which means slow WordPress page load times for users. The most common culprit is image size or lack of compression. If you never had any image size restrictions or automatic resizing on your site, it can be extremely convenient to batch resize those images in Linux.

This guide shows you how to batch resize jpg and png files using Imagemagick on Ubuntu or Debian. If you want to install Imagemagick on CentOS see this guide.

Batch Resize Images using Linux Command Line and Imagemagick

First we need to install Imagemagick from the repository on Debian or Ubuntu

sudo apt-get update
sudo apt-get install imagemagick -y

We can use the identify command to get the width (%w) and height (%h)

identify -format "%wx%h" image.jpg

You will see the resolution, width is first then height.

3960x2120

You can resize the image if it is larger than the specified dimensions. This will automatically preserve the aspect ratio of the image too.

Note that this overwrites your original image!

convert image.jpg -resize 600x400\> image.jpg

Check the image was resized

identify -format "%wx%h" image.jpg

All good!

600x321

Now we can move on to batch resizing

Batch Resize Images with Linux with Imagemagick

Create the following script

mkdir -p ~/scripts
nano ~/scripts/batch-image-resize.sh

Paste the script below, remember to change the FOLDER variable!

FOLDER is the absolute path to your image folder

WIDTH is the max width and HEIGHT is the max height.

It will overwrite your original images so make sure you have a backup before running this!

#!/usr/bin/env bash
# Purpose: batch image resizer
# Source: https://guides.wp-bullet.com
# Author: Mike

# absolute path to image folder
FOLDER="/var/www/wp-bullet.com/wp-content/uploads"

# max width
WIDTH=540

# max height
HEIGHT=300

#resize png or jpg to either height or width, keeps proportions using imagemagick
#find ${FOLDER} -iname '*.jpg' -o -iname '*.png' -exec convert \{} -verbose -resize $WIDTHx$HEIGHT\> \{} \;

#resize png to either height or width, keeps proportions using imagemagick
#find ${FOLDER} -iname '*.png' -exec convert \{} -verbose -resize $WIDTHx$HEIGHT\> \{} \;

#resize jpg only to either height or width, keeps proportions using imagemagick
find ${FOLDER} -iname '*.jpg' -exec convert \{} -verbose -resize $WIDTHx$HEIGHT\> \{} \;

# alternative
#mogrify -path ${FOLDER} -resize ${WIDTH}x${HEIGHT}% *.png -verbose

Ctrl+X, Y and Enter to save and exit.

Check the folder size

du -sh foldername

Check output size

220MB

Screen will ensure the batch command keeps on running even if your SSH session is terminated.

sudo apt-get install screen

Create a new screen session, press space or enter at the intro screen

screen

Execute the script

bash ~/scripts/batch-image-resize.sh

Detach the screen with Ctrl+A and pressing D (detach).

You can use the top command and look for jpegoptim processes once in a while.

Reattach the screen like so

screen -r

Check the folder size again

du -sh foldername

You should see an improvement

186MB

Make sure to compress your images with lossless (guide) or lossy compression (guide).

If you need to do some more advanced find commands that use regex this should help.

Sources

Using find to Search for Multiple Extensions
How to get Image Information with Linux
Imagemagick Shrink
Resize Images and Keep Ratio

24 thoughts on “Batch Resize Images using Linux Command Line and Imagemagick”

  1. thanks for this interesting approach…cannot see any activity when running the script…just a quick cessation/no-result…the isolated “convert” command does work for me…is there a way to step through a bash script?…when i run the script without customizing the folder-name it does execute and reports the expected error (find: `/var/www/wp-bullet.com/wp-content/uploads’: No such file or directory)

      • Thanks for the reply. I did subsequently replace with the desired path, but when the script is run it merely fails silently. I do not know what to do next. thanks again

        • Could be there are no images there, what output do you get from find $FOLDER -iname ‘*.jpg’ -o -iname ‘*.png’ because if that returns no results then there are no images for the script to resize.

  2. Can’t see any activity either. Convert works on an individual file. The test folder is correctly identified and there’s a 4000 wide image in it. Width limit set to 1024 and height set to 10000 just to keep it out of the way. I just get an instant cursor back. Nothing happens in the directory.

      • Yes, and if I shorten the last line to ….
        find $FOLDER -iname ‘*.jpg’ -o -iname ‘*.png’;
        It puts out a list of the files. Also tried removing the HEIGHT as ImageMagick says if only WIDTH is provided then everything stays in the same ratio but that didn’t work either.

        • I am actually testing this now and it seems to be working, it’s just very fast! Can you try running the identify command on some of the images in the folder you wanted to convert? I’m working on getting verbose output so it doesn’t appear to fail

          • -verbose in the original line makes no difference.
            Using the new line (changing .png for .jpg) I get….
            mogrify: unable to open image `*.jpg’: No such file or directory @ error/blob.c/OpenBlob/2712.
            Yet find $FOLDER -iname ‘*.jpg’ -o -iname ‘*.png’; gives a full list of images.

          • Weird, I just tested with a png and jpg in the same absolute path on Linux and I get this output

            root@guides:/tmp/images# bash test
            /tmp/wp-cli-delete-unused-plugins.png PNG 360×111=>80×25 80×25+0+0 8-bit sRGB 1.39KB 0.000u 0:00.009
            /tmp/images/wp-cli-delete-unused-plugins.png PNG 300×139=>80×37 80×37+0+0 8-bit sRGB 1.66KB 0.000u 0:00.009

            Script

            #!/usr/bin/env bash
            # Purpose: batch image resizer Source: https://guides.wp-bullet.com
            # Author: Mike absolute path to image folder
            set -o errexit
            set -o pipefail

            FOLDER=”/tmp”
            # max height
            WIDTH=120
            # max width
            HEIGHT=80
            #resize to either height or width, keeps proportions using imagemagick
            find ${FOLDER} -iname ‘*.jpg’ -o -iname ‘*.png’ -exec convert {} -verbose -resize $WIDTHx$HEIGHT> {} ;

      • Final line is…..
        find $FOLDER -iname ‘*.jpg’ -o -iname ‘*.png’ -exec convert {} -resize $WIDTH> {} ;
        WIDTH is set to 1024 and the target folder has a jpg in it that’s over 4000 wide.
        I’m using Linux Mint 18.2 Cinnamon 64 bit. All up to date.

  3. Hi. Today I found your script, but after starting it, I just get the cursor back … nothing happens. The convert command for a single image is working fine.

    • Hi Janko, please see the comments below and let me know how that goes. If you are still struggling please consider sharing SSH access and getting in touch with me via m contact form 🙂

      • I already had a look. And I think I use the latest version with -verbose, but there is still no output. Maybe we could have a look together via TeamViewer?

  4. Hey, this is excellent, is there any way to check the file size before converting, I want only image greater than 1 mb to be converted. Thanks

Comments are closed.