Go Picture Crazy: Resize Images Using GDI+

Go Picture Crazy: Resize Images Using GDI+

ne of the many improvements of .NET’s GDI+ over its Win32-based predecessor is its high-level image processing API. It’s a doddle for Web servers running ASP.NET to stream JPEG data on the fly, and standalone desktop applications also benefit from a good set of methods to load, save, and convert image data from a variety of resources and media. However, just because it’s easy to do something with GDI+ doesn’t necessarily mean you should use it, and one place you’re likely to get stung?sooner or later?is when you try to resize an image.

The System.Drawing.Image and System.Drawing.Bitmap namespaces have every manner of method to manipulate image formats and properties, and bang!?in the middle of both namespaces is one method that looks exactly like what you want:

Image GetThumbnailImage(int thumbWidth, int thumbHeight ...) 

Sure enough, pass an Image or a Bitmap to GetThumbnailImage, and you’ll get back another image at the dimensions you specified. But you should take a cue from the method’s title: What it wants to return you is a thumbnail, not simply a resized image.


You want to manipulate the size of an original image, but the best method provided in GDI+ for doing so is designed to work with embedded thumbnails, not originals, causing poor image quality and lack of control over aspect ratios.


Use the ImageResize class and API to grab and manipulate images based on any property you find convenient.

Out on a Thumbnail
Working with thumbnails is inherently troublesome. The problem is, certain kinds of image formats (for example, JPEG) may already include embedded thumbnails, and under these circumstances GetThumbnailImage() just extracts the image’s existing thumbnail and scales it to the proportions you specify, rather than generating a new bitmap by resampling the original image. In fact, many digital cameras will generate and embed a thumbnail automatically whenever you take a picture, so that you can quickly browse through any pictures you’ve taken on the camera itself.

If you want to generate a thumbnail that’s substantially larger than the embedded thumbnail, GetThumbnailImage() is likely to produce a severely degraded image. For example, try downloading Figure 1 (a large file, so I’ve linked to it rather than try to display it in flow) and running the following code, which resizes it to 655 x 480 pixels:

void ThumbnailResize(string str_file, Size new_size)   {      Image src_image = Image.FromFile(str_file);      Image dst_image = src_image.GetThumbnailImage(new_size.Width,          new_size.Height, null, System.IntPtr.Zero);      dst_image.Save("tn-" + str_file,          System.Drawing.Imaging.ImageFormat.Jpeg);      dst_image.Dispose();      src_image.Dispose();   }   ThumbnailResize("aikido.jpg", new Size(655, 480)); 

Open up the rescaled image, and you’ll see something like Figure 2. Compare this with the same image resized in Paint Shop Pro (see Figure 3). The difference in quality is painfully apparent.


Figure 2. Resolution 421 Pixels per Inch.
?
Figure 3. Resolution 180 Pixels per Inch.
Editor’s note: Because we display supporting figures as thumbnail images on article pages, what you see on this page is essentially a thumbnail of a thumbnail. Please click on the thumbnails shown and view the images as popups in order to see the actual effect as the author intends.

Finer Control
Even when your source images don’t contain embedded thumbnails, though, there are good reasons why you can do better than call GetThumbnailImage() to do your resizing. For a start, GDI+ gives you considerable control over the way your image is resampled, so it makes sense to take advantage of this flexibility. Consider the following code:

void ImageResize(string str_file, Size new_size)   {      Image src_image = Image.FromFile(str_file);      Bitmap bitmap = new Bitmap(new_size.Width, new_size.Height,          src_image.PixelFormat);      Graphics new_g = Graphics.FromImage(bitmap);      new_g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;      new_g.InterpolationMode =         System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;      new_g.DrawImage(src_image, 0, 0, bitmap.Width, bitmap.Height);      src_image.Dispose();      bitmap.Save("ir-" + str_file, System.Drawing.Imaging.ImageFormat.Jpeg);      bitmap.Dispose();      new_g.Dispose();   }
Figure 4. Resolution 96 Pixels per Inch.

Having used your initial image to create a Graphics surface, you are now free to configure the way that surface is rendered. You achieve this by setting a variety of flags that the renderer will inspect when it composes the final image. Because you’re now working with the full image, any embedded thumbnails are conveniently overlooked. You can see the result in Figure 4, a vast improvement on Figure 2, and of a comparable quality with Figure 3.

In my experience, the default Graphics surface settings have been sufficient for most applications, but if you do want to customize things, the table below gives a few options to customize the smoothing, interpolation, and pixel-offset algorithms used to produce your new image.

Table 1. Smoothing, Interpolation, and Pixel Offset Modes for System.Graphics

Smoothing Mode Interpolation Mode Pixel Offset Mode
AntiAlias Bicubic Default
Default Bilinear Half
HighQuality Default HighQuality
HighSpeed High HighSpeed
None HighQualityBicubic None
? HighQualityBilinear ?
? Low ?
? NearestNeighbour ?

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.

devx-admin

devx-admin

Share the Post:
Performance Camera

iPhone 15: Performance, Camera, Battery

Apple’s highly anticipated iPhone 15 has finally hit the market, sending ripples of excitement across the tech industry. For those considering upgrading to this new

Battery Breakthrough

Electric Vehicle Battery Breakthrough

The prices of lithium-ion batteries have seen a considerable reduction, with the cost per kilowatt-hour dipping under $100 for the first occasion in two years,

Economy Act Soars

Virginia’s Clean Economy Act Soars Ahead

Virginia has made significant strides towards achieving its short-term carbon-free objectives as outlined in the Clean Economy Act of 2020. Currently, about 44,000 megawatts (MW)

Renewable Storage Innovation

Innovative Energy Storage Solutions

The Department of Energy recently revealed a significant investment of $325 million in advanced battery technologies to store excess renewable energy produced by solar and

Chip Overcoming

iPhone 15 Pro Max: Overcoming Chip Setbacks

Apple recently faced a significant challenge in the development of a key component for its latest iPhone series, the iPhone 15 Pro Max, which was unveiled just a week ago.

Performance Camera

iPhone 15: Performance, Camera, Battery

Apple’s highly anticipated iPhone 15 has finally hit the market, sending ripples of excitement across the tech industry. For those considering upgrading to this new model, three essential features come

Battery Breakthrough

Electric Vehicle Battery Breakthrough

The prices of lithium-ion batteries have seen a considerable reduction, with the cost per kilowatt-hour dipping under $100 for the first occasion in two years, as reported by energy analytics

Economy Act Soars

Virginia’s Clean Economy Act Soars Ahead

Virginia has made significant strides towards achieving its short-term carbon-free objectives as outlined in the Clean Economy Act of 2020. Currently, about 44,000 megawatts (MW) of wind, solar, and energy

Renewable Storage Innovation

Innovative Energy Storage Solutions

The Department of Energy recently revealed a significant investment of $325 million in advanced battery technologies to store excess renewable energy produced by solar and wind sources. This funding will

Renesas Tech Revolution

Revolutionizing India’s Tech Sector with Renesas

Tushar Sharma, a semiconductor engineer at Renesas Electronics, met with Indian Prime Minister Narendra Modi to discuss the company’s support for India’s “Make in India” initiative. This initiative focuses on

Development Project

Thrilling East Windsor Mixed-Use Development

Real estate developer James Cormier, in collaboration with a partnership, has purchased 137 acres of land in Connecticut for $1.15 million with the intention of constructing residential and commercial buildings.

USA Companies

Top Software Development Companies in USA

Navigating the tech landscape to find the right partner is crucial yet challenging. This article offers a comparative glimpse into the top software development companies in the USA. Through a

Software Development

Top Software Development Companies

Looking for the best in software development? Our list of Top Software Development Companies is your gateway to finding the right tech partner. Dive in and explore the leaders in

India Web Development

Top Web Development Companies in India

In the digital race, the right web development partner is your winning edge. Dive into our curated list of top web development companies in India, and kickstart your journey to

USA Web Development

Top Web Development Companies in USA

Looking for the best web development companies in the USA? We’ve got you covered! Check out our top 10 picks to find the right partner for your online project. Your

Clean Energy Adoption

Inside Michigan’s Clean Energy Revolution

Democratic state legislators in Michigan continue to discuss and debate clean energy legislation in the hopes of establishing a comprehensive clean energy strategy for the state. A Senate committee meeting

Chips Act Revolution

European Chips Act: What is it?

In response to the intensifying worldwide technology competition, Europe has unveiled the long-awaited European Chips Act. This daring legislative proposal aims to fortify Europe’s semiconductor supply chain and enhance its

Revolutionized Low-Code

You Should Use Low-Code Platforms for Apps

As the demand for rapid software development increases, low-code platforms have emerged as a popular choice among developers for their ability to build applications with minimal coding. These platforms not

Cybersecurity Strategy

Five Powerful Strategies to Bolster Your Cybersecurity

In today’s increasingly digital landscape, businesses of all sizes must prioritize cyber security measures to defend against potential dangers. Cyber security professionals suggest five simple technological strategies to help companies

Global Layoffs

Tech Layoffs Are Getting Worse Globally

Since the start of 2023, the global technology sector has experienced a significant rise in layoffs, with over 236,000 workers being let go by 1,019 tech firms, as per data

Huawei Electric Dazzle

Huawei Dazzles with Electric Vehicles and Wireless Earbuds

During a prominent unveiling event, Huawei, the Chinese telecommunications powerhouse, kept quiet about its enigmatic new 5G phone and alleged cutting-edge chip development. Instead, Huawei astounded the audience by presenting

Cybersecurity Banking Revolution

Digital Banking Needs Cybersecurity

The banking, financial, and insurance (BFSI) sectors are pioneers in digital transformation, using web applications and application programming interfaces (APIs) to provide seamless services to customers around the world. Rising

FinTech Leadership

Terry Clune’s Fintech Empire

Over the past 30 years, Terry Clune has built a remarkable business empire, with CluneTech at the helm. The CEO and Founder has successfully created eight fintech firms, attracting renowned

The Role Of AI Within A Web Design Agency?

In the digital age, the role of Artificial Intelligence (AI) in web design is rapidly evolving, transitioning from a futuristic concept to practical tools used in design, coding, content writing

Generative AI Revolution

Is Generative AI the Next Internet?

The increasing demand for Generative AI models has led to a surge in its adoption across diverse sectors, with healthcare, automotive, and financial services being among the top beneficiaries. These

Microsoft Laptop

The New Surface Laptop Studio 2 Is Nuts

The Surface Laptop Studio 2 is a dynamic and robust all-in-one laptop designed for creators and professionals alike. It features a 14.4″ touchscreen and a cutting-edge design that is over

5G Innovations

GPU-Accelerated 5G in Japan

NTT DOCOMO, a global telecommunications giant, is set to break new ground in the industry as it prepares to launch a GPU-accelerated 5G network in Japan. This innovative approach will

AI Ethics

AI Journalism: Balancing Integrity and Innovation

An op-ed, produced using Microsoft’s Bing Chat AI software, recently appeared in the St. Louis Post-Dispatch, discussing the potential concerns surrounding the employment of artificial intelligence (AI) in journalism. These