Creating thumbnail preview

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 200x150 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.


Blog Topics:

Comments