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.


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


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

Mirror - Flip And Flop

Sometimes you get an image and you know that for whatever reason, it has been scaled on the X axis by -1. To put that right use the -flop option of convert, no option argument needed. The matching -flip works on the vertical axis but that seems a lot less useful to me in real life.


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.

The case where cropping most naturally comes in handy is when trying to isolate a section of an image. Perhaps you have a series of video frames and you only want the part that is looking out a car window above the hood or something. To do this you can start by interactively determining the region of interest. Use xwininfo and then click the display (maybe feh or eog or display) and it will tell you a lot including the "window ID". Now you use xev -id 0x3a00005. Then when you mouse around the image in the display program, you’ll get coordinate display of the pointer. Once you’ve figured out just what you need, you can use something like this.

$ import -window 0x3a00005 -crop 250x125+387+321 subimg.png

This will extract a 250x125 part of the window and if the window is 1024x768, it will be centered.

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

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


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.


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. '

Maybe you need to annotate an image or some video frames with a reference grid or marker. See the next section for some tips on that.


ImageMagick can do much fancier things. For example, if you need some lines superimposed over an image. In this example, I wanted some lines superimposed over some dashcam lane lines (red on the port side, green on starboard). I also wanted to crop so just the road was visible.

for F in *jpg ; do
    convert -stroke red -strokewidth 5 \
    -draw "line 480,970 890,750" \
    -stroke green \
    -draw "line 1395,970 1040,735" \
    -crop 1920x300+0+675 ${F} lines-${F}


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


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

Here’s how I made a video of two sets of images shown side by side.

for N in {0001..2509}; do
    echo $N; montage -geometry 350x350 /tmp/r112/radar-${N}.png r512/radar-${N}.png radars-${N}.png;

The original image sizes here were 350x350 and the montage is 700x350.