Writing a GNOME thumbnailer

How does GNOME generate thumbnails for files? It uses a collection of programs called thumbnailers, each one generating thumbnails for a specific set of content-types of files. For example, totem-video-thumbnailer generates thumbnails for video files using GStreamer; evince-thumbnailer generates thumbnails for PDFs and other document files.

To generate a thumbnail, an appropriate thumbnailer program is selected then executed, passing it the path of the file to thumbnail, plus a path to write the thumbnail image to. If thumbnailing succeeds, the thumbnailer should have written the image to disk before terminating; but if thumbnailing fails, no image should be written, and the thumbnailer should return a non-zero exit status.

Thumbnailers are chosen by examining a series of .thumbnailer files in $PREFIX/share/thumbnailers. Each is in a simple key-file format:

[Thumbnailer Entry]
TryExec=evince-thumbnailer
Exec=evince-thumbnailer -s %s %u %o
MimeType=application/pdf;application/x-bzpdf;application/x-gzpdf;

The .thumbnailer format supports three keys:

  • TryExec: Optional. The name of the the thumbnailer program in the current $PATH. This allows the calling code to quickly check whether the thumbnailer exists before trying to execute it.
  • Exec: Required. The command to execute the thumbnailer. It supports a few different parameters which are replaced before calling the thumbnailer: %u is the URI of the file being thumbnailed; %i is its filename; %o is the filename of the image file to be written to; %s is the maximum desired size of the thumbnail image (in pixels); and %% is a literal percent character.
  • MimeType: Required. A semicolon-separated list of MIME types which the thumbnailer supports generating thumbnails for.

So in the evince-thumbnailer file above, the command passes the requested thumbnail size, then the input file’s URI, then the path for the output image file to evince-thumbnailer.

The code to examine and call a thumbnailer is in gnome-common’s GnomeDesktopThumbnailFactory class, which handles looking up the right thumbnailer script, building and executing the command for it, and loading the resulting thumbnail image into a GdkPixbuf.

Thumbnail caching is supported by GnomeDesktopThumbnailFactory. When calling a thumbnailer, the path passed for the output image file is in ~/.cache/thumbnails/$SIZE/. The cached image file is given a (probably) unique filename, generated by hashing the original file’s URI, so the thumbnail can be looked up in future. gnome-desktop supports two sizes of thumbnails: ‘normal’ and ‘large’. Normal thumbnails are up to 128×128 pixels, whereas large thumbnails are up to 256×256 pixels. Thumbnails which are larger than this are scaled down before being cached, and non-square thumbnails are scaled so their largest dimension is at most 128 or 256 pixels.

gnome-desktop also handles failed thumbnails. If a thumbnailer can’t generate a thumbnail for a file (e.g. because the file is corrupt or because the right video codecs aren’t available), it returns a non-zero exit status. gnome-desktop then writes an entry to ~/.cache/thumbnails/fail/gnome-thumbnail-factory/ which is named after the hash of the input file URI (just like a successful cached thumbnail). For future queries for thumbnails for that file, GnomeDesktopThumbnailFactory can immediately return an error after looking up the fail entry.

If a file changes content, GnomeDesktopThumbnailFactory knows to generate a new thumbnail because each cached image has associated metadata (stored as PNG tEXt keys) storing the full URI of the thumbnailed file (to check for hash collisions) and its last modification time at the point of thumbnailing. If the stored modification time doesn’t match the file’s current one, a new thumbnail is generated.

I don’t care. Show me the code.

As an example of this, I present gnome-directory-thumbnailer, which generates thumbnails for directories (which is possible with a few small fixes to gnome-desktop). I wrote this as part of a project for my new employer, Collabora. It generates a thumbnail for a directory by heuristically choosing its ‘most interesting’ file (or subdirectory) and taking the thumbnail from that. It works fairly well for generic directories, but there’s great scope for improving the heuristics to cater for directories which match different templates (e.g. a directory of audio files for an album; a directory containing an automake project; a mounted DVD directory; etc.).

Nautilus showing some album directories.

Nautilus showing some album directories.

The code is in gnome-directory-thumbnailer on git.gnome.org and it’s in the process of getting a gnome-directory-thumbnailer product on bugzilla.gnome.org, so please file bugs there. Note that you’ll need the latest release (3.10.1) of gnome-desktop for it to work correctly in Nautilus.

If you want to write your own thumbnailer, a good place to start is with the gnome-thumbnailer-skeleton by Bastien Nocera. It provides the generic wrapper code for command line parsing and output handling which would otherwise get rewritten for each new thumbnailer.

There are actually other ways of generating thumbnails, such as the Tumbler thumbnailing system which is accessed via D-Bus and implements the proposed thumbnailer specification which is used by Rygel. As far as I’m aware, Nautilus doesn’t use D-Bus thumbnailers.

5 thoughts on “Writing a GNOME thumbnailer

  1. Matthew Barnes

    Nice, I hadn't heard of tumbler before. For several years now, Evolution has been using gnome-desktop to generate its own thumbnails for attachments while waiting eagerly for someone... anyone... to implement the D-Bus thumbnailing spec. I would happily trade our gnome-desktop dependency for tumbler. Maybe that would help force the issue for GNOME.

  2. Leif Gruenwoldt

    Very cool!

    Years back (GNOME 2.x era) I wanted to apply movie poster thumbnails to a folder of my video files. I struggled with this. Maybe I was looking in the wrong area, but at the time my conclusion was there no way for to apply custom thumbnails without forking Nautilus 🙂

  3. Stuart Axon

    Nice 🙂

    I had a play with using gnumeric, abiword + open office to thumbnail documents.. it looked quite nice, but obviously was a bit heavy!

    Last time I checked, ubuntu seemed to disable a whole bunch of thumbnailers for security reasons (like for pdf), + it was a bit of a pain to enable them. Also, getting network drives thumbnailed was a bit of a pain on that OS too.

  4. Philip Van Hoof

    Hey Matthew Barnes, the history of it is that it was first made for the N900's Maemo thumbnailer 'hildon-thumbnail' (https://maemo.gitorious.org/maemo-af/hildon-thumbnail). later Jannis Pohlmann reimplemented that software for XFCE as Tumbler (http://git.xfce.org/xfce/tumbler) and since we preferred to work with upstream open source projects instead of internal Nokia projects, we adopted Tumbler on MeeGo Harmattan for the N9's thumbnailing needs (after having made several adaptations which are managed here (https://maemo.gitorious.org/maemo-af/tumbler). For a specialized thumbnailer implementation, you can take a look at the Maemo Video Thumbnailer available here: https://maemo.gitorious.org/maemo-af/maemo-video-thumbnailer . All that code should also run on standard GNOME desktops. I don't really know why the GNOME desktop world never adopted it, as it would indeed greatly help softwares like Evolution with thumbnailing. I recall that the Banshee team was also interested in doing music-piece thumbnailing with it at some point.

Comments are closed.