Image Resizing in C#

   I got complaints from millions of readers that I have not posted any programming articles with actual code lately. I do not have anything to write about right now so I decided to pull out some old code. It seems that this one is the most useful piece of code I have ever written. I originally wrote it for my first project and then wrote it again for this very no-blog. I have been asked by several people how to do this and it seems that it is a common problem so maybe someone will find it with the help of mighty Google.

   The problem is that .NET does not come with built-in method for resizing images while keeping the original aspect ratio. Resizing image to a certain size is trivial. You just use the Bitmap class constructor and pass it the old image and the new size. However this will deform the image. In most cases what you want is the largest image that fits some container but is not deformed. For example the images that come with the articles on this website are expected to fit a certain size so they need to be resized but the original aspect ratio needs to be maintained. Here is my solution to the problem:

using System.Drawing;

/// <summary>
/// Used to handle images
/// </summary>
public static class ImageManipulator
{
   public static Bitmap Resize(Image image, int width, int height, bool keepAspectRatio, bool enlargeSmallerImages)
   {
       if (!enlargeSmallerImages && image.Width <= width && image.Height <= height)
       {
           return new Bitmap(image);
       }
       if (!keepAspectRatio)
       {
           return new Bitmap(image, width, height);
       }
       else
       {
           double aspectRatio = image.Width / (double)image.Height;
           double newAspectRatio = width / height;

           if (aspectRatio >= newAspectRatio) //fit horizontally
           {
               double scale = image.Width / (double)width;
               int newHeight = (int)(image.Height / scale);
               return new Bitmap(image, width, newHeight);
           }
           else //fit vertically
           {
               double scale = image.Height / (double)height;
               int newWidth = (int)(image.Width / scale);
               return new Bitmap(image, newWidth, height);
           }
       }
   }
}

   First we check if we need to enlarge smaller images. Sometimes you do not want to do this because you will lose quality and it is better to just show the smaller image as it fits the container. If we don't need to keep the aspect ratio we just use the Bitmap constructor. However if this is not the case we need to do actual work. First we calculate the original aspect ratio and the aspect ratio of the container. If the original aspect ratio is greater than the new aspect ratio the image will fit horizontally, the new width will be the maximum width of the container and the new height will be calculated according to the scale. Then we just use the built in method with the newly calculated height as an argument. I bet it is clear for everyone what the else code does.

   I do not know if other platforms like Java or Python have methods for resizing while keeping the original aspect ratio but if they do not I believe that this code is trivial to port.
Tags:   english programming 
Posted by:   Stilgar
02:44 12.06.2009

Comments:

First Previous 1 Next Last 

Posted by   Ravenheart   on   14:11 12.06.2009

Very nice, thank you!

Posted by   npavlov   on   16:48 16.06.2009

A better way of doing this is to use method DrawImage of class Graphics instead.  There, you can use Graphics.InterpolationMode to control the quality of the output.

Graphics gr = Graphics.FromImage (targetImage);
using (gr)
{
 gr.InterpolationMode = InterpolationMode.HighQualityBicubic;
 gr.DrawImage (sourceImage,
   new Rectangle (0, 0, newWidth, newHeight),
   new Rectangle (0, 0, sourceImage.Width, sourceImage.Height),
   Graphics.Pixel);
}

Posted by   Guest (Unregistered)   on   19:34 21.03.2019

In order to make the scale function 100% I had to change to this:

double aspectRatio = (double)image.Width / (double)image.Height;
double newAspectRatio = (double)width / (double)height;

Thank you for the rest of the code!

First Previous 1 Next Last 


Post as:



Post a comment: