In Valid Logic

Endlessly expanding technology

Lesser known CS goodies: ImageInfo class

Kevin came to me the other day and was asking about whether I knew of a good way to efficiently extract the dimensions of 100+ images.  He said he was starting to look at the System.Drawing namespace and was curious what the best way was.

I immediately turned on my caps and said NO!  DON'T DO IT!  Don't get me wrong, the System.Drawing namespace is great, but when you just need the dimensions of an image, and you are processing 100 images, it is not very efficient.  It will need to load up the entire image, just so you can access some metadata about it.  Do that 100+ times on a given run, and it will be incredibly slow and CPU hungry.

I had encountered the same issue way back when we were developing Community Server v1.0.  I had begun prototyping the FTP Gateway and one of my main things was that I wanted to queue up 1000 images to be sent in a row.  It worked, but would have the CPU pinned at 80-100% the whole time.  The problem was that the images would transfer so fast (since it was on the local network), and the slow down was where it accessed the image's dimensions and cached the EXIF data.  Initially, we were using the System.Drawing namespace and was having to process the entire image when we were just accessing the metadata.

So I set out to find a way to access the image's metadata directly, by looking at the raw header instead of relying on accessing it as an image.  The solution was ImageInfo.  I found this class that did precisely what I wanted, just that it was written in Java.  So I did what any determined developer would do and decided to port it.  And in one night, I was able to get it ported over to C#, plugged into CS, and working in both the CS website and with the FTP Gateway.

This class has been a part of Community Server v1.0 around beta2 or 3.  It is in the CommunityServer.Components project, with its full namespace being CommunityServer.Components.ImageInfo.  Since it is in Components, it is accessible by all CS assemblies.  It is also quite easy to use.  Just take this little tidbit:

// Check to make sure it is a valid image
FileStream stream = File.Open("image.jpg", FileMode.Open);
ImageInfo imageInfo
= new ImageInfo(stream);
string contentType;
int width;
int height;

// If it is a picture, get the imagesize
if (imageInfo.Check())
{
// Get the image's width and height settings
contentType = imageInfo.MimeType;
width
= imageInfo.Width;
height
= imageInfo.Height;
}

stream.Close();

This is a simple and straightforward way to access some basic information about the image.  Create a new ImageInfo object with the stream of the file.  Then, call the imageInfo.Check() method to do the actual processing of the file.  If it returns true, it is a valid image type of either JPEG, PNG, GIF, BMP, and a couple others.  After that, you can access the properties that contain the info about the image.  Overall, it gathers the following:

  • Width/height
  • Bits per pixel
  • Whether the image is progressive
  • The image format (an enum of either JPEG, GIF, BMP, etc)
  • The content type (as a string)
  • Color type
  • Comments from the image (such as in JPEG files)
  • Number of images (such as with animated GIFs)
  • Physic width and height DPI

Use it, love it, and enjoy it.  Joy me next time, as I may make this into a semi-regular series to expose developers and power users to some of the great utilities buried deep within CS.

Friday, September 22, 2006

 
blog comments powered by Disqus