How to resize image files with C#

Written by
Published on
Modified on

I recently wrote about website optimization on this blog as it is quickly becoming an important ranking factor in search engines.

One of the methods mentioned to improve page load times was to reduce your image sizes. That can be done by changing the file type often times, such as converting a .png file to a .webp file. But an easier way is to simply resize the images physical dimensions directly on the server.

The following is a C# script that I created and that I use daily on all of my websites in order to do just that. It works by leveraging the built-in .NET System.Drawing classes in order to create a virtual Bitmap with the new dimensions and then saving this new file on the server.

I will show the code first and then do a bit of background and further explanation right after.

The code

private void CreateThumbnail(string filename, string path, int maxWidth, int maxHeight){
try
{
    System.Drawing.Image img = System.Drawing.Bitmap.FromFile(Server.MapPath(string.Format("{0}{1}", path, filename)));
string strName = string.Format("thumb_{0}", filename);

System.Drawing.Image newImg;
double newWidth = img.Width;
double newHeight = img.Height;

// finds the small dimensions
for (int i = 99; i > 0; i--)
{
    newWidth = (double)(i / 100.0) * newWidth;
    newHeight = (double)(i / 100.0) * newHeight;

    if (newWidth <= maxWidth && newHeight <= maxHeight)
    {
        break;
    }
}

var bmSmall = new System.Drawing.Bitmap(img, new System.Drawing.Size((int)newWidth, (int)newHeight));

newImg = (System.Drawing.Image)(bmSmall);
newImg.Save(Server.MapPath(string.Format("{0}{1}", path, strName)));
img.Dispose();
newImg.Dispose();
}

catch (Exception ex) { } }

You can copy that function as is as it is written generically to run alongside any other code. But for the full breakdown, read on.

First up, let's take a look at the functions signature.

private void CreateThumbnail(string filename, string path, int maxWidth, int maxHeight){

The first argument, filename, is the name of the file on the file system that you wish to resize. This assumes that you already have the file stored somewhere on your server after an upload.

The second argument, path, is the relative directory path of your file. For example:

~/images/blog/

Combined with the filename, this gives you the full relative path to the image. The 3rd and 4th arguments are the maximum dimensions that you want your new image to fit.

Note that this particular implementation will ensure that ratio's are maintained during the resize process.

System.Drawing.Image img = System.Drawing.Bitmap.FromFile(Server.MapPath(string.Format("{0}{1}", path, filename)));

Note that I left the full namespace class names in each variable declaration for clarification as to where these classes are located.

The first thing that you'll need to do is to create a Drawing.Image object instantiated with your uploaded image file's path. You can get the actual server image path using the Server.MapPath method, which takes in a relative path URL as its argument.

With this implementation, I want to keep both the original image and the new image on the server, so I will be saving the new file with the "thumb_" prefix on the original filename.

string strName = string.Format("thumb_{0}", filename);

Here are a few more variable declarations to include:

System.Drawing.Image newImg;
double newWidth = img.Width;
double newHeight = img.Hxeight;

The newImg variable will reference the final Image object after being resized. For now however, it will be uninitialized. The newWidth and newHeight variables will be updated to the corresponding resized ratios. But for now, they are initialized to the original dimensions.

The actual resizing happens with the following for loop, in which the original dimensions are resized on a percentage basis (99%, 98%, 97%, ...) until they reach the maximum width and height passed in through the parameters.

// finds the small dimensions
for (int i = 99; i > 0; i--)
{
    newWidth = (double)(i / 100.0) * newWidth;
    newHeight = (double)(i / 100.0) * newHeight;

    if (newWidth <= maxWidth && newHeight <= maxHeight)
    {
        break;
    }
}

Once the desired size has been found, a break statement terminates the loop.

We can now create a new Bitmap object based on the new dimensions and the original Image object.

var bmSmall = new System.Drawing.Bitmap(img, new System.Drawing.Size((int)newWidth, (int)newHeight));

Notice that the 2nd argument to the Bitmap constructor is an instance of the Drawing.Size class, which takes in both the width and height arguments as integers.

The last step is a simple conversion from Bitmap to Drawing.Image, so that we can call the Save method of the Drawing.Image class.

newImg = (System.Drawing.Image)(bmSmall);
newImg.Save(Server.MapPath(string.Format("{0}{1}", path, strName)));

We'll save the image with the new "thumb_" prefix onto the original file path and lastly dispose of any remaining resources.

img.Dispose();
newImg.Dispose();

And that's all there is to an image resize. As mentioned, the code is left generic so that you can implement it into any .NET C# project.

If you found this script useful, let me know and leave a comment below and feel free to suggest any improvements that could be made.

Leave a comment

No messages posted yet

Developer Poll

Q:

Add a comment

Send me your weekly newsletter filled with awesome ideas
Post