Monday, April 6, 2009

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.

No comments:

Post a Comment