Imagemagick Montage Contact Sheets

I had originally written a blog post about this back in 2013. It’s now 2016 and I’m still doing this when I need to quickly generate a contact sheet of images in a directory - so I thought I’d migrate the notes in that old blog post over to here for a) visibility and b) to offload this from my aging brain…

I’ll usually end up with a directory of images that I will occasionally want to see an overview of (for various reasons). It’s just how I’m accustomed to choosing images from a strip I guess…

So, if you need a quick contact sheet view of all of the images in a directory, I submit for your consideration, Imagemagick’s montage that I will use:

$ montage -verbose -label '%f' -pointsize 14 \
  -background 'black' \
  -fill 'gray' \
  -define jpeg:size=300x300 \
  -geometry 300x300+2+2 \
  -auto-orient
  P12801{00..90}.jpg \
  OUTPUT.png

A quick run-down for anyone not familiar with montage:

  • -verbose
    should be self-explanatory.

  • -label '%f'
    Label the thumbnails with the filename.

  • -pointsize 14
    Set the font size to 14 pts.

  • -background 'black' -fill 'gray'
    set the background and foreground fill (text) colors

  • -define jpeg:size=300x300
    This one is neat. It turns out that if you simply call the montage command without it, it will load up the full-sized jpeg into memory. All of them. With a large list, this may quickly choke available memory. This option generates at least a 300x300 version of the image and holds that in memory instead. It makes the command much faster.

  • -geometry 300x300+2+2
    This simply says to make each thumbnail 300px on it’s longest size, and pad it with 2px all around.

  • -auto-orient
    Auto-rotate the image according to exif orientation.

  • P12801{00..90}.jpg
    This is a neat shell expansion trick that will fill in the sequence of values for me between 00 and 99. Essentially providing: P1280100.jpg P1280101.jpg P1280102.jpg .... This won’t work on windows, use a glob instead (P12801*.jpg).

  • OUTPUT.png
    The filename for the output.

Not sure if this will help anyone out but figured it couldn’t hurt to post this here… :slight_smile:

[edit]
Almost forgot, here’s an example contact sheet I made using this command:

2 Likes

Hello Pat, that works well and is very fast indeed. That downsize trick is a good one, when I do this in G’MIC with say 30 JPG’s, it crashes after a while. (No doubt there’s a solution for that with a resize at the beginning of a script).

For who’s interested, the -label field can be extended with some exif info:
-label ‘f - f/[EXIF:FNumber] - %[EXIF:ExposureTime]s’

gives dsc_1000.jpg - f/56/10 - 10/400s.
some more exif tags (iso, gps) on the ImageMagick site.

Anyone knows how to recalculate those last two values into 5.6 and 1/40, so that it says f/5.6 - 1/40s?

3 Likes

Ah, that’s right about the other fields. I normally only care about filenames personally, but thank you for getting that extended exif info in there, I’m sure others will find it super-useful. :slight_smile:

1 Like

@patdavid, I have used your older blog post for generating contact sheets (I used it to compare the effect of film simulation preset overall on a collection of images) and it was painfully slow, so thanks for the size thing!

1 Like

If you put this into a script and changed P12801{00..90}.jpgto $1 so that you could pass the files names as a parameter, would P12801{00..90}.jpg still expand?

Assuming you’re using Bash…

In that case it’s better if you don’t use P12801{00..90}.jpg \ at all, and instead rely on "$@" and then use the script not from command-line which can be cumbersome, but from a graphical file manager. E.g. make a selection of image files in Dolphin of Thunar or PCMan or whatever file manager you use, then right-click on them and “Open with” the script.

To get you started, you are interested in parameter expansion, specifically "$@"
http://mywiki.wooledge.org/BashGuide/Parameters
http://wiki.bash-hackers.org/syntax/pe

This script:

#!/usr/bin/env bash
printf '%s\n' "$@"

for f in "$@"; do
    printf "%s\n" "$f"
done

which I saved as /tmp/foo and set chmod +x /tmp/foo, will print the same list of input files twice:

/tmp/foo "image 1.tif" "image 2.jpg" "image 7.png"
image 1.tif
image 2.jpg
image 7.png
image 1.tif
image 2.jpg
image 7.png

The for loop lets you do things to each positional parameter on the fly.

1 Like

I think you’d have to do what @Morgan_Hardwood suggest and use “$@”. From his link:

“$@” - Expands to all the words of all the positional parameters. Double quoted, it expands to a list of them all as individual words.

That might be able to be passed to montage directly that way. So replacing P12801{00..90}.jpg with "$@" should expand what is passed - then work the rest of the way as indicated by @Morgan_Hardwood.

@patdavid I fixed a typo in the code in your message, hope you don’t mind.

1 Like

Awesome, I’ll give that a shot and if I can get it to work, I’ll add it to the github repo.

1 Like