Ariya Hidayat
Graphics Dojo
Posted by Ariya Hidayat
 in Graphics Dojo
 on Monday, January 26, 2009 @ 09:57

In this era of digital photography, thumbnail preview is probably one of the most important features in any photo management software. Imagine if you have to flip through thousands of pictures, without being able to see the thumbnail previews. It would be a complete waste of time. Ideally the thumbnail preview is taken from what is stored in those JPEGs. However, suppose that you want larger or smaller previews, how to do that? With Qt, we can utilize QImage::scaled() function:

QImage result = img.scaled(200, 150, Qt::IgnoreAspectRatio, Qt::FastTransformation);

This gives a very fast downscaling, however the result is perhaps not so satisfactory because the resizing is only using the nearest-neighborhood method. For extra filtering, use the following instead:

QImage result = img.scaled(200, 150, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);

Due to Qt::SmoothTransformation, the thumbnail has a better quality. The drawback is that it is very slow compared to the previous Qt::FastTransformation.

A trick known to almost every graphics programmer out there is this one:

QImage result = img.scaled(400, 300).scaled(200, 150, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);

The first scaling is using Qt::FastTransformation (we do not need to specify it explicity, it is the default) to twice our target size. This is of course very fast. The second scaling does some smoothing for the final result.

Another obvious and better alternative is of course:

QImage result = img.scaled(800, 600).scaled(200, 150, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);

which is essentially the same, only now we scale to four times the target size first.

So basically we “cheat” by not really scaling and filtering the whole image. This will speed up thumbnail generation process significantly. But don’t be surprised when I say that we can still make it even more faster. The trick? Use the previously discussed faster halfscaling method! The following chart shows the overall performance comparison (longer is better), take it with a grain of salt:

“Cheat scaling” is apparently very fast. This lies in the fact that it processes ARGB components at once (see the blog entry on fast image halfscaling) at the expense of less-precise low bits. The numbers represent the iterations for every 10e12 CPU ticks in order to resize a 10-megapixel image to 200×150 pixels. As you can see, the improvement is clearly obvious, though you may get less speed-up if the original and target size are not that extreme. You could probably push the performance further by falling back to processor-specific vector operations, e.g. SSE on modern Intel CPU.

How about the quality? Check the example at Graphics Dojo repository under the subdirectory thumbview. After building and running it, drag an image (from file manager or web browser) and drop it there. Please try a very big image, i.e. exercise the program with pictures from a fairly modern digital camera. The screenshot looks something this:

Press 1, 2, or 3 to change the scaling method for the bottom right image. To compare the quality between Qt::SmoothTransformation and cheat scaling method, you can flip using 2 and 3 quickly. Are you able to spot the difference? You’d be the judge!

Of course this cheat scaling method is not a silver bullet, nor it is a replacement for Qt::SmoothTransformation. For our specific case, namely creating a small preview of a very large, relatively patternless digital picture in ARGB32 format, the trick works well.

4 Responses to “Creating thumbnail preview”

» Posted by Carina Denkmann
 on Monday, January 26, 2009 @ 15:17

To improve loading speed for a JPEG image that does not have a stored thumbnail, you should look into libjpeg’s feature of scaled loading. I think the newest KDE JPEG thumbnailer does this. It basically gives you 1/2, 1/4, and 1/8 scaled images with smoothing already applied for free.

» Posted by ariya
 on Monday, January 26, 2009 @ 18:20
Ariya Hidayat

@ Carina: Qt’s JPEG handler also supports 1/2, 1/4, 1/8 scaling via libjpeg. Check out qjpeghandler.cpp in the source code.

» Posted by Wysota
 on Monday, February 02, 2009 @ 00:01

Yeeey! :)

Let’s call it “Qt::HeuristicTransformation” ;)

» Posted by Andre
 on Thursday, February 05, 2009 @ 17:44

@ariya: It’s enclosed in a #ifndef QT_NO_IMAGE_SMOOTHSCALE
When is this defined and when not? There is also no mention of it in the Docs iirc.



© 2008 Nokia Corporation and/or its subsidiaries. Nokia, Qt and their respective logos are trademarks of Nokia Corporation in Finland and/or other countries worldwide.
All other trademarks are property of their respective owners.