views:

456

answers:

5

I have a winforms image list which contains say like 200 images 256x256.

I use the method Images.FromFile to load the images and then add them to the image list.

According to ANTS .NET profiler, half of the program's time is spent in Images.FromFile. Is there a better way to load an image to add to an image list?

Another thing that might be optimized is, the images that are loaded are larger than 256x256. So is there a way to load them by resizing them first or something? I just want to uniform scale them if they their height is larger than 256 pixels.

Any idea to optimize this?

EDIT: They are JPEGs.

+1  A: 
  1. If you want speed then prescale your images, don't do it in runtime.
  2. You didn't mention want type of images you loading (jpeg, png, gif, bmp) of course that bmp is the fastest one since it has not (or almost no) compression.
  3. Are your images 256 colors (8 bit w/ palette), bmp, gif and png support that format that can load pretty fast.
Shay Erlichmen
I could prescale them, but it's gonna be a lot of work, but if it's gonna make it faster, then sure.#3, They are 24bit.
Joan Venge
@Joan: prescaling is not necessarily a lot of work: check out http://www.imagemagick.org/script/index.php; excellent command line tool for batch processing images.
Fredrik Mörk
Thanks, I could write a PS script, just thought it's gonna be more work when the original ones are changed, color corrected, but it may well be done at the end.
Joan Venge
@Joan, are your images really need to be 24Bit? (You didn't mention which format I'm guessing jpeg) try color converting them to 256 colors. that will save you a lot of memory bandwidth.
Shay Erlichmen
alternatively you can cache the scaled images instead of pre-scaling them each time
Aleris
@Shay, sorry I added that info to the original post, but yeah they are jpegs. Also making them 256 color will not make it faster though, right?@Aleris, how do you cache then scaled images? You mean automatically scale at runtime?
Joan Venge
@Joan You need to switch format to "enjoy" the benefit of 8 Bit, try converting them to GIF or 8 Bit PNG, I believe that you will see a great improvement.
Shay Erlichmen
Ok will give it a try too. I am concerned whether the images look bad because they are photos, but worth a try. Thanks.
Joan Venge
+1  A: 

It sounds like you need some sort of image thumbnails? Don't forget that jpeg images already contains thumbnails inside, so you can extract only this small image and you do not need to scale. Such images however smaller than 256x256.

Another option is to move loading logic into separate thread, it will not be faster, but from users perspective it can look as significant speedup.

arbiter
+1  A: 

If you are trying to make thumbnails then try this code here it will let you extract thumbnails without completely loading the image.

murasaki5
Thanks, but thumbnails are smaller than 256x256 and therefore will look blurry/ugly in my app.
Joan Venge
A: 

You don't say how much bigger than 256x256 the images actually are - modern digital cameras images are much bigger than this.

Disk I/O can be very slow, and I would suggest you first get a rough idea how many megabytes of data you're actually reading.

Then you can decide if there's a subtle 'Image.FromFile' problem or a simple 'this is how slow my computer/drives/anti-virus scanner/network actually is' problem.

A simple test of the basic file I/O performance would be do to File.ReadAllBytes() for each image instead of Image.FromFile() - that will tell you what proportion of the time was spent with the disk and what with the image handling - I suspect you'll find it's largely disk, at which point your only chance to speed it up might be one of the techniques for getting JFIF thumbnails out of files. Or perhaps one can imagine clever stuff with partial reads of progressive JPEGs, though I don't know if anyone does that, nor if your files are progressive (they're probably not).

I don't really know how fast you need these to load, but if the problem is that an interactive application is hanging while you load the files, then think of ways to make that better for the user - perhaps use a BackgroundWorker to load them asynchronously, perhaps sort the images by ascending file-size and load the small ones first for a better subjective performance.

Will Dean
Thanks Will. Basically these are some that are 256x256, some are 4K. I think the total size of all the images are about 90MB. Is this alot? How should I do this?
Joan Venge
It's a fair bit of info to read from disk (and it won't be one nice block read of a continous swathe of disk, before you reach for your hard-disks theoretical performance figures...). I added some more stuff to my answer to offer some suggestions.You will generally get better answers to this sort of question if you're more up-front with the real numbers - the 50% figure you started with is meaningless on its own. Number of files, size of files, type of storage they're coming from (local hard disk, network, etc), and most importantly HOW LONG is the 50% half of?
Will Dean
+1  A: 

I have a winforms image list

I would avoid using ImageList in this scenario. Internally, it is an old Windows common control intended for working with GUI icons, usually 32x32 pixels or less.

Another thing that might be optimized is, the images that are loaded are larger than 256x256.

Be aware that GDI+ is not optimized for working with very large bitmaps of the kind that you would normally edit using photo software. Photo editing software packages generally have sophisticated algorithms that divide the image into smaller parts, swap parts to and from disk as needed to efficiently utilize memory, and so on.

Resizing an image is CPU intensive, especially when using a good quality interpolation algorithm. Take a cue from how Windows Explorer does this -- it saves the thumbnails to a file on disk for future access, and it does the processing in the background to avoid monopolizing the system.

binarycoder