ASP.NET Image Uploading (part I)

Introduction

Is image uploading different from simply file uploading? No, but when creating an image uploading functionality you usually have to perform more operation, than if you application were to receive text files only. Basically, when making an image uploading form, you have to implement the following things:

  • Check if a file is uploaded
  • Check if the uploaded file is an image
  • Check if the uploaded file doesn't exceed a certain size
  • Resize the uploaded images without changing the proportions of the picture
  • Save the image

In this particular tutorial, I'll tell you how to perform the 3 operations, while I'll explain how to check the file size in the next part. Form We need to create a form element that is used for choosing a file, we can do it by using the FileUpload control.

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

After that, we add two CustomValidators that will validate if file upload and the file type, we also add a submit button:

<asp:CustomValidator
  ID="valFile"
  runat="server"
  ErrorMessage="No file uploaded"
  onservervalidate="valFile_ServerValidate"
  Display="Dynamic"
/>
<asp:CustomValidator
  ID="valFileType"
  runat="server"
  ErrorMessage="This isn't not an image"
  onservervalidate="valFileType_ServerValidate"
  Display="Dynamic"
/><br />

<asp:Button
  ID="btnSubmit"
  runat="server"
  Text="Upload"
  onclick="btnSubmit_Click"
/>

Validation

Since, we cannot access the file input with JavaScript, we can perform only server-side validation. First, we should validate if a user has uploaded a file.

protected void valFile_ServerValidate(object source, ServerValidateEventArgs args)
{
    if (!fileImage.HasFile)
    {
        args.IsValid = false;
    }
}
```

There are two ways of validating the file type, the first one is to check the extension and the second one is to check the mime/type. The first one isn't very reliable, because a smart user can change the file extension, besides there are lot of extensions of JPEG images - .jpg, .jpeg, .jpe, while the mime/type is the only - "image/jpeg". So, we'll be using the second way, i.e. we will be checking the mime type. Here is the code we should write:

```csharp
protected void valFileType_ServerValidate(object source, ServerValidateEventArgs args)
{
    if (fileImage.HasFile)
    {
        string[] acceptedTypes = new string[]
        {
            "image/bmp",
            "image/jpeg",
            "image/tiff",
            "image/gif",
            "image/png"
        };

        if (!acceptedTypes.Contains(fileImage.PostedFile.ContentType))
        {
            args.IsValid = false;
        }
    }
}

There is an interesting thing in this code, we use the Contains() extension method, that checks if a string belongs to a collection. Processing Image Upload In order to process image uploading we should simply add some code to the submit button click event handler:

protected void btnSubmit_Click(object sender, EventArgs e)
{
    if (IsValid)
    {
        Bitmap image = ResizeImage(fileImage.PostedFile.InputStream, 200, 400);
        image.Save(Server.MapPath("~/Photos/") + Guid.NewGuid().ToString() + ".jpg", ImageFormat.Jpeg);
    }
}

Resizing

This is the most interesting part of the tutorial. We won't simply resize images, but we also retain their proportions. Here is the code:

private Bitmap ResizeImage(Stream streamImage, int maxWidth, int maxHeight)
{
    Bitmap originalImage = new Bitmap(streamImage);
    int newWidth = originalImage.Width;
    int newHeight = originalImage.Height;
    double aspectRatio = (double)originalImage.Width / (double)originalImage.Height;

    if (aspectRatio <= 1 && originalImage.Width > maxWidth)
    {
        newWidth = maxWidth;
        newHeight = (int)Math.Round(newWidth / aspectRatio);
    }
    else if (aspectRatio > 1 && originalImage.Height > maxHeight)
    {
        newHeight = maxHeight;
        newWidth = (int)Math.Round(newHeight * aspectRatio);
    }

    return new Bitmap(originalImage, newWidth, newHeight);
}

Now, you can compile the project and test it by uploading some of new images and seeing the resized ones on the server.

Conclusion

Image uploading is very common problem. ASP.NET provides great tools for developers to accomplishing this task. In the next part, I'll show you how to validate the file size that can be very tricky sometimes.

Mike Borozdin (Twitter)
21 August 2008

The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way. My personal thoughts tend to change, hence the articles in this blog might not provide an accurate reflection of my present standpoint.

© Mike Borozdin