Resizing uploaded image

One of my readers asked for example about my image resizing routine. Here you can find example and also some notes about my code design solution.

Why I used streams?

First, the resizing method is thought for web applications. Second, using streams is more general solution that using file paths (you don’t want to save files to hard disc if you get them from file upload and save to database). Web application may get image files from following sources:

  • files located on web server hard disc,
  • file uploads,
  • web services,
  • BLOB field of database table.

For first two sources we can ask stream directly. For the other two we can create memory stream and write byte array with image bytes to it.

Streams are useful also for output. Output stream may be file, response output stream or memory stream by example. And you can use also other streams that you need. In the case of file stream the resized image is written to file. In the case of response output stream the resized image is written back to browser. If you use memory stream then you may convert it to byte array so you can send image to database or post to web service.

Example

Let’s see now simple example that resizes images and uses streams. We have Resize.aspx page that accepts file uploads. If image is uploaded then it resizes it to 50% and shows it to user. If error occurs then error message is printed out.

protected void Page_Load(object sender, EventArgs e)
{
   
if
(Request.Files.Count > 0)
    {
        ShowPreview();
       
return
;
    }
}

protected void ErrorMessage(string
error)
{
   
var outputBuilder = new StringBuilder
();
    outputBuilder.Append(
"<html><head></head><body>"
);
    outputBuilder.Append(
"<span>"
);
    outputBuilder.Append(error);
    outputBuilder.Append(
"</span>"
);
    outputBuilder.Append(
"</body></html>"
);

   
try
    {
        Response.Clear();
        Response.ContentType =
"text/html"
;
        Response.Write(outputBuilder);
        Response.End();
    }
   
catch
{ }
}

protected void
ShowPreview()
{
   
var
file = Request.Files[0];
   
try
    {
        Response.Clear();
        Response.ContentType = file.ContentType;
        ResizeImage(0.5, file.InputStream, Response.OutputStream);
        Response.End();
    }
   
catch (ArgumentException
)
    {
        ErrorMessage(
"Unknown image file!"
);
    }
   
catch (ThreadAbortException
)
    {

    }
   
catch (Exception
ex)
    {
        ErrorMessage(
"Unknown error: "
+ ex);
    }
}

private void ResizeImage(double scaleFactor, Stream fromStream, Stream
toStream)
{
   
var image = Image
.FromStream(fromStream);
   
var newWidth = (int
)(image.Width * scaleFactor);
   
var newHeight = (int
)(image.Height * scaleFactor);
   
var thumbnailBitmap = new Bitmap
(newWidth, newHeight);

   
var thumbnailGraph = Graphics
.FromImage(thumbnailBitmap);
    thumbnailGraph.CompositingQuality =
CompositingQuality
.HighQuality;
    thumbnailGraph.SmoothingMode =
SmoothingMode
.HighQuality;
    thumbnailGraph.InterpolationMode =
InterpolationMode
.HighQualityBicubic;

   
var imageRectangle = new Rectangle(0, 0, newWidth, newHeight);
    thumbnailGraph.DrawImage(image, imageRectangle);

    thumbnailBitmap.Save(toStream, image.RawFormat);

    thumbnailGraph.Dispose();
    thumbnailBitmap.Dispose();
    image.Dispose();
}

You can use this resizing method also in desktop applications and web services.

Gunnar Peipman

Gunnar Peipman is ASP.NET, Azure and SharePoint fan, Estonian Microsoft user group leader, blogger, conference speaker, teacher, and tech maniac. Since 2008 he is Microsoft MVP specialized on ASP.NET.

    16 thoughts on “Resizing uploaded image

    • April 3, 2009 at 12:43 pm
      Permalink

      Hi,

      This codes doesnt work.

    • April 3, 2009 at 12:47 pm
      Permalink

      Why don’t you just use the built in Image.GetThumbnailImage method for creating thumbnails…?!

    • April 3, 2009 at 1:39 pm
      Permalink

      Hi.
      I’m a great fan of your blog. I like your ResizeImage method but I’m also a great fan of ‘using’. So I will rewrite your method as :

      private void ResizeImage(double scaleFactor, Stream fromStream, Stream toStream)
      {
      using (var image = Image.FromStream(fromStream))
      {
      var newWidth = (int)(image.Width * scaleFactor);
      var newHeight = (int)(image.Height * scaleFactor);
      var imageRectangle = new Rectangle(0, 0, newWidth, newHeight);

      using (var thumbnailBitmap = new Bitmap(newWidth, newHeight))
      {
      using (var thumbnailGraph = Graphics.FromImage(thumbnailBitmap))
      {
      thumbnailGraph.CompositingQuality = CompositingQuality.HighQuality;
      thumbnailGraph.SmoothingMode = SmoothingMode.HighQuality;
      thumbnailGraph.InterpolationMode = InterpolationMode.HighQualityBicubic;
      thumbnailGraph.DrawImage(image, imageRectangle);

      thumbnailBitmap.Save(toStream, image.RawFormat);
      }
      }
      }
      }

      Because if I pass 0 as scaleFactor – newWidth and newHeight will be 0 and 0 respectively. So the constructor of Bitmap will throw an exception and image.Dispose(); will be not called. The version with ‘using’ doesn’t have this flaw.
      My 2 cents.

    • April 4, 2009 at 9:39 pm
      Permalink

      Thanks, Petar! Your suggestion is very good! :)

    • February 4, 2010 at 9:06 pm
      Permalink

      This works very well. Thank you for sharing the example.

    • March 12, 2010 at 2:12 pm
      Permalink

      Thanks a lot.
      This post have helped me a lot.

      This 3 line of code i was missing

      thumbnailGraph.CompositingQuality = CompositingQuality.HighQuality;

      thumbnailGraph.SmoothingMode = SmoothingMode.HighQuality;

      thumbnailGraph.InterpolationMode = InterpolationMode.HighQualityBicubic;

    • May 27, 2010 at 6:31 pm
      Permalink

      Thanks a lot.

      This post have helped me a lot.

    • September 23, 2010 at 7:59 pm
      Permalink

      Hi Gunnar,

      I think the possibilities with your suggested code are awesome, I just have difficulties using it. Please see this discussion on your post here: http://forums.asp.net/p/1605692/4095389.aspx

      If you have ANY hints/tips, help me out! :)

      Hopefully I can soon implement this code in my applications, since its the best one I’ve seen out there!

    • October 4, 2010 at 4:08 am
      Permalink

      hi gunnar ,

      i am new bie to .net……

      I am getting images from webservices. when i try to resize the image, i am losing quality .. please help me for this

    • October 20, 2010 at 7:58 pm
      Permalink

      I really like this example but how would I go about saving this to file or displaying it in an image tag once it has been resized? Basically I want to attempt impliment this on a site giving the user the ability to adjust the image on the fly prior to saving to file.

    • October 20, 2010 at 8:30 pm
      Permalink

      Nevermind on my comment above I read through the forum and found your example. Thanks a bunch, this is great.

    • October 27, 2010 at 9:50 pm
      Permalink

      Running the attached project file Experiments.ResizeImage.zip, the generated thumbnail if zoomed(reized) using the Windows Photo Viewer does not give the same image(original.jpg). This shows that the thumbnail has some information missing.

    • October 27, 2010 at 9:59 pm
      Permalink

      Even if I resize the generated thumbnail(153 height and 204 width) with a scale factor of 10 (To generate image with same dimensions as original(2048 width and 1536 height). The new generated image is bad.

    • October 29, 2010 at 2:10 pm
      Permalink

      What are the names spaces required in order to compile the above code? I have imported System.Drawing but it is not compiling for me. And i wnat to resize image when admin uploads in my site, so how do i call the above method?

    • July 25, 2012 at 8:09 pm
      Permalink

      thanks for your post

      finally what is the best way to resize image ? BitmapSource ?
      can some one help me to find resize function in vb ?

    Leave a Reply

    Your email address will not be published. Required fields are marked *