Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the fastest way of loading and re-sizing an image?

I need to display thumbnails of images in a given directory. I use TFileStream to read the image file before loading the image into an image component. The bitmap is then resized to the thumbnail size, and assigned to a TImage component on a TScrollBox.

It seems to work ok, but slows down quite a lot with larger images.

Is there a faster way of loading (image) files from disk and resizing them?

Thanks, Pieter

like image 219
Pieter van Wyk Avatar asked May 07 '09 16:05

Pieter van Wyk


People also ask

Do Compressed images load faster?

During our testing, we found that image compression improved loading times around 10% in most cases. This is at the lower end of the scale, though. During testing, we saw even better results, all the way up to a 24.29% performance increase.


2 Answers

Not really. What you can do is resize them in a background thread, and use a "place holder" image until the resizing is done. I would then save these resized images to some sort of cache file for later processing (windows does this, and calls the cache thumbs.db in the current directory).

You have several options on the thread architecture itself. A single thread that does all images, or a thread pool where a thread only knows how to process a single image. The AsyncCalls library is even another way and can keep things fairly simple.

like image 179
skamradt Avatar answered Sep 27 '22 21:09

skamradt


I'll complement the answer by skamradt with an attempt to design this for being as fast as possible. For this you should

  • optimize I/O
  • use multiple threads to make use of multiple CPU cores, and to keep even a single CPU core working while you read (or write) files

The use of multiple threads implies that using VCL classes for the resizing isn't going to work, as the VCL isn't thread-safe, and all hacks around that don't scale well. efg's Computer Lab has links for image processing code.

It's important to not cause several concurrent I/O operations when using multiple threads. If you choose to write the thumbnail images back to files, then once you have started reading a file you should read it completely, and once you have started writing a file you should also write it completely. Interleaving both operations will kill your I/O, because you potentially cause a lot of seeking operations of the hard disc head.

For best results the reading (and writing) of files should also not happen in the main (GUI) thread of your application. That would suggest the following design:

  • Have one thread read files into TGraphic objects, and put these into a thread-safe list.
  • Have a thread pool wait on the list of files in original size, and have one thread process one TGraphic object, resize it into another TGraphic object, and add this to another thread-safe list.
  • Notify the GUI thread for each thumbnail image added to the list, so it can be displayed.
  • If thumbnails are to be written to file, do this in the reading thread as well (see above for an explanation).

Edit:

On re-reading your question I notice that you maybe only need to resize one image, in which case a single background thread is of course enough. I'll leave my answer in place anyway, maybe it will be of use to someone else some time. It's what I learned from one of my latest projects, where the final program could have needed a little more speed but was only using about 75% of the quad core machine at peak times. Decoupling I/O from processing would have made the difference.

like image 30
mghie Avatar answered Sep 27 '22 23:09

mghie