ASP.NET HttpPostedFile Image Resizer
By Peter Bromberg
An Image Resizer class for uploaded image files
Many websites have forums and other features where members can upload an avatar image
or photo of themselves. One of the most common problems with this is that people
upload images that are too big.
You can work around this by specifying one parameter in your <img/> tags, a
width property. This will automatically constrain the displayed image to your
required size. However, it does not change the size of the uploaded image file.
To do that, you must resize the image the user has uploaded before saving it.
This handy ImageResizer class does just that.
using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Web;
namespace PAB.ImageResizer
{
/// <summary>
/// A class to resize uploaded images
/// </summary>
public class ImageResizer
{
private int _imgQuality;
private int _maxHeight;
private int _maxWidth;
private PAB.ImageResizer.ImageFormat _outputFormat;
/// <summary>
/// Initializes a new instance of the <see cref="ImageResizer"/>
class.
/// </summary>
public ImageResizer()
{
this._maxWidth = 800;
this._maxHeight = 800;
this._imgQuality = 80;
this._outputFormat = PAB.ImageResizer.ImageFormat.Jpeg;
}
/// <summary>
/// Initializes a new instance of the <see cref="ImageResizer"/>
class.
/// </summary>
/// <param name="maxWidth">Maximum Width .</param>
/// <param name="maxHeight">Maximum Height</param>
/// <param name="imgQuality">The image quality.</param>
public ImageResizer(int maxWidth, int maxHeight, int imgQuality)
{
this._maxWidth = 800;
this._maxHeight = 800;
this._imgQuality = 80;
this._outputFormat = PAB.ImageResizer.ImageFormat.Jpeg;
this._maxHeight = maxHeight;
this._maxWidth = maxWidth;
this._imgQuality = imgQuality;
}
/// <summary>
/// Resizes the specified source image.
/// </summary>
/// <param name="sourceImage">The source image.</param>
/// <returns></returns>
internal System.Drawing.Image Resize(System.Drawing.Image sourceImage)
{
System.Drawing.Image source = new Bitmap(sourceImage);
int width = sourceImage.Width;
int height = sourceImage.Height;
if (width > this.MaxWidth)
{
height = (height * this.MaxWidth) / width;
width = this.MaxWidth;
}
if (height > this.MaxHeight)
{
width = (width * this.MaxHeight) / height;
height = this.MaxHeight;
}
if ((width != sourceImage.Width) || (height != sourceImage.Height))
{
source = new Bitmap(source, width, height);
}
return source;
}
/// <summary>
/// Resizes by specified image path.
/// </summary>
/// <param name="imagePath">The image path.</param>
public void Resize(string imagePath)
{
this.Resize(imagePath, imagePath);
}
/// <summary>
/// Resizes the specified posted file.
/// </summary>
/// <param name="postedFile">The posted file.</param>
/// <returns></returns>
public byte[] Resize(HttpPostedFile postedFile)
{
if (postedFile.ContentLength == 0)
{
return new byte[0];
}
System.Drawing.Image sourceImage = System.Drawing.Image.FromStream(postedFile.InputStream);
System.Drawing.Image image2 = this.Resize(sourceImage);
sourceImage.Dispose();
EncoderParameters encoderParams = new EncoderParameters(1);
encoderParams.Param[0] = new EncoderParameter(Encoder.Quality, (long) this.ImgQuality);
ImageCodecInfo encoder = ImageCodecInfo.GetImageEncoders()[(int) this.OutputFormat];
MemoryStream stream = new MemoryStream();
image2.Save(stream, encoder, encoderParams);
byte[] buffer = stream.GetBuffer();
image2.Dispose();
stream.Close();
return buffer;
}
/// <summary>
/// Resizes the specified original image path.
/// </summary>
/// <param name="originalImagePath">The original image path.</param>
/// <param name="resizedImagePath">The resized image path.</param>
public void Resize(string originalImagePath, string resizedImagePath)
{
System.Drawing.Image image;
try
{
image = System.Drawing.Image.FromFile(originalImagePath);
}
catch
{
if (!File.Exists(originalImagePath))
{
throw new Exception("File " + originalImagePath + " doesn't exist; resize failed.");
}
throw new Exception("File " + originalImagePath + " is not a valid image file or No read permission on the file; resize failed.");
}
System.Drawing.Image image2 = this.Resize(image);
image.Dispose();
EncoderParameters encoderParams = new EncoderParameters(1);
encoderParams.Param[0] = new EncoderParameter(Encoder.Quality, (long) this.ImgQuality);
ImageCodecInfo encoder = ImageCodecInfo.GetImageEncoders()[(int) this.OutputFormat];
try
{
image2.Save(resizedImagePath, encoder, encoderParams);
}
catch (Exception exception)
{
string userName;
try
{
userName = Environment.UserName;
}
catch
{
userName = null;
}
if (String.IsNullOrEmpty( userName))
{
userName = "'ASPNET' or 'Network Service'";
}
userName = userName + " windows account";
throw new Exception("Could not save resized image to " + resizedImagePath + "; resize failed.\r\n" + exception.Message + "\nTry the following:\r\n1. Ensure that " + resizedImagePath + " is a valid file path.\r\n2. Ensure that the file " + resizedImagePath + " is not already being used by another process.\r\n3. Ensure that " + userName + " has write/modify permission on " + resizedImagePath + " file.\r\n");
}
finally
{
image2.Dispose();
}
}
/// <summary>
/// Resizes the specified posted file.
/// </summary>
/// <param name="postedFile">The posted file.</param>
/// <param name="resizedImagePath">The resized image path.</param>
public void Resize(HttpPostedFile postedFile, string resizedImagePath)
{
postedFile.SaveAs(resizedImagePath);
this.Resize(resizedImagePath);
}
public int ImgQuality
{
get
{
return this._imgQuality;
}
set
{
if ((value < 2) || (value > 100))
{
this._imgQuality = 80;
}
else
{
this._imgQuality = value;
}
}
}
/// <summary>
/// Gets or sets the max height.
/// </summary>
/// <value>The max height.</value>
public int MaxHeight
{
get
{
return this._maxHeight;
}
set
{
this._maxHeight = value;
}
}
/// <summary>
/// Gets or sets the max width.
/// </summary>
/// <value>The max width.</value>
public int MaxWidth
{
get
{
return this._maxWidth;
}
set
{
this._maxWidth = value;
}
}
/// <summary>
/// Gets or sets the output format.
/// </summary>
/// <value>The output format.</value>
public PAB.ImageResizer.ImageFormat OutputFormat
{
get
{
return this._outputFormat;
}
set
{
this._outputFormat = value;
}
}
}
}
To use this, you can apply it's Resize method directly to the HttpPostedFile object:
if (FileUpload1.HasFile)
{
PAB.ImageResizer.ImageResizer resizer = new PAB.ImageResizer.ImageResizer();
resizer.MaxHeight = int.Parse(txtMaxHeight.Text);
resizer.MaxWidth = int.Parse(txtMaxWidth.Text);
resizer.ImgQuality = 100;
resizer.OutputFormat = PAB.ImageResizer.ImageFormat.Gif;
byte[] bytes = resizer.Resize(FileUpload1.PostedFile);
File.WriteAllBytes(Server.MapPath("~/test.gif"), bytes);
Response.Redirect("Default.aspx",true);
}
Then you simply save the new image file. You can even specify the Image Format you
want - Bmp, Gif, Jpeg, or Png.
I have put in several overloads of the Resize method that allow you to load an image
from a path and resize it, along with resizing from an HttpPostedFile object
directly after an upload.
The downloadable Visual Studio 2010 Solution has a sample ASP.NET project with a web page that will allow you to upload an image,
have it resized, and it will then display the saved image on the page.
Popularity (3682 Views)
 |
| Biography - Peter Bromberg |
Peter Bromberg is a C# MVP, MCP, and .NET expert who has worked in banking, financial and telephony for over 20 years. Pete focuses exclusively on the .NET Platform, and currently develops SOA and other .NET applications for a Fortune 500 clientele. Peter enjoys producing digital photo collage with Maya,playing jazz flute, the beach, and fine wines. You can view Peter's UnBlog and IttyUrl sites.
|  |
|
|
Article Discussion: ASP.NET HttpPostedFile Image Resizer
Axel Rietschin replied
to Peter Bromberg at Friday, September 24, 2010 9:46 AM
Great article, except that "Classes within the System.Drawing namespace are not supported for use within a Windows or ASP.NET service. Attempting to use these classes from within one of these application types may produce unexpected problems, such as diminished service performance and run-time exceptions."
http://msdn.microsoft.com/en-us/library/system.drawing.aspx
Peter Bromberg replied
to Axel Rietschin at Friday, September 24, 2010 9:46 AM
Well, then you have a choice: If you need to do this in a Windows Service or webservice, either find a different way, or use the System.Drawing namespace and do plenty of testing on it to ensure that it works for you.
Axel Rietschin replied
to Peter Bromberg at Friday, September 24, 2010 9:46 AM
Please not that these were not my words. I quoted MSDN, which says so in a yellow box with a bold "Caution" title at the top of the page. As fasr as I know the only supported way to manipulate images in ASP.NET is through the use of System.Windows.Media.Imaging.
Peter Bromberg replied
to Axel Rietschin at Friday, September 24, 2010 9:46 AM
I'm aware that the words you quoted are from a cautionary not in the MSDN library. I have used the code in this article many times in many different scenarios without problems, including the provided sample which does indeed use ASP.NET. It would be an interesting exercise to rewrite it using the System.Windows.Media.Imaging namespace.
Ismael replied
to Peter Bromberg at Friday, September 24, 2010 9:46 AM
Dude thats a really nice class, Im already using it in my webiste