Menu

How to resize image files with C#

1,712 devs read this
How to resize image files with C#

One of the most common methods to improve page load times on your website is 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. WebP images are optimized image files specifically designed for the web. But an easier way to improve your performance is to simply resize the images physical dimensions directly on the server.

The following is a C# script that I use daily on all of my websites in order to scale down their image size. 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.

C# Code to Resize an Image

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.

Breaking Down the Function

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.

~/images/blog/

Combining the directory path with the filename gives us the full relative path to the image. The 3rd and 4th arguments are the maximum dimensions that we want the new image to encompass.

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.

For this implementation, I want to keep both the original full-sized 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.

How to scale the image

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();

Common Issues When Resizing Images in C#

Even though the code is relatively straightforward, there are a few common hiccups you might run into when resizing images using System.Drawing in C#:

1. Blurry Output

If your resized image comes out noticeably blurry, it’s usually due to the interpolation mode being left at its default. By default, the quality is set to low. You can improve this by creating a Graphics object from your Bitmap and explicitly setting a higher-quality interpolation mode:

using (Graphics g = Graphics.FromImage(bmSmall))
{
    g.InterpolationMode = InterpolationMode.HighQualityBicubic;
    g.DrawImage(img, 0, 0, newWidth, newHeight);
}

This extra step ensures the final output maintains better clarity, especially for high-res original files.

2. File Access Exceptions

If you’re working with files on a busy server or multi-threaded environment, make sure the file isn’t being accessed by another process. Locking or incorrect file permissions can throw exceptions or create corrupted output files. A quick try-catch like in the example helps handle this, but it’s always good to log those errors during development.

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.

Walter Guevara is a Computer Scientist, software engineer, startup founder and previous mentor for a coding bootcamp. He has been creating software for the past 20 years.
AD: "Heavy scripts slowing down your site? I use Fathom Analytics because it’s lightweight, fast, and doesn’t invade my users privacy." - Get $10 OFF your first invoice.

Community Comments

No comments posted yet

Code Your Own Classic Snake Game – The Right Way

Master the fundamentals of game development and JavaScript with a step-by-step guide that skips the fluff and gets straight to the real code.

Ad Unit

Current Poll

Help us and the community figure out what the latest trends in coding are.

Total Votes:
Q:
Submit

Add a comment