[updated] Resize image BEFORE saving to server

[updated]:

Hello again, it seems my post title was a little confusing, apologies to all who have already read the post. I have since corrected the title to reflect this mistake. The purpose of the below script was to save space on the server without requiring the client to have Photoshop (or any Image Editor Software) knowledge, and we found that the below example was the best way to do this. Just to clarify that I'm aware that this solution doesn't help with speeding up the uploading of the image as obviously the client still has to upload the full size image before it is resized. I have found this solution to be very useful for a lot of our clients and hopefully it will be of use to others as well. Again, apologies for the previous mis-communication.

The problem:

I noticed a problem recently with one of our clients Content Management Systems. Unfortunately this particular system was built by the clients previous development company and so wasn't picked up immediately as a serious issue. But although what probably seemed like a sensible thing to do at the time of development turned out to be the source of costing our client more and more money each year with regards to purchasing additional website hosting space.

The problem was to do with how images were being uploaded to the server via their Content Management System. The client would select an image from their hard drive (usually a large digital camera image) and they would upload the selected image to a specified folder on the server. On the front-end of their website the ASP.NET page would then connect to the database, pull out the image URL and would then display the image on the web page, but not before the .NET framework had done it's duty of resizing the image into a thumbnail so the end-user wasn't spanked with a huge file download.

The problem was that after about 3 months of uploading image after image, the client found they were out of server space because each image they were uploading was on average about 8mb - and although the end result (the thumbnail image)  was only a couple of kilobytes in size - the server was being drained of its space by all these large photos being uploaded.

The solution:

Well the solution was simple enough, rather than upload an 8mb image and then resize it for the front-end, we fixed it so that instead the client would select an image from their hard drive to upload and the .NET framework would resize the image into a thumbnail BEFORE saving it onto the server (thus saving server space).

[updated note: although the image is resized before saving to the server, the original file size it still uploaded, so this solution does not speed up the uploading process]

Below is a simple code example I put together. There are only two files "ImageUpload.aspx" and its code-file "ImageUpload.aspx.cs"...

ImageUpload.aspx

<form id="form1" runat="server">

<asp:FileUpload ID="fileUpload" runat="server" />

<br /><br />

<asp:Button ID="uploadButton" runat="server" Text="Upload!" OnClick="UploadFile" />

<br /><br />

<asp:Label ID="label" runat="server"></asp:Label> <br /><br />

<asp:Image ID="Image1" ImageUrl="" runat="server" Visible="false" />

</form>

ImageUpload.aspx.cs

using System;
using System.Collections;
using System.Configuration;
using System.Data;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.IO; // this is for the file upload
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;

public partial class GDI_UploadImage : System.Web.UI.Page
{
     protected void Page_Load(object sender, EventArgs e)
     {
          //
     }

     protected void UploadFile(Object s, EventArgs e)
     {
          // First we check to see if the user has selected a file
          
if (fileUpload.HasFile)
          {
              
// Find the fileUpload control
               string filename = fileUpload.FileName;

              
// Check if the directory we want the image uploaded to actually exists or not
              
if (!Directory.Exists(MapPath(@"Uploaded-Files")))
               {
                    // If it doesn't then we just create it before going any further
                   
Directory.CreateDirectory(MapPath(@"Uploaded-Files"));
               }
               

               // Specify the upload directory
              
string directory = Server.MapPath(@"Uploaded-Files\"); 

              
// Create a bitmap of the content of the fileUpload control in memory
              
Bitmap originalBMP = new Bitmap(fileUpload.FileContent); 

              
// Calculate the new image dimensions
               int origWidth = originalBMP.Width; 
               int origHeight = originalBMP.Height;
               int sngRatio = origWidth / origHeight; 
               int newWidth = 100;
               int newHeight = newWidth / sngRatio;               

              
// Create a new bitmap which will hold the previous resized bitmap
              
Bitmap newBMP = new Bitmap(originalBMP, newWidth, newHeight);

               // Create a graphic based on the new bitmap
               Graphics oGraphics = Graphics.FromImage(newBMP);               

               // Set the properties for the new graphic file
              
oGraphics.SmoothingMode = SmoothingMode.AntiAlias;oGraphics.InterpolationMode = InterpolationMode.HighQualityBicubic;

               // Draw the new graphic based on the resized bitmap
              
oGraphics.DrawImage(originalBMP, 0, 0, newWidth, newHeight);               

               // Save the new graphic file to the server
              
newBMP.Save(directory + "tn_" + filename); 

               // Once finished with the bitmap objects, we deallocate them.
              
originalBMP.Dispose(); 
               newBMP.Dispose()
;
               oGraphics.Dispose()
;               

              
// Write a message to inform the user all is OK
               label.Text = "File Name: <b style='color: red;'>" + filename + "</b><br>"; 
               label.Text +=
"Content Type: <b style='color: red;'>" + fileUpload.PostedFile.ContentType + "</b><br>";
               label.Text +=
"File Size: <b style='color: red;'>" + fileUpload.PostedFile.ContentLength.ToString() + "</b>";

               // Display the image to the user
               Image1.Visible = true;
              
Image1.ImageUrl = @"/Uploaded-Files/tn_" + filename; 
          }
          else
          {
               label.Text =
"No file uploaded!"; 
          }
     }
}

10 Comments

  • this is very nice artile.

  • Thankx author. This helped me.

  • great article. the old file can be deleted from the server by using FileInfo class.

    System.IO.FileInfo file = new System.IO.FileInfo(MapPath(UploadedFileName));
    file.Delete();

  • Thanks for this article. This something I really want to do.

  • Great solution, but I did run into one problem though, since all the dimension valuables were of type int, when sngRatio is really something like 1.6 it is rounded to 1, so some rectangular images end up being square.
    I just used them all as double and converted them back to int at the end. But very good soultion, saved me a lot of time. Thanks :)

  • Hi, i found out your script very useful, but i has issues with resizing dimesions. To solve that i replased the following code...

    // Calculate the new image dimensions
    int origWidth = originalBMP.Width;
    int origHeight = originalBMP.Height;
    int sngRatio = origWidth / origHeight;
    int newWidth = 100;
    int newHeight = newWidth / sngRatio;

    with...

    // Calculate the new image dimensions
    decimal origWidth = originalBMP.Width;
    decimal origHeight = originalBMP.Height;
    decimal sngRatio = origHeight / origWidth;
    int newHeight = 300; //hight in pixels
    decimal newWidth_temp = newHeight / sngRatio;
    int newWidth = Convert.ToInt16(newWidth_temp);

    ...because
    int SngRatio = origHeight / origWidth

  • The code didn't work for me at the begining.

    int newHeight = newWidth / sngRatio; doesn't gives out decimal value which is important, but the whole number.

    To solve that i did the following.

    Part...

    // Calculate the new image dimensions
    int origWidth = originalBMP.Width;
    int origHeight = originalBMP.Height;
    int sngRatio = origWidth / origHeight;
    int newWidth = 100;
    int newHeight = newWidth / sngRatio;

    ...was replaced with...

    // Calculate the new image dimensions
    decimal origWidth = originalBMP.Width;
    decimal origHeight = originalBMP.Height;
    decimal sngRatio = origHeight / origWidth ;
    int newHeight = 300; //hight in pixels
    decimal newWidth_temp = newHeight / sngRatio;
    int newWidth = Convert.ToInt16(newWidth_temp);

  • Hi,
    I would like to thanks because with the help of this code i have solved my big problem.
    Thanks

  • Everyone please replace the // Calculate the new image dimensions code with this code. The code above does not work.

    // Calculate the new image dimensions
    int thumbnailSize = 250;
    int newWidth, newHeight;
    if (originalBMP.Width > originalBMP.Height)
    {
    newWidth = thumbnailSize;
    newHeight = originalBMP.Height * thumbnailSize / originalBMP.Width;
    }
    else
    {
    newWidth = originalBMP.Width * thumbnailSize / originalBMP.Height;
    newHeight = thumbnailSize;
    }

  • The script works perfect.... but there is an issue, it does resize the way it should. The file size is still high compared to what it should be. If I try to create a thumbnail of 150/113 it should be no more than 6 or 7kb, in the above script it produces a file with at least 43kb. Any ideas on how to reduce it more?

Comments have been disabled for this content.