Add a drop shadow to images from the command-line with ImageMagick

Today I finally figured out how to add a drop shadow to an image from the command-line. As you might expect, the solution uses ImageMagick. This is one of those command-line tools that makes you wonder how people survive out there in the cold world of the GUI alone. You can do pretty much anything to an image with one or more ImageMagick commands.

Some tasks, like resizing, are irresponsibly easy. But for other tasks, (say, a drop shadow) the learning curve can be more of a wall.

I had glanced at ImageMagick for drop shadows before, and shied away. But today, I had a whole bunch of drop shadows to do, and I just didn't want to click around in GIMP. With a little searching, I found this:

$ convert image.png \( +clone  -background black  -shadow 80x3+5+5 \) \ 
+swap -background none -layers merge +repage image-shadowed.png

Isn't that beautiful?

Right. Now I know how clients feel when I show them CSS. I have no idea how that code works. The ImageMagick site, carefully read, will either require or eventually confer an M.A. in graphic craftsmanship. For now, I do know this:

  • You can change the background color black to another color, of course.

  • You do not have to set the 80x3 to the size of the image. Leave it alone. It works.

  • If you want to add the shadow to the actual image, use the original name at the end (instead of image-shadowed.png). Normally you'd use mogrify to alter the input image, but the parenthetical cloning action will break if you try that here.

Here is a short, not very robust bash script, which you may enjoy using and improving. (Typing out the original command in full every time may slightly reduce the efficiency gains we're after here.)

#!/bin/bash
# im-drop-shadow.sh
# Apply a drop shadow using imagemagick.
# For more arcana, see: http://www.imagemagick.org/Usage/blur/#shadow
 
if [ $# != 1 ] ; then echo "Usage: $0 IMAGEFILE" ; exit; fi 
 
FIN=$1
FOUT=$(echo $1 | sed -e 's/.\(jpg\|jpeg\|png\|tif\)$//i')-shadow.$(echo $1 | sed -e 's/.*.\(jpg\|jpeg\|png\|tif\)$/\1/i')
 
#Uncomment the next line if you want to "mogrify" the input file.
#FOUT=$FIN
 
# Change this viewer if you don't have gpicview on your system.
VIEWER=gpicview
 
convert $FIN \( +clone  -background black  -shadow 80x3+5+5 \) +swap -background none -layers merge +repage $FOUT
echo "Added shadow to: $FOUT"
$VIEWER $FOUT

Using it is pretty easy:

$ im-drop-shadow.sh image.png

That will output a shadowed file to image-shadow.png, and display it using $VIEWER.

You could do a whole directory like this:

for i in *.png
do
   im-drop-shadow.sh $i
done

(Although if you're churning through a pile of files, you might want to comment out the $VIEWER line.)

Anyhow, that's how you add a drop shadow from the command-line. One less thing to fire up GIMP for.