ImageMagick is a suite of utterly inscrutable programs designed to provide the ability to perform almost any kind of image manipulation that can be done programmatically, i.e. without live human visual interaction. This can be huge help for many tasks. Imagine making thousands of thumbnails or proofsheets from a huge catalog of images. Perhaps you need to standardize sizes for web consistency. Maybe you want to use uploaded images but have them be black and white. The problem with ImageMagick is the very challenging syntax which is not helped much by the light-duty man pages. Also it is split among a handful of different executables. Despite less than thorough man pages, there is excellent on-line documentation with visual examples. Here are some notes for operations I have done.

Identify

ImageMagick is very handy for finding out properties of image files. Often viewers scale images up or down and it’s hard to tell what you really have. The identify program cuts through the mystery and gives you the solid truth about an image.

$ identify xed.jpg
xed.jpg JPEG 420x236 420x236+0+0 8-bit DirectClass 24.1kb

Or if you need more detailed info.

$ identify -verbose xed.png | sed 11q
Image: xed.png
  Format: PNG (Portable Network Graphics)
  Class: DirectClass
  Geometry: 886x498+0+0
  Resolution: 28.34x28.34
  Print size: 31.2632x17.5723
  Units: PixelsPerCentimeter
  Type: TrueColor
  Endianess: Undefined
  Colorspace: sRGB
  Depth: 8-bit

Format Conversion

One of the most important executables in the ImageMagick suite is called convert and as you might expect one of its primary functions is to convert images from one type to another.

$ convert xed.gif xed.png
$ identify xed.*
xed.gif GIF 257x198 257x198+0+0 8-bit PseudoClass 2c 1.33kb
xed.png[1] PNG 257x198 257x198+0+0 8-bit PseudoClass 2c 1.04kb

Resize

Perhaps the most common application for ImageMagick that I have is resizing images. If I’m giving a presentation and I need a graphic to be something convenient for that, I will usually look for a large sized image (>1000pixels) and then resize it. This is the general technique:

convert -geometry 400x400 wrongsize.jpg correctsize.jpg

I wish I knew how exactly the -geometry specification worked but if you use something like 400x400 then the maximum dimension, in X or Y, will be 400 with the other scaled to preserve the aspect ratio.

The official manual says, "Geometry is a very special option. The operator behaves slightly differently in every IM command, and often in special and magical ways." Great.

Another way to resize images that could be useful if you knew what percent of the original size you wanted.

convert xed.png -resize 50% half_xed.png

Crop

The official web help is helpful. Cropping is a bit weird and like many other aspects of ImageMagick, there is much about it I do not understand.

Imagine that you have two images that need to be the same size. They are the same width but one is taller than the other. The taller one has a bunch of sky in the top portion and it can be made the same height as the other by cropping off the top. First check the images with identify to see exactly what needs to be done.

$ identify ok.jpg tall.png
ok.jpg JPEG 420x236 420x236+0+0 8-bit DirectClass 24.1kb
tall.png[1] PNG 420x320 420x320+0+0 8-bit PseudoClass 256c 103kb

The tall one is 84 pixels taller than the ok one. It needs the top 84 pixel rows cropped off. This is done with the following.

$ convert -crop 420x236+0+84 tall.png tall.jpg
$ identify ok.jpg tall.jpg
ok.jpg JPEG 420x236 420x236+0+0 8-bit DirectClass 24.1kb
tall.jpg[1] JPEG 420x236 420x236+0+0 8-bit PseudoClass 256c 26.7kb

Note that this converted to jpg at the same time. ImageMagick tends to need a source and target name even if they are both the same file.

Here is an example of where I wanted to cut off the bottom 7 pixels off of an image.

$ identify bomb+caption.jpg
bomb+caption.jpg JPEG 338x217 338x217+0+0 8-bit DirectClass 30.1kb
$ convert -crop 338x210+0-7 bomb+caption.jpg bomb.jpg
$ identify bomb+caption.jpg bomb.jpg
bomb.jpg JPEG 338x210 338x210+0+0 8-bit PseudoClass 256c 33.8kb

Borders

ImageMagick does a good job of quickly putting borders around images. Here’s an example that puts a red border around an image where the border on the left and right is 10 pixels and the border on the top an bottom is 5 pixes.

$ convert  -bordercolor '#ce0000' -border 10x5 xed.png xed.png

Backgrounds For Transparent Images

Since the border feature actually creates a separate image of the border and then overlays it, you can use this to provide a background for transparent PNGs and GIFs and other formats that possibly have transparent backgrounds. I find this most useful when exporting to a bitmap from Inkscape. In Inkscape, everything looks fine, but when you go to a browser or viewer, it turns out that the lack of background is quite annoying. You could put a big white rectangle at the lowest level of your Inkscape vector model before exporting, but this fix from ImageMagick may be easier since all of your images can be done in one quick operation.

$ convert -border 0 -bordercolor white xed.png xed.png

Import

Imagemagick is good at doing screen captures. I prefer it to fancy GUI things because it can be properly scripted and controlled.

Find the window ID with xwininfo.

$ WID="0x3200097"
$ import -window ${WID} +frame mylilscreen.png

Also for the whole screen use something like this.

$ import -window root wholescreen.png

Note that this just captures the first monitor.

Annotate

Remember how YouTube used to have those little text overlays you could add? Then people started using them only for obnoxious advertising. Well, I used them so that my videos didn’t need a stupid obnoxious sound track (I could explain in text the important things). I’ve been looking for a way to get that functionality back and I think that ImageMagick can do it.

Check the annotate features.

Here is an example of putting a caption on a video frame before assembling it.

convert frame-0342.png -fill white -undercolor '#00000080' -gravity South
-pointsize 40 -annotate +0+25 ' Note the space padding here. '
frame2-0342.png

Montage

If you work with sets of images it can be nice to have a way to visualize the whole collection at a glance. A "montage" is an image composed of a grid of other images. Here are settings I use the most.

montage -background '#cecece' -geometry 64x48+1+1 src-*.jpg montage.jpg

Note that the geometry will control the geometry of the inset images. The +1+1 component of the geometry specification controls how much padding there is around the images. Other options of interest.

  • -label %f - Add the file name as a label to each sub image.

  • -stroke '#ff0000' - Color of label text. Also a -fill color might be needed with big text.

  • -frame 3 - Add 3 pixel shaded borders to each sub image.

  • -mattecolor '#ff0000' - Color of the frame.

  • -border 3 - Similar to -frame but less decorative.

  • -shadow - Adds a fancy shadow for each sub image.

  • -tile ${COL}x${ROW} - Organize the grid of images yourself.

  • -tile ${COL}x - As many rows as needed.

  • -tile x${ROW} - As many columns as needed.

  • null: - Use this as an image name in a place where you want blank.

Full official details on montage.

Here’s an example.

montage -tile 4x -geometry 168x94 tn*.jpg vidmon.jpg

Montage Example