March 30, 2005

ImageMagick: A graphics wizard for the command line

Author: Preston St. Pierre

For many a GNU/Linux user, the command line is supreme. But can you manipulate images without switching to the GUI and using the resource-hungry GIMP? You can, using the fantastic ImageMagick suite.

With ImageMagick (IM) you can crop your image, change its shades and colors, and add captions, among other operations.

Basic image manipulations

IM packs a nifty utility, convert, that can handle this. In addition to changing the size of an image, convert can convert it from one format to another (IM supports almost 90 different image formats), rotate an image, and add effects to an image.

To convert one image into a thumbnail for my blog, I ran the command convert -sample 80x60 big.jpg thumb.jpg. Here, big.jpg is the input image and thumb.jpg is the output image, which is to be 80x60 pixels. -sample tells IM to scale the image using pixel sampling. You can also specify percentages instead of pixels by using syntax such as convert -sample 30%x30% big.jpg thumb.jpg. ImageMagick maintains the aspect ratio of an image, which results in symmetric images.

Convert can also rotate or flip an image:

convert -rotate 90 image_0001.tiff output.tiff

The -rotate switch, by default, rotates the image clockwise by the number of degrees specified. If you wish to rotate the image counter-clockwise, use a negative number.

The -flip switch produces an upside-down image of the original while the -flop switch turns the image on a vertical axis.

convert -flip me.jpg me_flipped.jpg
convert -flop me.jpg me_flopped.jpg

You can change a JPG file to PNG with a command such as convert one.jpg newone.png. If you have a huge collection of images to convert, use IM's mogrify utility with the -format switch:

mogrify -format tiff *.png

You can also use mogrify to create same-sized thumbnails of multiple images:

mogrify -sample 80x60 *.jpg

Be careful, however -- this command will overwrite your existing images! If you wish to preserve the originals, you have to use a different format for the thumbnails. For instance, this command would make PNG thumbnails of all your JPG files:

mogrify -format png -sample 15%x15% *.jpg

Adding other effects to an image

Among its many options, convert offers artistic effects to enhance your images, including charcoal, colorize, implode, solarize, and more. I find the charcoal effect really cool; it looks like an artist's initial draft, with no colors, just a sketch made with charcoal. To apply the effect, use a command such as:

convert -charcoal 1 me.png coal.png

The numeric value specified refers to the amount of charcoal you want in the image.

Playing with PDFs

Now imagine you're traveling, and you want to share some photos with your friends. Your mail client may allow large attachments, but how many attachments do you really want to send? The convert utility lets you to put all your images into one neatly organized PDF file, one image per page, with a command such as:

convert *jpg allinone.pdf

Convert also lets you extract all the images from a PDF file:

convert allinone.pdf image_%04d.tiff

The %d operator is a format specifier, much like the printf format specifier in C language. %d means a decimal number, and the 0 that follows it means you want leading zeroes in the file name. The 4 after the 0 specifies how many digits the total value should use. So, %04d means that you want leading zeroes and the total number of digits should be four, thus creating files named image_0001.tiff, image_0002.tiff, and so on.

You can also run the command without the %d operator; convert will automatically append unique numbers to the filename.

convert allinone.pdf img.png
ls img*
img.png.0 img.png.1 img.png.2

Adding text

If you're a prolific digital photographer, how do you distinguish one set of images from another? One good way is to put a tag on all the images -- a word or two describing where and when they were snapped.

I labeled a few picture from a recent trip to Bangalore using convert:

convert -font helvetica -fill yellow -pointsize 25 \
> -draw 'text 100,250 "Nandi Hills, Bangalore"' \
> image.png text.png

This command specifies the font, color, and size of the text, its location (specified by the column and row in pixels where text should begin), and the actual text itself. You can add text at two different locations in different colors like so:

convert -font helvetica -fill yellow -pointsize 36 \
> -draw 'text 100,250 "Nandi Hills, Bangalore"' \
> -fill green -draw 'text 150,300 Beautiful' \
> image.png text.png

Notice the variations in quotes. Use double quotes when you need to draw more than one word on your image. If you have only one word to write, you don't need to include it within double quotes.

You can specify different font sizes for the two texts, and, if the font you wish to use if it is in a non-standard directory, you can include the path to the font in the command as well.

Frames for your images

Frames and borders help enhance images and make them more appealing. To add a simple solid-colored frame around your image, use a command such as:

convert -bordercolor blue -border 5x5 pic001.png border001.png

In the size specification (5x5), the horizontal size comes first and then the vertical. You can't make a frame larger than the picture, and you must specify the border color. You can check the complete list of colors IM supports for border, text, and backgrounds with the command convert -list color.

I like frames with raised and lowered borders. To create a raised border, use the -raise option along with the dimensions:

convert -raise 5x5 image.png raised.png

To create a lowered border, replace the hyphen before the raise argument with a plus-sign.

For more complex frames with padded borders, you can use the -mattecolor and the -frame options in place of -bordercolor and -border.


Being a command-line tool has its advantages. You can make all of the above mentioned modifications through scripts written using programming languages such as Perl, Python, and C/C++. ImageMagick also provides interfaces for various languages -- PerlMagick (Perl), Magick++ (C++), PythonMagick (Python), MagickWand (PHP), RMagcik (Ruby), TclMagick (Tcl) and JMagick (Java).

While all we've talked about has been command-line operations, IM also has a GUI which you can invoke with the command display.

Shashank Sharma is a computer science student who loves to write about free and open source software for new users.