Custom thumbnail generators for audio waveforms and GIMP XCF files

I recently packaged these 3D thumbnailers for Arch Linux and this act inspired me to dig into this topic a bit and make some of my own. First off, what’s a “thumbnailer”? It related to this Free Desktop specification and I’d summarise it as:

A thumbnailer is a program that can generate a small preview image (called “thumbnail”) of a specific file type. File browsers know about thumbnailers by reading configuration from .thumbnailer files which specify which program to call for a specific MIME type, and which arguments to use to get the desired output.

For more details and practical examples of what these files look like and what you can do with them, see this blog post by Radu Zaharia. For most of the 3D thumbnailers I packaged, the thumbnailer programs are small purpose-built scripts, written in Python or Bash, that understand the specified format and how to get a PNG image out of it. The thumbnailer config just specified which order it wants its file input and output arguments in. However, as Radu’s blog post points out these can also be more advanced one-liners using programs you already have installed, so I decided to try that out and this post I’ll cover 2 such examples: Audio & GIMP.

tl;dr: Copy-pastable version at the end of the post

Audio

I picked these formats because I have many such files locally but there’s no preview available and I couldn’t find any working thumbnailers for them in the wild. As in, I found some, but they didn’t work. There’s already a thumbnailer installed with GNOME’s Totem video player that I suppose is meant use album art as the thumbnail but it doesn’t seem to do anything. Or maybe that’s what’s responsible for making all audio files look like a music note:

a screenshot of OGG sound effect files in a file browser all looking the same

sound files all look like a musical note

Anyway I thought it’d be cool if the thumbnail would be a visual representation of the shape of the sound in the file. I knew this should be possible because last year I added a spectrum analyzer effect to a music video using GUI video editing software, but how do you do something like that automatically from the command line? Well, as it turns out, ffmpeg can do it.

This tool never ceases to surprise me. Its intended purpose is for converting audio/video from one format to another, e.g. FLAC → OGG but it can do so much more. For a few years now this is what I use to convert screencasts to gifs and now it turns out it can generate PNG waveform images too! Based off this wonderfully detailed Stackoverflow answer I wrote this:

ffmpeg -i %i \
    -f lavfi \
    -i color=c=black:s=%sx%s \
    -filter_complex "[0:a]showwavespic=s=%sx%s:colors=white[fg];[1:v][fg]overlay=format=auto" \
    -frames:v 1 \
    %o

Here %sx%s is specifying the input height twice for both width and height of the black background square, and also for the waveform drawn with the showwavespic filter. It draws a white waveform on a black background and that’s it. See the ffmpeg docs on Waveform images for more details on how to use the tool.

I looked in the list of MIME types in /etc/mime.types for audio formats I thought these thumbnails would be useful for and the resulting thumbnailer configuration looks like this:

[Thumbnailer Entry]
TryExec=ffmpeg
Exec=ffmpeg -i %i -f lavfi -i color=c=black:s=%sx%s -filter_complex "[0:a]showwavespic=s=%sx%s:colors=white[fg];[1:v][fg]overlay=format=auto" -frames:v 1 %o
MimeType=audio/ogg;audio/mpeg;audio/x-wav;

The TryExec line checks you have ffmpeg available before trying to run the command.

For some reason this seems to only generate thumbnails for .mp3 files and not for other file types I listed like OGG and WAV and I’m not sure why because I’m not seeing failed thumbnails. If I had to guess, it might be that another thumbnailer is handling them with higher priority but not outputting anything interesting. If you have a clue for what I can do to fix this please let me know.

some example waveform thumbnails generated for music and sound effects files

some example waveform thumbnails generated for music and sound effects files

One unexpected advantage of this thumbnailing approaching is you can tell if two obscurely named files have the same or similar content just by glancing at them! Before this I had to open them up and listen to them to tell. How convenient.

GIMP

This one’s going to be a bit more long-winded because it involved multiple attempts. Searching AUR I found gnome-xcf-thumbnailer, a package probably originally from Ubuntu but that I can’t find an online, browsable source repo or issue tracker for and it doesn’t seem to have been updated in a while. You run it like this:

gnome-xcf-thumbnailer ~/Documents/sample.xcf sample.png

But it gives you this error:

Warning: XCF version 11 not supported (trying anyway...)
$0: This can't happen (unknown out_color_mode)

The error message “this can’t happen” was suspicious to me. It looks like something a programmer might assert according to a specification or even just an assumption. I checked the code and indeed there’s a switch-case of several possible color modes and the last “default” case is what gives this message:

switch( flatspec.out_color_mode ) {
case COLOR_GRAY:
    // ...
case COLOR_RGB:
    // ...
case COLOR_INDEXED:
    // ...
default:
    FatalUnexpected("This can't happen (unknown out_color_mode)");
}

So even though my XCF file is using RGB mode the library this program uses is not recognising it as such. It’s potentially fixable but it requires domain-specific knowledge on the XCF format and the program did warn on startup that it doesn’t support this version. Oh well, let’s try something else.

There’s another relevant-looking package called xcftools and because it’s in the Extra repository and not in AUR it might be more up-to-date and working as expected. It contains a program called xcf2png, fantastic, this looks like exactly what I’m looking for! You use it like this:

xcf2png ~/Documents/sample.xcf -o sample.png

and the program says:

Warning: XCF version 11 not supported (trying anyway...)

Suspiciously similar error to the other one. Which makes sense, it turns out the other program is also using the xcftools lib internally. There’s no error but the result is a transparent empty png, as shown below:

a screenshot of a correctly sized but otherwise empty, transparent image

a screenshot of a correctly sized but otherwise empty, transparent image, all it shows is the greyscale checkerboard used to indicate transparency but this output PNG has the exact same dimensions as the input XCF it was generated from

Never mind, let’s see what else is possible. Someone’s already asked how to convert XCF to PNG on Stackoverflow, great, but unfortunately the accepted answer from 2011 uses exactly this xcf2png program that doesn’t work any more. Other answers suggest writing a short GIMP script or using imagemagick. I haven’t written anything in Scheme before but there’s a code snippet in the answer so a GIMP script could be a good plan B. On the other hand I already know and like imagemagick, so even though other comments say “ImageMagick’s XCF support is seriously broken” I thought I’d try this first, in case it works.

Based off of this extended answer I wrote this:

convert %i -alpha on -background none -flatten -resize x%s %o

I added -resize to set the output image’s height using the %s (size) argument. ImageMagick resize arguments are formatted like WxH so if you only have height you omit the width, e.g. for 200px it’d be -resize x200.

One weird, annoying thing was that although -layers merge merges layers into one layer at the end, the resizing happens first and only applies to the lowest layer, all the others stay at the original size :facepalm: Anyway this “merge” approach might be deprecated, and there’s another flag -flatten that does exactly what’s expected, so I used that instead. Now we get the appropriate sized PNG with all layers flattened into one before resizing.

I couldn’t find XCF mentioned in /etc/mime.types but the gimp.desktop file in /usr/share/applications/ mentions image/x-xcf and image/x-compressed-xcf so the final thumbnailer configuration I put together looks like this:

[Thumbnailer Entry]
TryExec=convert
MimeType=image/x-xcf;image/x-compressed-xcf;
Exec=convert %i -alpha on -background none -flatten -resize x%s %o
a comparison of a thumbnail for a JPG file and for the XCF file it was exported from, they both look the same

a comparison of a thumbnail for a JPG file and for the XCF file it was exported from, they both look the same

It works like a charm. I was worried that this would run slowly with multiple files but once the resizing was added it generates the thumbnails in an instant!


Altogether, to get GIMP XCF thumbnails and waveform thumbnails for audio, place these two files in /usr/share/thumbnailers:

#/usr/share/thumbnailers/xcf.thumbnailer
[Thumbnailer Entry]
TryExec=convert
MimeType=image/x-xcf;image/x-compressed-xcf;
Exec=convert %i -alpha on -background none -flatten -resize x%s %o
#/usr/share/thumbnailers/audio.thumbnailer
[Thumbnailer Entry]
TryExec=ffmpeg
Exec=ffmpeg -i %i -f lavfi -i color=c=black:s=%sx%s -filter_complex "[0:a]showwavespic=s=%sx%s:colors=white[fg];[1:v][fg]overlay=format=auto" -frames:v 1 %o
MimeType=audio/ogg;audio/mpeg;audio/x-wav;

These work fine for me so I’m unlikely to tweak them more but if you have questions or suggestions then don’t hesitate to get in touch and for a detailed and softer introduction on how to use these configurations please see this external post: Custom thumbnails for unknown formats in Gnome.