X

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.

Liked this post? Empower your friends by sharing it!
Categories: ASP.NET Graphics

View Comments (16)

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

  • 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.

  • 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;

  • 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!

  • 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

  • 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.

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

  • 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.

  • 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.

  • 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?

  • 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 ?

Related Post