All Articles

Batch image resize with simple script (use case)

Recently I’ve seen a simple HTML project with many images. All of them were totally unoptimized. Many of them could be scaled down without losing the quality. The problem was that it could take ages to do it manually using Gimp for example.

For some reason (it was a college task for non computer science degree which can explain a lot 😄) the project was a mess and some images had .jpg format, some .JPG, some .png etc.

I wanted to help and to reprocess the images automatically. The images were in a ‘per-page’ structure.

images
|---page_1
|-------image1.jpg
|-------image2.JPG
|-------image3.JPEG
|---page_2
|-------image4.png
|-------image5.jpg

So I wanted to write a script that would take the folder structure, mirror it, and reprocess all images, no matter what format and move the to the output directory.

I knew the tool ImageMagick that can do bulk processing of the images but it requires the format to be given explicitly.

Therefore, I wrote this script below that automated the process. I added comments to explain each step.

#!/bin/bash 

# define the value for the resize
RESIZE_VALUE=30%
# take the input directory as a parameter
content_dir=$1;
# the output will go to the ./OUTPUT directory
output_dir=./OUTPUT

# take all directories that are inside out input directory
all_dirs=$(ls -d $content_dir*/)

# image formats that can be found in the input directory
formats=(".jpg" ".png" ".JPG" ".PNG" ".JPEG" ".jpeg")

for dir in $all_dirs
do
  # strip the input directory
  new_dir=${dir/$content_dir/''}
  # create the same folder in the output directory
  # -p flag will create nested directories even if the root 
  # directory does not exist.
  mkdir -p $output_dir/$new_dir 
  
  for format in ${formats[*]}
  do
    echo processing directory ${dir} for format ${format}...
    # resize images of each format
    magick ${dir}'*'${format} \
      # keep the filename
      -set filename:original %t \
      -resize $RESIZE_VALUE \
      $output_dir/$new_dir/%[filename:original]${format} \
      # suppress error output if files with specific format cannot be found
      2>/dev/null
    echo 'done;'
  done
done

echo '- - - - - - - - - - - - - -'
echo 'work complete'

To run the script you need to install ImageMagick. I was using Mac OS X so it was simple: brew install imagemagick. Then you need to add execute permission to the file chmod u+x ./the-script.sh and then just run it passing the input directory as a parameter.

./the-script.sh ./images