ASP.NET In-Memory Image Control with Built-In Resizing of Posted File

By Peter Bromberg
Access over 40 UI widgets with everything from interactive menus to rich charts.

A custom control that allows developers to assign an image to a page 100% from memory as well as providing resizing capability for uploaded images.

About six years ago, I published this article on our site which shows how to construct an ASP.NET custom Image control that does not require a file path - you can simply assign a bitmap to the control's .BitMap property from memory, and it can be persisted to the control through postbacks as well - either via Cache or Session.

At eggheadcafe.com we often get forum posts by users asking how they can display images from a database without having to first save the image on the filesystem in order to populate the Image Control's ImageUrl property, and so I thought, since the original code for this is quite old, that it would be a good idea to revisit it.

I redid the control for .NET Framework 4.0 and also added my Image Resizer code from this article.

Let's have a look at some code. First, we'll show the ASP.NET "demo page":

<form id="Form1" method="post" runat="server">
<pab:ImageControl id="ImageControl1" runat=server></pab:ImageControl>
<asp:FileUpload ID="FileUpload1" runat="server" />
<asp:Button ID="btnUpload" runat="server" onclick="btnUpload_Click"
Text="Upload" />
Width: <asp:TextBox ID="txtWidth" runat="server" Width="36px"></asp:TextBox>
Height: <asp:TextBox ID="txtHeight" runat="server" Width="38px"></asp:TextBox>
<asp:Button ID="btnResize" runat="server" onclick="btnResize_Click"
Text="Resize" />
<asp:Button ID="btnSave" runat="server" onclick="btnSave_Click" Text="Save" />
<asp:Label ID="statusLabel" runat="server"></asp:Label>
</form>

I have one of my ImageControls, an Upload button, an ASP.NET FileUpload Control, a TextBox for Width and one for Height, a Resize Button, and a Save button.

And the codebehind:

protected void btnUpload_Click(object sender, EventArgs e)
         {
             if (FileUpload1.HasFile)
             {
                 try
                {
                    ImageControl1.PersistenceType = Persistence.Cache;
                    ImageControl1.Bitmap =
                        (Bitmap) Image.FromStream(new MemoryStream(FileUpload1.FileBytes));
                      Session["fileName"] = FileUpload1.FileName;
                    txtWidth.Text = ImageControl1.Bitmap.Width.ToString();
                    txtHeight.Text = ImageControl1.Bitmap.Height.ToString();
                    statusLabel.Text = "Upload status: File uploaded!";
                }
                catch (Exception ex)
                {
                    statusLabel.Text = "Upload status: The file could not be uploaded. The following error occured: " + ex.Message;
                 }

                 // Uncomment the following lines to resize and save the image immediately upon upload as 80X120
                /*
                 HttpPostedFile file = FileUpload1.PostedFile;
                ImageResizer resizer = new ImageResizer(80,120,100);
                resizer.OutputFormat = System.Drawing.Imaging.ImageFormat.Png;
                 // fix the filename to have the correct extension as indicated by the above line
                string fname = FileUpload1.FileName.Substring(0, FileUpload1.FileName.LastIndexOf("."));
                fname += "." + resizer.OutputFormat.ToString();
                resizer.Resize(file, Server.MapPath(fname));
                 */
             }
         }


         protected void btnResize_Click(object sender, EventArgs e)
        {
            Bitmap bmp = ImageControl1.Bitmap;
            int maxWidth = int.Parse(txtWidth.Text);
            int maxHeight = int.Parse(txtHeight.Text);
            var resizer = new ImageResizer(maxWidth, maxHeight, 100);
            Image img = resizer.Resize(bmp);
            ImageControl1.Bitmap = (Bitmap) img;
        }

        protected void btnSave_Click(object sender, EventArgs e)
         {
             ImageControl1.Bitmap.Save(Server.MapPath((string) Session["fileName"]));      
}

The btn_Upload_Click handler has your "standard" FileUpload handling. It sets the PersistenceType on the ImageControl, sets the control's Bitmap property to a new MemoryStream created from the FileUpload control's FileBytes property, stores the FileName in Session  for later use, and sets the width and height properties of the uploaded image into the two TextBoxes.

A bit further down in the method body, I show some commented code which would enable you to automatically resize the uploaded image and save it immediately.

In the btnResize_Click handler, we get the uploaded Bitmap and set the maxHeight and maxWidth properties for resizing from the values the user entered into the two TextBoxes, and then we call the resizer's Resize method:

             var resizer = new ImageResizer(maxWidth, maxHeight, 100);
            Image img = resizer.Resize(bmp);

Finally we reset the control''s Bitmap property to the new resized image so the user can see the results:

            ImageControl1.Bitmap = (Bitmap) img;

Lastly, in the btnSave_Click handler, we let the user Save their resized bitmap on the server.

I won't detail all the code for the control; it's all there in the downloadable solution for you to review and play around with.

Download the Visual Studio 2010 Solution that accompanies this article.

Popularity  (3786 Views)