Click here to Skip to main content
12,897,360 members (55,169 online)
Click here to Skip to main content
Add your own
alternative version


17 bookmarked
Posted 3 Jun 2013

Resize Images to Size Limit

, 3 Jun 2013 CPOL
Rate this:
Please Sign up or sign in to vote.
This tip describes how to resize an existing image (e.g. uploaded by a user) so it does not exceed a defined size limit.


To enable customers to upload images which exceed the maximum upload size given by the system, it became necessary to scale down large images until the given size limit was no longer exceeded. Since I did not find any articles about this problem, I decided to write one myself to maybe help others struggling with a similar problem.


Before we can start the resizing process, we need to obtain the source path of the uploaded image, the destination path (which is very likely the same path) and the maximum allowed size given by your system. All these values are initialized in the constructor:

private int allowedFileSizeInByte;
private string sourcePath;
private string destinationPath;

public ImageResizer(int allowedSize, string sourcePath, string destinationPath)
	allowedFileSizeInByte = allowedSize;
	this.sourcePath = sourcePath;
	this.destinationPath = destinationPath;

Scaling Images

Let's start with the function which does the scaling. I use a Bitmap as the source image and a scale factor which is applied to change the width and height of the image. Later, we will see how to calculate this scale factor. Since the following code is pretty straight forward, I won't go into further details:

public Bitmap ScaleImage(Bitmap image, double scale)
	int newWidth = (int)(image.Width * scale);
	int newHeight = (int)(image.Height * scale);

	Bitmap result = new Bitmap(newWidth, newHeight, PixelFormat.Format24bppRgb);
	result.SetResolution(image.HorizontalResolution, image.VerticalResolution);

	using (Graphics g = Graphics.FromImage(result))
		g.InterpolationMode = InterpolationMode.HighQualityBicubic;
		g.CompositingQuality = CompositingQuality.HighQuality;
		g.SmoothingMode = SmoothingMode.HighQuality;
		g.PixelOffsetMode = PixelOffsetMode.HighQuality;

		g.DrawImage(image, 0, 0, result.Width, result.Height);
	return result;

Calculating the Scale Factor

The scale factor for the file size can be approximated by dividing the allowed file size by the file size of the image. This simply describes by which amount the file size has to decrease to reach the size limit. Since we generally don't know anything about the compression of the uploaded image, we cannot exactly predict by which factor we have to scale the width and height of our image. However, we know that the file size of an image will increment quadratically if we increase its width and height, since the file size is approximately calculated by multiplying width and height. Since we want to decrease the file size of the picture, we simply have to calculate the square root of the scale factor calculated above and use this value as a parameter for our ScaleImage function. To clarify this process, take a look at the following function which will be called by the client to perform the resizing:

public void ScaleImage()
	using (MemoryStream ms = new MemoryStream())
		using (FileStream fs = new FileStream(sourcePath, FileMode.Open))
			Bitmap bmp = (Bitmap)Image.FromStream(fs);
			SaveTemporary(bmp, ms, 100);

			while (ms.Length > allowedFileSizeInByte)
				double scale = Math.Sqrt
				((double)allowedFileSizeInByte / (double)ms.Length);
				bmp = ScaleImage(bmp, scale);
				SaveTemporary(bmp, ms, 100);

			if (bmp != null)

As you can see, we use a while MemoryStream to save the uploaded image in memory instead of the hard disk during the resizing process. The Bitmap variable bmp contains the image to be resized which is obtained through a FileStream. Inside the while loop, the image is resized using the scale factor and the new image is saved back into the MemoryStream using the SaveTemporary function we will see in a minute. This while loop is applied until the size limit is not exceeded anymore. We need to iterate here, because our scale factor is really only an approximation and depending on the image it might not provide enough scaling when calling ScaleImage for the first time.

Other Helper Functions

Finally, let's take a look at the helper functions used by the scaling process:

private void SaveTemporary(Bitmap bmp, MemoryStream ms, int quality)
	EncoderParameter qualityParam = new EncoderParameter
		(System.Drawing.Imaging.Encoder.Quality, quality);
	var codec = GetImageCodecInfo();
	var encoderParams = new EncoderParameters(1);
	encoderParams.Param[0] = qualityParam;
	bmp.Save(ms, codec, encoderParams);

private void SaveImageToFile(MemoryStream ms)
	byte[] data = ms.ToArray();

	using (FileStream fs = new FileStream(destinationPath, FileMode.Create))
		fs.Write(data, 0, data.Length);

private ImageCodecInfo GetImageCodecInfo()
	FileInfo fi = new FileInfo(sourcePath);

	switch (fi.Extension)
		case ".bmp": return ImageCodecInfo.GetImageEncoders()[0];
		case ".jpg":
		case ".jpeg": return ImageCodecInfo.GetImageEncoders()[1];
		case ".gif": return ImageCodecInfo.GetImageEncoders()[2];
		case ".tiff": return ImageCodecInfo.GetImageEncoders()[3];
		case ".png": return ImageCodecInfo.GetImageEncoders()[4];
		default: return null;

The SaveTemporary function is used to temporarily save the image into the provided MemoryStream during each iteration. It uses .NET EncoderParameters and ImageCodecInfo to get high quality compression rates which are nearly as good as the compression rates provided by Image editing software. Using the EncoderParameters and ImageCodecInfo in the call to bmp.Save provides better result than using the save function which takes a stream and an ImageFormat instance as its only parameters, so I advise you to use this version to get the best results. The SaveImageToFile function is finally used to write the MemoryStream, which contains the resized image, to its final location on the hard disk.


Hopefully you find this code useful and can apply it to solve similar problems. I appreciate any feedback tips and suggestions.


This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


About the Author

Software Developer (Junior)
Germany Germany
No Biography provided

You may also be interested in...


Comments and Discussions

QuestionVery Useful Pin
ryanoc3334-Jun-13 4:45
memberryanoc3334-Jun-13 4:45 
AnswerRe: Very Useful Pin
Philipp Engelmann4-Jun-13 5:05
memberPhilipp Engelmann4-Jun-13 5:05 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Terms of Use | Mobile
Web01 | 2.8.170424.1 | Last Updated 3 Jun 2013
Article Copyright 2013 by Philipp_Engelmann
Everything else Copyright © CodeProject, 1999-2017
Layout: fixed | fluid