Free Bash ScriptBatch Resizing Using Command Line and ImageMagick

Advertisement

If you deal with images, sooner or later you will want to automate the repeating process of saving different sizes from one source image. If you own Adobe Photoshop and do not save too many output sizes, Photoshop actions are probably quite enough for your needs. However, keeping a Photoshop action up-to-date is quite painful — change a source folder, and you’re screwed.

As you probably noticed in Smashing Magazine’s monthly desktop wallpaper series1, especially if you work on wallpapers, preparing them for a plethora of desktop resolutions is quite a task. On my own wallpapers website (Vladstudio2), I generate more than 300 JPEG files for each wallpaper! I want my art to reach as many devices as possible, which means I need to publish my wallpapers in as many sizes as I can support. On the other hand, I do not want to spend the rest of my life resizing my artworks — I’d rather draw new ones!

Long ago, I used Photoshop actions to save multiple sizes from a source file, but it quickly became a nightmare to maintain. Photoshop provides a more powerful tool — scripting language (it’s not the same as “actions”, though the concept is similar). When writing a script, you use a programming language to tell Photoshop what to do (compared to actions, where Photoshop records what you do with mouse and keyboard). However, it’s not easy to learn at all, and I also wanted to completely remove Photoshop from process.

The solution I found is ImageMagick3 — a command-line image manipulation program, available for Windows, Mac and Linux4. Unless you are a server administrator, you probably never thought of resizing images using command line. However, after switching to command line, I never looked back at Photoshop for batch resizing.

Using command line is:

  • Easy to expand — adding new sizes takes only one line of code.
  • Easy to maintain — changing folders is as easy as changing one variable.
  • Portable — I can save images on my server as well as my main computer.

Terminal in Python5
The bash script in use in Terminal. Large view6.

If you have never worked with command line before, it all might look scary at first. However, with a bit of patience, you will find that it’s actually a very powerful tool.

Below is the bash script I wrote, simplified for more universal usage. It takes the following parameters (from either you or from default values):

  • Set of output sizes.
  • Source file.
  • Destination path (path must include the % symbol, which will be replaced by output size, i.e. “800×600”).
  • Optional signature image.

Batch Resize Script7
The result after the script was applied. Large view8.

Then it resizes source image into every output size, applying a signature. For a better understanding, please look through the comments in source code.

The script requires:

  • imagemagick9 — to install. Follow instructions for your OS.
  • python — I’m sure your PC already has it installed!

Tested in Ubuntu and Mac OS X. How to use:

  • Save resize.sh to any folder on your computer.
  • Edit the file and set default values for variables (optional).
  • Open Terminal, navigate to this folder, and execute the following command: bash resize.sh.
  • Follow instructions, sit back and enjoy!

The Bash Script

Here is the full bash script. Of course, you can also download it from GitHub10.

#!/bin/bash

# Edit the settings below:

# Output sizes - 
# Please note the format: each size is wrapped with quotes, width and height are separated with space.
output=("800 600" "1024 768" "1152 864" "1280 960" "1280 1024" "1400 1050" "1440 960" "1600 1200" "1920 1440" "1024 600" "1366 768" "1440 900" "1600 900" "1680 1050" "1280 800" "1920 1080" "1920 1200" "2560 1440" "2560 1600" "2880 1800")

# If you frequently use the same source file (e.g. "~/Desktop/src.jpg"), 
# set it in "default_src"
default_src="src.jpg";

# If you frequently use the same destination
# (e.g. "~/Desktop/Some_folder/%.jpg"), set it in "default_dst"
# Destination must include "%", it will be replaced by output size, e.g. "800x600"
default_dst="%.jpg";

# Add signature? 
default_sign='y'

# If you frequently use the same signature file (e.g. "~/Desktop/sig.png"), 
# set it in "default_sig"
default_sig="sig.png";

# Gravity is for cropping left/right edges for different proportions (center, east, west)
default_gravity="center"

# Output JPG quality: maximum is 100 (recommended)
quality=100

# ======
# Do not edit below.
# ======
# Welcome to Smashing resizer!
# Written by Vlad Gerasimov from http://www.vladstudio.com
# 
# This script takes one "source" image and saves it in different sizes.
# 
# Requires:
# * imagemagick - http://www.imagemagick.org/
# * python - I'm sure your PC already has it!

# Unfortunately, bash is awful at math operations.
# We'll create a simple function that handles math for us.
# Example: $(math 2 * 2)

function math(){
  echo $(python -c "from __future__ import division; print $@")
}

# To make our script short and nice, here is the "save()" function.
# We'll use it to save each size.

function save(){

  # read target width and height from function parameters
  local dst_w=${1}
  local dst_h=${2}

  # calculate ratio 
  local ratio=$(math $dst_w/$dst_h);

  # calculate "intermediate" width and height
  local inter_w=$(math "int(round($src_h*$ratio))")
  local inter_h=${src_h}

  # calculate best sharpness
  local sharp=$(math "round((1/$ratio)/4, 2)")

  # which size we're saving now
  local size="${dst_w}x${dst_h}"
  echo "Saving ${size}..."

  #crop intermediate image (with target ratio)
  convert ${src} -gravity ${gravity} -crop ${inter_w}x${inter_h}+0+0 +repage temp.psd

  # apply signature
  if [ "${sign}" == "y" ]; then
  convert temp.psd ${sig} -gravity southeast -geometry ${sig_w}x${sig_h}+24+48 -composite temp.psd
  fi

  # final convert! resize, sharpen, save
  convert temp.psd -interpolate bicubic -filter Lagrange -resize ${dst_w}x${dst_h} -unsharp 0x${sharp} +repage -density 72x72 +repage -quality ${quality} ${dst/%/${size}}

}

# Ask for source image, or use default value
echo "Enter path to source image, or hit Enter to keep default value (${default_src}): "
read src
src=${src:-${default_src}}

# ask for destination path, or use default value
echo "Enter destination path, or hit Enter to keep default value (${default_dst})."
echo "must include % symbol, it will be replaced by output size, e.g. '800x600'"
read dst
dst=${dst:-${default_dst}}

# Ask for signature image, or use default value
echo "Apply signature? (hit Enter for 'yes' or type 'n' for 'no') "
read sign
sign=${sign:-${default_sign}}

# Ask for signature image, or use default value
echo "Enter path to signature image, or hit Enter to keep default value (${default_sig}): "
read sig
sig=${sig:-${default_sig}}

# ask for gravity, or use default value
echo "Enter gravity for cropping left/right edges (center, east, west), or hit Enter to keep default value (${default_gravity}): "
read gravity
gravity=${gravity:-${default_gravity}}


# detect source image width and height
src_w=$(identify -format "%w" "${src}")
src_h=$(identify -format "%h" "${src}")

# detect signature width and height
sig_w=$(identify -format "%w" "${sig}")
sig_h=$(identify -format "%h" "${sig}")


# loop throught output sizes and save each size
for i in "${output[@]}"
do
  save ${i}
done

# Delete temporary file
rm temp.psd

# Done!
echo "Done!"

Please let me know if you have any suggestions for improvements. Or perhaps you use a different technique to batch resize your images? Please share your thoughts, opinions and ideas in the comments section below!

(jvb) (vf)

Footnotes

  1. 1 http://www.smashingmagazine.com/2012/08/31/free-desktop-wallpaper-calendar-september-2012/
  2. 2 http://www.vladstudio.com
  3. 3 http://www.imagemagick.org/
  4. 4 http://www.imagemagick.org/script/binary-releases.php
  5. 5 http://www.smashingmagazine.com/wp-content/uploads/2012/09/terminal.png
  6. 6 http://www.smashingmagazine.com/wp-content/uploads/2012/09/terminal.png
  7. 7 http://www.smashingmagazine.com/wp-content/uploads/2012/09/finder.png
  8. 8 http://www.smashingmagazine.com/wp-content/uploads/2012/09/finder.png
  9. 9 http://www.imagemagick.org/script/binary-releases.php
  10. 10 https://github.com/vladstudio/smashing-resizer

↑ Back to topShare on Twitter

Vlad Gerasimov is a digital artist from Russia, most known by his wallpaper project, Vladstudio. In 1998 Vlad started to design user interfaces for web sites and software applications. However, during his spare time, he created desktop wallpapers. Over the time, this hobby has grown into business, and today Vlad enjoys full-time self-employment, creating wallpapers for your computers and mobile devices.

Advertising
  1. 1

    I got to ask, what color scheme are you using in Terminal?

    0
  2. 4

    Daniel Alexander Smith

    September 9, 2012 2:50 pm

    You can also use Automator to scale images (or indeed, a folder full of images):

    e.g. http://mactips.info/2007/03/resize-images-with-automator

    0
    • 5

      Automator is indeed good option if you don’t want to learn new stuff like Bash language. I already had this “burden” :-) So i figured using Bash would be better for me – I could “outsource” saving images to my Ubuntu machine.

      0
  3. 6

    Hi Vlad,

    This is wonderful! Thank you so much for this useful bit of info.
    N.

    0
  4. 7

    I started using Image Resizer for Windows. It works great! You just select the image(s) you want to resize in Windows explorer, right-click, and choose the image size.

    http://imageresizer.codeplex.com/

    0
  5. 8

    You can use RIOT to scale or optimize the images in a batch
    http://luci.criosweb.ro/riot/

    0
  6. 9

    Just…..nice :)

    0
  7. 10

    ImageMagick is one of those tools that I have used to a long time for a number of different tasks. The whole suite of utilities are fantastic. Don’t let a fear of a command line put you off of using them.

    0
  8. 11

    This really ease the working! ImageMagick has some pretty cool commandline tools to manage images.Its just so awesome!Pretty handy and quick.

    0
  9. 12

    This looks very promising. I’m currently struggling with moving my old website into a new WP theme. It takes forever to have to remake all the required graphics, with all different measures. Thank you!

    0
  10. 13

    i love it when a bash example are using macos screenshot :)

    0
  11. 15

    This is nice, but you have to install imagemagick on your computer. You could use sips (built-in Scriptable Image Processing System) to do the same thing: I have been using sips to do this for some months now on some computers at work and at home without maintaining extra software.

    0
    • 16

      …on OSX…
      (I forgot this … sorry!)

      0
    • 17

      Thanks! I am glad people suggest other solutions in comments. This, as well as most comments above, is tied to one platform (usually Windows or Mac). One bonus of my script is ability to run it on Macs and Linux PCs (I guess it could work on Windows too but with some more preparation).

      0
    • 18

      sips (and Automator and Preview) use a resizing filter that makes images look pretty blurry. You’d often need to add additional sharpening before or after resizing them. And it’s harder or impossible to do things like cropping.

      0
  12. 19

    You are true linux user.

    0
  13. 20

    I’m surprised nobody has mentioned Phatch yet…
    Phatch (Photo Batch Processor) will do this and a ton of other image manipulation techniques combined.
    I’ve yet to resort back to Bash or PHP scripts for bulk image manipulation since finding it over a year ago, although I do still code custom scripts for websites of course.

    0
    • 21

      This is why I love this kind of article – I share my solution, people share their alternatives in comments, and we end up having lots of great solutions on one page!

      0
  14. 22

    Imagemagick’s commandline tools are excellent, but user-beware: the quality can be very hard to nail.

    I worked on an automated resizing process to speed up the designers’ workflow at my workplace a while back, and without a doubt the biggest challenge was matching the resize quality to that of Photoshop and Fireworks. I almost got there, but it can still be a bit off depending on the image content. I’ll have to try out the filter settings you’ve used here.

    For anyone interested in the specifics, the related bits in this script are “-interpolate bicubic -filter Lagrange” and “-unsharp”. There’s a big list of the “interpolate” and “filter” parameters in the docs, and there’s also a thorough visual breakdown here: http://www.imagemagick.org/Usage/resize/#filter

    0
    • 23

      Thanks – as you can see from my script, I settled down with -interpolate bicubic -filter Lagrange and unsharp as well, through trial and error. I did not want to make things scarier describing all this stuff ;-)

      0
  15. 24

    Every version of Fireworks has this built right in. And many more, look under the File menu for “Batch”.

    You can make your own batch by right clicking your history, but it already has many batch commands already there, with a nice graphical interface to customize each job. For instance the size and image quality settings for the images you wish to re-size.

    If your designing graphics for the web you NEED Fireworks. If you have always used PhotoShop learn Fireworks and save massive amounts of time.

    0
  16. 25

    When I need to resize multiply images I simply write Bash script directly to terminal like this:

    for IMAGE in *.jpg; do convert IMAGE -resize 800×600 -sharpen 1×1 temp_path/IMAGE; done;

    And thats it.

    0
  17. 26

    Photoshop can do this without any actions using File->Scripts->Image processor. Just choose input and output paths and it’s ready to go.

    0
    • 27

      That’s perfect for simple tasks. The bash script I provided is simple as well. The actual script I use does much more: signed copies, specific output filenames, even saving puzzle pieces for my online puzzles :-) So, for more complex work, bash wins. Don’t worry, I still use Photoshop 8 hours a day :-)

      0
  18. 28

    ImageMagick is a very powerful tool. I use it for scaling up JPG images for printing on canvas photoframes. I even get quite good results with scaling up low resolution images (i.e. Instagram, 612x612px) for digital print on 50x50cm canvas.

    The only thing it cannot do is output high-resolution, print-ready pdf-files. I do this by outputting a high-resolution TIFF first, and then convert it to PDF with libtiff.The result is perfectly!

    0
  19. 29

    Cool script.

    One possible change I would make is use the bc utility for the math function instead of python, but as you say it is installed pretty much every where.

    0
  20. 30

    Just want to mention Nconvert, another multiplatform commandline image tool from the XNView Developer
    http://www.xnview.com/en/nconvert.html
    http://www.xnview.com/wiki/index.php?title=NConvert_User_Guide

    0
  21. 31

    I might be missing something here, but why no one is mentioning Adobe’s Bridge, which come with each copy of any software or package from Aobe? You can do all this there and much more, very easily. Just go to tools > Photoshop > Image Processor.

    0
  22. 32

    My word, if only I had read this article two days ago rather than leaving it queued in Google Reader…

    Still at least I’ll now be able to improve the ImageMagick script I hacked together – thanks!

    0
  23. 33

    Great write-up.
    I was beginning to think I was the only web dev that used imagemagick, let alone bash and python.
    I used imageMagick with bash and perl once to create almost a thousand thumbnails for products for a Shopp driven eCommerce site.
    Plus, cool wallpapers.

    0
  24. 34

    Ok, awesome but one thing: how to use this script?

    What I really mean is: do I have to copy this script in every folder I have images to resize or i can run say
    “./script my_folder/” or something like that and it’ll automatically resize the files in that folder I specify?

    Thanks,
    Alex

    0
  25. 35

    One can’t simply re-create Photoshop’s graphics engine. I’ve experienced it on a few levels and the image quality is pretty terrible. Oversharpening, blurring, lots of problems.

    I still use the PS actions. Not willing to lose quality at that level.

    0
  26. 36

    This imagemagick solution seems appropriate for this e-comm-site I’ve been working on lately (lots of images in lots of folders). My tool o choice tho is ‘fast image resizer’ due to its drag ‘n drop capability..

    0
  27. 37

    As long as you’re doing the math in python, why not go whole-hog and have the whole thing be a python script? Also, ruby would work well for this, too :-)

    0
  28. 39

    Hi,

    I would really be interested to see how to:

    create a for loop that will go through the current directory, changing all .pdf to .jpg while keeping the last name. In the same for loop I would like to change converted image into 3 different sizes and append the file size to the end of each image.

    the result should be “img_480.jpg”

    This is what I have so far:
    ext=”.pdf”
    target=”jpg”

    for i in *.pdf
    do
    base=$(basename $i $ext)
    convert -resize 2325×2475! -quality 10 $i $base.$target
    done

    Thank you,
    Thor

    0
    • 40

      Hello All,
      First of all, Thanks Vlad for your wonderfull artwork, I have many of your works and use them for my Wallpaper.
      I have been looking for a script like this for a long time and finally found it (I think). I am having a problem running the script though. I setup the script and enter through all the questions, then the scripts acts as if it is working and I can see the tmp file but the script errors out with this: convert.im6: unable to open image `/home/patrick/Pictures/Backgrounds/Resized/1600×900.jpg’: No such file or directory @ error/blob.c/OpenBlob/2638. Any suggestions would be greatly appreciated. I probably have set something wrong but have tried a few different things and it still doesn’t work. Not an expert with these things, sorry.

      Cheers

      0

Leave a Comment

Yay! You've decided to leave a comment. That's fantastic! Please keep in mind that comments are moderated and rel="nofollow" is in use. So, please do not use a spammy keyword or a domain as your name, or else it will be deleted. Let's have a personal and meaningful conversation instead. Thanks for dropping by!

↑ Back to top