Displaying An Image or Animated GIF in Qt With Aspect Ratio-Preserving Scaling

When it comes to me and organizing images, GQView (now Geeqie) has always been a “best of a bunch of bad options” sort of thing and, with my move off Kubuntu 14.04 LTS, it’s become downright unusable in some cases. (eg. Freezing up at 100% CPU for several minutes to load certain collections)

As a result, I’ve been pushed to prioritize my efforts to replace at least the bare minimum subset of that functionality and, since I don’t want to rely on gtk3-mushrooms to make my own creations tolerable to me and Rust doesn’t have mature Qt bindings, that means PyQt5.

It’s not perfect (Qt doesn’t have incremental loading like GdkPixbufLoader, so I have to rely more heavily on my prototype code for asynchronously loading a bunch of upcoming images ahead in the background while I dawdle looking at the current one) but it’ll have to do… and I’ve filed a bug about that.

Now Qt has always been weird about how to get a displayed image to preserve its aspect ratio properly. It’s probably the one really glaring oversight in an otherwise very nicely designed and documented set of APIs. Given how much I had to fiddle around with things, I decided that I definitely wanted to share what I came up with.

What made it more difficult is that I’ve always wanted a GQView-alike which also displays animated GIFs with their animation, and Qt doesn’t have a unified solution for that. (QImage handles static images and QMovie handles GIF and MNG, but not actual movies, which you need to use the multimedia backend for.)

It turns out that getting smooth upscaling with QMovie is a tricky thing in itself because it’s very easy to accidentally build a widget tree that does the upscaling at a point in the pipeline where fast/ugly upscaling gets used, so a big thanks to Spencer on StackOverflow who figured it out.

Anyway, enough talk. Here’s the code:

(Yeah. I was too eager to post it, so this prototype hasn’t actually been split into the design which allows me to put the cache after the images get decoded. Still, it should be useful for most people.)

CC BY-SA 4.0 Displaying An Image or Animated GIF in Qt With Aspect Ratio-Preserving Scaling by Stephan Sokolow is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License.

This entry was posted in Geek Stuff. Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *

By submitting a comment here you grant this site a perpetual license to reproduce your words and name/web site in attribution under the same terms as the associated post.       Also, please be aware that non-constructive comments will have their URL field erased before being approved in order to combat SEO spam.