Take the 2-minute tour ×


I am populating a TListView with the ViewStyle set to vsIcon. The Listview is connected to a TImageList where for each item added to the Listview, has its own image as specified by the corresponding index.

The idea is to be able to automate the process of manipulating a series of bitmaps all at once. Each Bitmap is different, although always the same in size.

Due to the nature of how this works there is never a fixed size or limit as to how many Bitmaps are been added to the ImageList, the only restriction is the available System memory.


The issue I have is related to the performance of the manipulation on these Bitmaps. By manipulation I mean performing different Image processing techniques on the Bitmaps such as Greyscale, Swapping colors, Adjusting Brightness etc.

Now suppose it takes 3 seconds to Adjust the Brightness of a Bitmap that is 1Mb in size. If the ImageList has a total of 10 Bitmaps then this process now takes approx 30 seconds.

(Note: I have not tested the speed with GetTickCount or anything, these are just examples).

Consider the fact though that as I said earlier this ImageList could be anything in size, potentially the processing time could go on for what may seem like an eternity.

When I perform any manipulation on these Bitmaps I use GetBitmap inside a loop to send each Bitmap to an off screen buffer Bitmap to perform the manipulation on, like this:

  Bmp: TBitmap;
  i: Integer;
  Bmp := TBitmap.Create;
      for i := 0 to ImageList1.Count - 1 do
        ImageList1.GetBitmap(i, Bmp);
        Bmp.PixelFormat := pf24Bit;
        // perform manipulation to Bmp here
        ImageList1.Replace(i, Bmp, nil);

Run that over a ImageList that could contain any size or amount of Images and you can maybe understand how this could be slow.

I am looking for ways to optimize and improve the way of doing this as right now it is no where near acceptable performance wise. BeginUpdate and EndUpdate does not offer a worthwhile solution here. I am not looking for any miracles as I understand that most computations require lengthy processing time, I just need to reduce this time as best as possible with any help and advice you may have to offer.

share|improve this question
I'll have to say that Multi-threading is the way you need to go, but not just any, you need a thread pool. The OmniThreadLibrary has great resources to do so, look here: otl.17slon.com And don't do like I attempted once and try to create over 700 threads at the same time (assuming 700 images) - as this will literally kill your computer. The idea of a thread pool is to run, let's say, 5 threads at once while the rest stay in queue waiting. Once one thread finishes, another one is fired, so there are presumably never more than 5 threads running at a time. –  Jerry Dodge May 29 '12 at 23:55
@JerryDodge by threads do you mean utilising each available core on a cpu? –  Blobby May 30 '12 at 12:36
No, he means using TThreads. These will run concurrently, allowing you to process multiple images at the same time, while your application UI will remain responsive. In theory, the OS will dole out the threads to alternate cores if they're available, you shouldn't have to worry about that. –  Tim Sullivan May 30 '12 at 17:17
@TimSullivan thanks for clearing that up –  Blobby May 30 '12 at 18:35
I would say put a thread limit of 20-30 and on a good machine maybe 50, but when working with hundreds of bitmaps at once, you need to think about the computer's performance. Perhaps calculate the available memory vs the size of each image you intend to process and create your thread count based on available memory. –  Jerry Dodge May 31 '12 at 23:50

2 Answers 2

up vote 4 down vote accepted

Personally, I'd do a few things:

0) Don't do anything until you've profiled your code to make sure this is in fact where the slowdown is happening.

1) Rather than using a TImageList, I'd use a TList descendent to store the images. I'm not sure if this would have a direct impact on performance, but IIRC, TImageList relies a lot on the built-in Windows image handling, which might be slower.

2) Update the images on-demand rather than all together, if this is possible.

3) Thread the conversion process rather than run it in the main thread. This is pretty simple if you're also using a TList, as you can just pass the list item to the thread (or thread queue). This has the added benefit of using multiple processors if they're available.

Threading has the most potential to improve perceived performance of your app, even if it might not actually take less time. Combine that with as-required conversion and you should see a giant improvement.

ETA: A thread pool, as mentioned by Jerry in the comment, is a good idea. There are some examples of this on the Embarcadero site, if you search their blogs.

share|improve this answer
Using a TList will definitely improve performance (even if by a millisecond) because as Tim mentions, a TImageList is extremely heavy. However this draws back the ability for the list items to automatically show their linked image. This means you would need to manually draw these images. Still possible, but quite a bit more involved. I still highly recommend this though, loading/processing images to show in a list is no easy chore, and should be handled with care. Ironically, just today I was given the task to do exactly this (only in a grid instead of TListView) –  Jerry Dodge May 30 '12 at 0:18
Putting the processing into threads seems like what I need to do. Certainly running on the main thread is obviously slow and unresponsive even with Application.ProcessMessages. Storing the images in a TList also could be better then ImageList. These are all things I need to research to understand better how to implement them, this is one of those questions where I need to do the work myself. I know the slowdown is due to the fact there are a limitless amount of Bitmaps been modified as performing the same on one Bitmap is relatively quick. –  Blobby May 30 '12 at 18:41

Added to the excellent suggestions of Tim: I am not sure how you access your bitmaps, use the ScanLine property of the bitmap if you did not do so. And use pf32Bit if possible, access is easier and mostly even faster.

Be aware that a bitmap is not threadsafe. It is no problem to read a scanline, but when you want to write the results back be sure you use a critical section or something like that.

Using a profiler is highly recommended, you will be surprised what code is inefficient or not. I use ProDelphi: it is not expensive and very precise.

share|improve this answer
Why is 32-bit bitmap easier to access and faster ? Could you elaborate this a little bit ? And there is nothing like reading a scanline, scanline gives you just a pointer to raw pixel data, which you can directly manipulate with. –  TLama May 30 '12 at 8:56
@Arnold He means you can't necessarily read scanline on its own and retrieve an actual copy of the image data. Instead it just points to a piece of the memory where that image data can be found. –  Jerry Dodge May 31 '12 at 4:50
PS - I hope that was an accidental typo at the beginning of your previous comment... –  Jerry Dodge May 31 '12 at 4:50
@TLama - I did some experiments and found that 32 bit usually was faster than 24 bit. One explanation that springs to mind is the organization of memory in chunks of four or eight words. Fewer fetches are necessary with 32 bit compared to 24 bit. I am not sure what you mean by directly manipulating a scanline: it still requires a read, manipulation and write of elements of the scanline. Or am I missing something?. –  Arnold May 31 '12 at 19:03
@TLama - I am very sorry for the typo, Jerry - Thanks for pointing me to it –  Arnold May 31 '12 at 19:04

Your Answer


