Posts Tagged ‘client side resize’

Flash Based Image Upload For ASP.NET With Client Side Resize

August 11, 2011

Recently, I had to provide a way for internal users to upload images via the company website. The images are usually 12-16 mega pixels and have huge files sizes (>5MB). I needed a way of  resizing the images on the client before uploading and also make it easier for users to upload a batch of images with progessbar.

During my search, I found plupload, an open source upload control which provides many ways of uploading including Flash, Silverlight, Google Gears, BrowserPlus, HTML5 and HTML4. The control provided all the features I needed except that all the examples were in PHP and it took me some time to get it working with ASP.NET. I am writing this post to help anyone else who may want to integrate this control into their ASP.NET websites. The control can be downloaded from the following location

http://www.plupload.com/index.php

After you download and extract the zip file within your website, you would need to add two pages in your project. One of the pages would host the upload control and the other page would receive the uploaded files and save them. I have only used Flash runtime of the control so this example will focus on the Flash runtime.

Here is the markup of the page that will host the Flash runtime of the plupload control.

<%@ Page Language="vb" AutoEventWireup="false" CodeBehind="UploadToCRM.aspx.vb" Inherits="ImageUploader.UploadToCRM" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title>Upload files to CRM</title>
    <link rel="stylesheet" href="js/jquery.plupload.queue/css/jquery.plupload.queue.css" type="text/css" media="screen" />

<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.5.1/jquery.min.js"></script>
<script type="text/javascript" src="http://bp.yahooapis.com/2.4.21/browserplus-min.js"></script>

<script type="text/javascript" src="js/plupload.js"></script>
<script type="text/javascript" src="js/plupload.flash.js"></script>
<script type="text/javascript" src="js/jquery.plupload.queue/jquery.plupload.queue.js"></script>

    <style type="text/css">
        #btnSubmit
        {
            width: 92px;
        }
    </style>

</head>
<body>
    <form id="form1" runat="server">
    <table>
     <tr>
      <td colspan="2">
         <h3>Upload Files To CRM</h3>
      </td>
     </tr>
     <tr>
      <td colspan="2">
       <br />
   	    <div style="float: left; margin-right: 20px">
		 <div id="flash_uploader" style="width: 450px; height: 330px;">Your browser doesn't have Flash installed.</div>
	     </div>
         <br style="clear: both" />
      </td>
     </tr>
     <tr>
      <td colspan="2">
       <asp:Button id="btnSubmit" runat="server" Text="Save" Enabled="false" />
          <asp:Label ID="lblMessage" runat="server" ForeColor="Red"></asp:Label>
      </td>
     </tr>
    </table>
    </form>
    <script type="text/javascript">
        $(function () {
            // Setup flash version
            $("#flash_uploader").pluploadQueue({
                // General settings
                runtimes: 'flash',
                url: 'upload.aspx',
                max_file_size: '10mb',
                chunk_size: '1mb',
                unique_names: true,
                filters: [
			{ title: "Image files", extensions: "jpg" }
		],

                // Resize images on clientside if we can
                resize: { width: 800, height: 600, quality: 90 },

                // Flash settings
                flash_swf_url: 'js/plupload.flash.swf',

                init: { StateChanged: function (up) {
                    // Called when the state of the queue is changed
                    if (up.state == plupload.STOPPED) {
                        $("#btnSubmit").removeAttr("disabled");
                    }
                }
                }

            });

        });

    </script>
</body>
</html>

The code for submit button uses the Request.Form collection to find out the names of files uploaded.

Protected Sub btnSubmit_Click(sender As Object, e As EventArgs) Handles btnSubmit.Click
        If Session("ID") Is Nothing Then
            lblMessage.Text = "You don't seem to have uploaded any pictures."
            Exit Sub
        Else
            Dim FileCount As Integer = Request.Form(Request.Form.Count - 2)
            Dim FileName, TargetName As String
            Try
                Dim Path As String = "\\servername\foldername\"
                Dim StartIndex As Integer
                Dim PicCount As Integer
                For i As Integer = 0 To Request.Form.Count - 1
                    If Request.Form(i).ToLower.Contains("jpg") Then
                        StartIndex = i + 1
                        Exit For
                    End If
                Next
                For i As Integer = StartIndex To Request.Form.Count - 4 Step 3
                    FileName = Request.Form(i)
                    If IO.File.Exists(Path & FileName) Then
                        TargetName = Path & FileName
                        Dim j As Integer = 1
                        While IO.File.Exists(TargetName)
                            TargetName = Path & IO.Path.GetFileNameWithoutExtension(FileName) & "(" & j & ")" & IO.Path.GetExtension(FileName)
                            j += 1
                        End While
                    Else
                        TargetName = Path & FileName
                    End If
                    IO.File.Move(Server.MapPath("Uploads/" & Session("ID") & "/" & FileName), TargetName)
                    PicCount += 1
                Next
                lblMessage.Text = PicCount & IIf(PicCount = 1, " Picture", " Pictures") & " Saved!"
                lblMessage.ForeColor = Drawing.Color.Black
            Catch ex As Exception
                lblMessage.Text = ex.ToString
			End Try
        End If
    End Sub

This code loops through the Request.Form collection and moves each file to the destination folder. Remember that, at this stage, the files have already been uploaded and saved in the “Uploads” folder with a GUID subfolder. This GUID is then saved into the session the link the two pages together.

The code behind (there is nothing special in the aspx) for the page which receives the uploaded files is below

Public Class upload
    Inherits System.Web.UI.Page

    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        If IsNothing(Request.Form("chunk")) = False Then
            If Session("ID") Is Nothing Then
                Session("ID") = Guid.NewGuid.ToString
                IO.Directory.CreateDirectory(Server.MapPath("Uploads/" & Session("ID")))
            End If
            Dim chunk As Integer = Request.Form("chunk")
            Dim chunks As Integer = Request.Form("chunks")
            Dim filename As String = Request.Form("name")
            If chunk = 0 Then
                Request.Files(0).SaveAs(Server.MapPath("Uploads/") & Session("ID") & "/" & Request.Files(0).FileName)
            Else
                Dim OutputStream As New IO.FileStream(Server.MapPath("Uploads/") & Session("ID") & "/" & Request.Files(0).FileName, IO.FileMode.Append)
                Dim InputBytes(Request.Files(0).ContentLength) As Byte
                Request.Files(0).InputStream.Read(InputBytes, 0, Request.Files(0).ContentLength)
                OutputStream.Write(InputBytes, 0, InputBytes.Length - 1)
                OutputStream.Close()
            End If
        End If
    End Sub

End Class

The Flash runtime of the plupload control sends the file in 4 chunks. The “chunk” variable in Form collection holds the current chunk number. The “chunks” variable holds the total number of chunks. If the chunk is 0, this means that the upload of this file has just started so we create the file on the server. If the chunk is greater than 0, this means that another chunk of existing file has been received so we append this chunk to the existing file.

This page is very easy to use for the users and my users (and managers) are very happy with it. I hope this post makes it easier for others to use this great upload control in their ASP.NET websites than it was for me.

Advertisements