How to get an image thumbnail without loading whole file into memory?

I would like to display the thumbnails of multiple image files, without having to slowly load every image. I don't need the whole file, and only want to display its thumbnail. What would be the best way to do this and how do applications normally do this? These are the ideas i came up with, but i am unsure if they are good:

  • Use a crate to load the thumbnail from the files metadata if available. I did not find one for rust (Please correct me if a am wrong. I searched everywhere)
  • I know some libraries that can resize images pretty quick. But as far as i can follow, all of those i found load the whole image into memory, to then resize it. (For example thumbnailer. I looked at the source code, and at some point the whole file is loaded into a Vec)
  • Write a "quick" custom Implantation, that reads from the files metadata markers. But this would take some time
  • Just use one of the many thumbnail libraries and save the thumbnails inside a thumbnail folder next to the executable. So that every time i need a thumbnail, i check if it exists inside the folder or else resize the image itself
  • Use the exiftool command line tool (I think this would be a little complicated)
  • I found a library that can read from the windows explorer thumbnail-cache database. But i want to support other os as well, so i think this could be a temporary solution

This depends on the image format and particular file.

  • Some images may have a thumbnail image already generated end embedded in their metadata (e.g. JPEG metadata has this ability). However, this is done very rarely in practice, since it bloats the file. Even when such data is present, it may have tiny dimensions (you don't control the size), and sometimes it's even total garbage (e.g. stuffed with a logo of the graphics program that made the file rather than miniature of the actual image).

  • Progressive JPEG can be used to generate a thumbnail at 1/8th of the size by decoding DC scan only. This is pretty efficient, and requires loading less than 15% of the file from disk. However, images scaled this way will have incorrect gamma and increased color distortion from chroma subsampling.

  • Interlaced PNG (and GIF) can be decoded similarly, but in practice interlacing is almost never used. You don't get anti-aliasing this way, but otherwise the thumbnail is properly scaled.

  • Baseline JPEG can't avoid loading and decoding the whole file, but can offer some CPU saving by processing the DC coefficients only, or performing IDCT at a lower resolution. Scaling this way will have incorrect gamma and increase distortions from chroma subsampling.

  • JPEG 2000 supports partial decoding pretty well, but it's rarely used.

  • WebP and AVIF must be decoded fully every time (for AVIF there's a proposal for an embedded thumbnail, but AFAIK nobody uses this yet).

In practice I recommend implementing this for JPEG only (libjpeg/mozjpeg can do it), because benefits from any other format are negligible. Not loading the full file seems like a smart thing to do, but in reality it's a lot of complexity, but very little benefit. Most images will require full decoding anyway. Many small I/O operations may be slower than one big read. RAM isn't a bottleneck any more.

8 Likes

Most images just don't come with a thumbnail, so there's really only two options:

  • Just accept loading it

  • Find a thumbnail that someone else already made by loading it.

So I'd suggest either do nothing (especially since cache invalidation is hard) or integrate with the OS, since it has this problem already. Finder does it on Mac, Explorer does it on Windows, Photos does it on Android, ...

3 Likes

Ok thank you guys. I think i will just dry load all the images and then when i have time, integrate the os specific thumbnail caches

1 Like

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.