Sunday, July 04, 2004

WMI Vs. Win32

System.Drawing.Image Performance

The Product I was working on previously had to load & Edit JPEG Images, which were of Digital Quality, which means the Image size would be greater than 3-5 MB. My Client has been always cribbing about image loading speed, everything was fine while loading a 1-2 MB Image, but things started to change drastically whenever a 3 MB or greater image is loaded, it took around 1-2 sec to load a image. 2 sec is fine for normal applications, but not for people who work with thousands of images per day.

The Windows Form would almost Hang before loading up the image. After a considerable amount of research I found out that the real culprit, which caused the bottleneck is the line

I happened to hit a KB http://support.microsoft.com/default.aspx?scid=kb;en-us;831419 Which confirms this issue. And had a hotfix, which updates

Infact there was interesting new signatures under System.Drawing.Imaging
System.Drawing.Image.FromStream(Stream stream, bool useICM, bool validateImageData)
This bool validateImageData was the real cause for the image being slowed down, which validated the content of the image file before loading up. So as size of the image increased, the loading time increased exponentially. And now, when I used this new method, voila! the images started loading up atleast 90% Faster and took less than 10Millisecond to load! Wow! That was great….

But noway, I cannot distribute this hotfix along with the product. And these hotfixes are included in the next SP of .NET, so I had to lookout for an alternate. The obvious choice was Win32. and here is the method equivalent to Image.FromFile()

public static Image Win32ImageFromFile(string filename)
filename = Path.GetFullPath(filename);
IntPtr loadingImage = IntPtr.Zero;

if ( GdipLoadImageFromFile(filename, out loadingImage) != 0 )
throw new Exception("GDI+ threw a exception.");

return (Bitmap) imageType.InvokeMember("FromGDIplus", BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.InvokeMethod, null, null, new object[] { loadingImage });

When I executed this code, The images were loaded in less than 10 seconds. If you are constrained to use Win32 May be you should wait until next SP Release of .NET. sometimes Win32/Unmanaged is the savior :-)

posted by Logu Krishnan : 12:01 PM

>>The images were loaded in less than 10 seconds.
Did you mean it or was it a typo? I guess you wanna say 10 ms!!

Yep... Right! That's a Typo... :( It's 10 MilliSeconds.
Thanks for identifying it.

Post a Comment

This page is powered by Blogger. Isn't yours?