Measuring the Size of Uploaded Images

In an earlier snippet I showed you how to measure the size of an image on disk. In a more recent post I explained how to work with an in-memory representation of an uploaded file and attach it to an e-mail message.

If you combine the two concepts you end up with a solution that allows you to check the dimensions of an uploaded file, so you can reject it if it doesn't have the correct dimensions before you save it to disk.

Introduction

It's not uncommon that you want to check the dimensions of an image that a user uploads to your web site. For example, you may want to check the size of an uploaded banner in an advertising web site, or check the size of an image that is shown in a news article. You could, of course, just allow any uploaded image and resize it on the fly, but in many cases you end up with distorted images because they have been resized with incorrect proportions. So, depending on your requirements, it can be a good idea to check the dimensions of the image, and reject the uploaded file if it doesn't meet your requirements. By checking the dimensions of the uploaded file before it's saved to disk, you save yourself the trouble from deleting the temporary image when it doesn't meet the specifications.

Fortunately, this is all quite easy to accomplish. The code download at the end of the article contains a small web site with a fully working example in both VB.NET and C#. The web site contains a web.config file with two appSettings keys for the required dimensions:

<appSettings>
  <add key="RequiredHeight" value="184"/>
  <add key="RequiredWidth" value="370"/>
</appSettings>		  

The values for the height and width are arbitrary in the sample application and can easily be changed to meet your requirements. These values are read and stored in private variables in the page when it is posted back (that is, when a file has been uploaded) with the following code (I am showing the C# version here, but you can find similar code for VB.NET in the demo application which you can download at the end of this article):

if (Page.IsPostBack)
{
  height = Convert.ToInt32(
       ConfigurationManager.AppSettings.Get("RequiredHeight"));
  width = Convert.ToInt32(
       ConfigurationManager.AppSettings.Get("RequiredWidth"));
}

These values are used to validate the dimensions of the image, which is shown later.

The markup of the demo page contains an <asp:FileUpload> control, a Button and a number of validator controls, used to ensure the user has selected a file and to provide feedback about the uploaded file and whether it meets the validation rules.

When the user has selected a file and clicked the Upload button, the following code is triggered:

Page.Validate();
if (Page.IsValid)
{
  if (FileUpload1.HasFile)
  {
    string extension = Path.GetExtension(FileUpload1.PostedFile.FileName);
    switch (extension.ToLower())
    {
      // Only allow uploads that look like images.
      case ".jpg":
      case ".jpeg":
      case ".gif":
      case ".bmp":
        try
        {
          if (ValidateFileDimensions())
          {
            string fileName = Path.GetFileName(
                FileUpload1.PostedFile.FileName);
            string saveAsName = Path.Combine(
                Server.MapPath("~/Uploads/"), fileName);
            FileUpload1.PostedFile.SaveAs(saveAsName);
            lblSucces.Visible = true;
          }
          else
          {
            valInvalidDimensions.IsValid = false;
            valInvalidDimensions.ErrorMessage = 
              String.Format(valInvalidDimensions.ErrorMessage, 
              height, width);
          }
        }
        catch
        {
          // Unable to read the file dimensions. 
          // The uploaded file is probably not an image.
          valInvalidFile.IsValid = false;
        }
        break;

      default: // The uploaded file has an incorrect extension
        valInvalidFile.IsValid = false;
        break;
    }
  }
}  

The code first checks if a file has been uploaded by checking the HasFile property of the FileUpload control. It then proceeds to check the extension of the uploaded file to see if it's an image or not. You can add or remove case blocks to the switch statement to change the type of files that your users are allowed to upload.

When the uploaded file looks like an image, the method ValidateFileDimensions (shown later) is called to check the dimensions of the uploaded image. If this method returns true, the image meets the specifications and it is saved to disk using the SaveAs method of the PostedFile. If the image has incorrect dimensions, the CustomValidator called valInvalidDimensions is shown to the user. Notice how String.Format is used to embed the required height and width into the ErrorMessage of the validator. In the markup, the ErrorMessage property contains two placeholders that are replaced by String.Format to inject the dimensions in the message:

<asp:CustomValidator 
  ID="valInvalidDimensions" 
  runat="server" 
  ErrorMessage="The image you uploaded has incorrect dimensions. 
    Please select a file with a height of {0}px and a width of {1}px." 
  Display="Dynamic" 
  EnableViewState="false">
</asp:CustomValidator>  

The most important part of the sample page is the ValidateFileDimensions method which is remarkably simple:

public bool ValidateFileDimensions()
{
using (System.Drawing.Image myImage =
System.Drawing.Image.FromStream(FileUpload1.PostedFile.InputStream))
{
return (myImage.Height == height && myImage.Width == width);
}
}

This code creates a new Image object by calling Image.FromStream and passing it the InputStream property of the PostedFile. This creates an in-memory representation of the image which exposes properties like Height and Width. Those are then used to check the dimensions of the image against the required height and width fields. The method returns true when the image has the exact same dimensions as specified in the private height and width fields. Otherwise it returns false. When the uploaded file doesn't contain a valid image at all, Image.FromStream raises an exception which is handled in the calling code.

The code contains a using block to ensure that the image is disposed of as soon as it's not needed anymore.

Notice I am prefixing the Image class with its full System.Drawing namespace to avoid name collisions with the Image class from the System.Web.UI.WebControls namespace which is imported by default.

Summary

Checking the dimensions of an image that is uploaded by your users is useful in many situations. Being able to check the image before it's even saved to disk is even better, as it frees you from deleting invalid images after they have been uploaded. With the code from this article you can now perform the validation while the image is still in memory and only save it to disk when it meets your requirements.

Further Reading

Download Files

Source Code for this Article The download contains a working example in both C# and VB.NET.

Where to Next?

Wonder where to go next? You can read existing comments below or you can post a comment yourself on this article .


Consider making a donation
Please consider making a donation using PayPal. Your donation helps me to pay the bills so I can keep running Imar.Spaanjaars.Com, providing fresh content as often as possible.



Feedback by Other Visitors of Imar.Spaanjaars.Com

On Friday, March 09, 2007 6:33:29 AM priscilla said:
i'm using vb.net 2003 here.
why is it the  [ConfigurationManager].AppSettings.Get("RequiredHeight"));
the ConfigurationManager got error, it says ConfigurationManager is not declared. The frame work i'm using is 1.1 does this affects it?
On Friday, March 09, 2007 7:00:58 AM Imar Spaanjaars said:
Hi priscilla,

Yes, that's what affecting it. The code you're having problems with is new in .NET 2.0. In .NET 1.x you can use this:

System.Configuration.ConfigurationSettings.AppSettings["RequiredHeight"];

Cheers,

Imar
On Friday, March 09, 2007 2:10:01 PM priscilla said:
=) thanks loads!! it works!
On Monday, April 09, 2007 8:21:30 AM Radiant said:
Hi,

This article was very useful, but con't we save the image file with our specified size of width and height.

Thanks
Radiant
On Monday, April 09, 2007 8:44:04 AM Imar Spaanjaars said:
Hi Radiant,

Yes you can. .NET has good support for reszing images. Search Google for

resize image asp.net

to find some useful articles and code.

Cheers,

Imar
On Tuesday, May 29, 2007 1:34:53 PM Nagendra Prasad said:
This will work fine, infact i have also done it,
But i am facing a probolem after the browse our image for upload, i want to show the image in Browser before the click on Upload button.
How we can do it.

So End  User make aconfirmation this is the right image,a nd now i should upload it else End User Browse another image.
On Tuesday, May 29, 2007 7:23:11 PM Imar Spaanjaars said:
Hi Nagendra,

You can show the uploaded image on an intermediate page and let the user choose Yes or No to further process it.

Alternatively, you may get away with using JavaScript to display the image at the client, based on the file the user has selected. Not sure if you run into security issues with that solution though.

Imar
On Wednesday, May 30, 2007 5:06:49 AM Nagendra Prasad said:
Hi Imar,

Thanks for your comments, but i was not intrigued by the idea of viewing the images after the upload. I wanted to view the images as soon as I select them from my hard drive. This will give me a better idea of what I am about to upload. Now let me with code if possible how to create a simple page that allows me to view the image as soon as I select it from my hard drive.
On Wednesday, May 30, 2007 9:14:04 AM Imar Spaanjaars said:
Hi Nagendra,

Like I said in my previous message: "you may get away with using JavaScript to display the image at the client, based on the file the user has selected"

I don't have any code for that right now so you'll have to Google a bit...

Imar
On Wednesday, May 30, 2007 10:18:49 AM Nagendra Prasad said:
Hi Imar,

Thanks for your comments and it is good news for me as well as other(s) having the same requirementslike me.
I got a URL pls. follow it.
http://gridviewguy.com/ArticleDetails.aspx?articleID=229

Regards,
Nagendra
On Friday, October 19, 2007 11:30:39 PM C.T. said:
hello, great article, i m your new reader.

here is some code that can view the local image before upload
-----------------------
[form name="form5" id="form5" method="post" action="#"]
[input type="file" name="file5" id="file5"
onchange="preview5()"/]
[/form]
[script type="text/javascript"]
function preview5(){
    var x = document.getElementById("file5");
    if(!x || !x.value) return;
    var patn = /\.jpg$|\.jpeg$|\.gif$/i;
    if(patn.test(x.value)){
      var y = document.getElementById("img5");
      if(y){
        y.src = 'file://localhost/' + x.value;
      }else{
        var img=document.createElement('img');
        img.setAttribute('src','file://localhost/'+x.value);
        img.setAttribute('width','120');
        img.setAttribute('height','90');
        img.setAttribute('id','img5');
        document.getElementById('form5').appendChild(img);
      }
    }else{
      alert("not a image");
    }
}
[/script]
-----------------------
On Wednesday, February 17, 2010 10:03:14 AM o_o said:
Post a very large image file and (for example a black 100k x 100k tiff) and you'll get an out of memory exception. yes we have images that are that big.
On Wednesday, February 17, 2010 3:13:05 PM Imar Spaanjaars said:
Hi o_o,

Take a lok at this quote:

>>  This creates an in-memory representation of the image which exposes properties like Height and Width.

So, the entire image is read which can indeed cause out of memory exceptions. You may need to look at third party components that can determine the size without reading the entire image into memory at once.

Cheers,

Imar
On Saturday, September 25, 2010 1:03:17 PM matt said:
hi,
on my site I have a div of width 500px. Within the div I have an asp.net image control with a pre defined height of 300.

As long as users upload images less than 500px in WIDTH I am fine and the image displays ok. If the image is + 500px then it messes up by page format.

COuld you confirm the code above will provide me with solution and demonstrate it here.

I just want to check the width and display an error message if to wide  - the image height does not matter.

thank you
On Saturday, September 25, 2010 2:04:08 PM Imar Spaanjaars said:
Hi matt,

Not sure I understand why you're asking this. Isn't this exactly what this article is about? Have you tried it?

Imar

Talk Back! Comment on Imar.Spaanjaars.Com

I am interested in what you have to say about this article. Feel free to post any comments, remarks or questions you may have about this article. The Talk Back feature is not meant for technical questions that are not directly related to this article. So, a post like "Hey, can you tell me how I can upload files to a MySQL database in PHP?" is likely to be removed. Also spam and unrealistic job offers will be deleted immediately.

When you post a comment, you have to provide your name and the comment. Your e-mail address is optional and you only need to provide it if you want me to contact you. It will not be displayed along with your comment. I got sick and tired of the comment spam I was receiving, so I have protected this page with a simple calculation exercise. This means that if you want to leave a comment, you'll need to complete the calculation before you hit the Post Comment button.

If you want to object to a comment made by another visitor, be sure to contact me and I'll look into it ASAP. Don't forget to mention the page link, or the QuickDocId of the document.

For more information about the Talk Back feature, check out this news item.