Browse DevX
Sign up for e-mail newsletters from DevX


Go Picture Crazy: Resize Images Using GDI+ : Page 3

It's tempting to use GDI+'s GetThumbnailImage method when you need to manipulate the size of images in your applications, but you'll pay for it with image degradation. There's a better way. Use the ResizeImage API in this article to do whatever you like with images and never drop a pixel (unless you want to).




Building the Right Environment to Support AI, Machine Learning and Deep Learning

A Simple Resizing API
While the code above will produce good quality thumbnails of arbitrary dimensions, this isn't always what you want. In fact, most of the time, you'll want to keep the image's aspect ratio the same, and resize it proportionally so that either the final image has a specified pixel width or height, or it has been scaled down to a specified percentage of its original dimensions. For convenience, I decided to put all this together into a dedicated assembly, which exposes the following simple API:

Table 2. API for the ImageResize class
Name Class Type Description
File Property String Sets the path from which the image should be loaded
Image Property Image Sets the image object from which to generate thumbnails
PreserveAspectRatio Property Bool Flag denoting whether the aspect ratio of the original image should be preserved (default is true)
UsePercentages Property Bool Whether to interpret the Width and Height properties as absolute dimensions or percentages of the original image dimensions
Width Property Double The width of the thumbnail
Height Property Double The height of the thumbnail (units depend on whether UsePercentages is true or false)
GetThumbnail Method Image Creates a thumbnail based on the properties that have been specified

I could just as soon have exposed a single, static method, but I find a formal ImageResize object both more intuitive and more flexible for several reasons. First, if you want a thumbnail of a specified height but don't care about the width, you just set the ImageResize object's Height property and don't specify a Width. In contrast, if I'd implemented GetThumbnail as a fully parameterized method, you would have had to pass in some "magic number" (perhaps 0 or –1) to signify that you didn't want to specify this field.

Second, resizing large images takes a lot of processing power and uses a lot of RAM, as I discovered while experimenting with the raw JPEGs downloaded from my digital camera. With an object-based approach you can cache images for immediate performance benefits. For example, the first thing GetThumbnail does is to check whether the source image has changed; if not, it uses the last image it has available. This means that if you need to generate thumbnails repetitively from a single image (for example, by displaying the image in a window and letting the user drag it to a new size with the mouse), the loading step only happens once. By the same token, if none of the ImageResize object's properties have changed between consecutive calls to GetThumbnail, it returns you a cached image rather than calculating a new one.

Finally, the object-based approach lets you group your preferred settings in one place, which makes for simpler code when you want to perform the same operation on a lot of different images.

To use the class, just compile the ImageResize assembly and add a reference to it in any projects that need to resize images. For example, the following code loads an image called "tabi.jpg," and reduces it to 35 percent of its original size, while maintaining its aspect ratio:

ImageResize o = new ImageResize(); o.File = "c:/temp/tabi.jpg"; o.Height = 35; o.UsePercentages = true; o.GetThumbnail().Save("c:/temp/test.jpg", System.Drawing.Imaging.ImageFormat.Jpeg);

If instead I'd wanted to resize the image to absolute percentage or pixel dimensions, I would have specified a Width as well as a Height for my resized image.

Images for the Web
When I originally wrote the ImageResize class I envisaged I would mostly be using it from Windows Forms-based applications. However, it's just as easy to use it server-side in order to stream dynamically resized images on demand. All you need to do is set the content type to "image/jpeg" and stream the image directly into the Response stream in your Page_Load() method:

Response.ContentType = "image/jpeg"; ImageResize o = new ImageResize(); // Load your image and perform any resizing here o.File = … o.GetThumbnail().Save(Response.OutputStream, System.Drawing.Imaging.ImageFormat.Jpeg);

Hopefully this simple class will cover most of your image resizing needs, as well as take care of basic image caching issues, leaving you free to concentrate on the more important programming tasks. It should also keep you from scratching your head when GetThumbnailImage doesn't return the data you expect.

Alex Hildyard is a freelance software consultant and writer, specializing in Web technology.
Comment and Contribute






(Maximum characters: 1200). You have 1200 characters left.



Thanks for your registration, follow us on our social networks to keep up-to-date