12 May, 2010

How To: Creating Thumbnail Images

Introduction
Web site image galleries can be an effective method of communicating with visitors.  Although images may enhance a site, you must still be aware of the penalties associated with slow download times.  A nice compromise to this situation is to present images as thumbnails.  This way, a visitor will be able to browse your thumbnail gallery, selecting only those images they find interesting.  This article shows how to create thumbnail images, which speed things up and make the visit more enjoyable.
The ASP.NETPage
Normal code for displaying images in ASP.NETincludes an Image control on the page, decorated with an ImageUrl attribute with the URL of the picture file you want to display.  The tricky part is translating that picture from full size to thumbnail.  The method we use is by specifying a web page URL for the ImageUrl attribute, which is not immediately intuitive (Listing 1).
Listing 1: ASP.NETPage to Display Thumbnail Image: Thumbnail.aspx
<asp:Imagerunat="server" ImageUrl="MakeThumbnail.aspx?file=fall800.jpg"/>
Think of the MakeThumbnail.aspx web page as a program, rather than the visible representation of an ASP.NETpage you're accustomed to.  In that context, we're simply sending it a parameter named file, which contains fall800.jpg as it's value.  The MakeThumbnail.aspx page will return the thumbnail representation of the full size picture from the file name submitted.  Since the MakeThumbnail.aspx page will not appear on any screen, it only needs a Page directive (Listing 2) with a reference to it's Codebehind file.
Listing 2: ASP.NETPage to Create a Thumbnail Image: MakeThumbnail.aspx
    <%@ Page language="c#" Codebehind="MakeThumbnail.aspx.cs" Inherits="Thumbnail.MakeThumbnail" %>
The Codebehind page
The MakeThumbnail.aspx page is as simple as can be, specifying the Codebehind page and class it Inherits from.  There's no need for anything more since there's no reason for it to display.  The real work of creating the thumbnail image is in the Page_Load event of the Codebehind page MakeThumbnail.aspx.cs (Listing 3).
Listing 3: Code  to Create a Thumbnail Image: MakeThumbnail.aspx.cs

   1:  ///<summary>
   2:  ///Creates a thumbnail image from a file spec in the calling URL.
   3:  ///</summary>
   4:  publicclass MakeThumbnail : System.Web.UI.Page
   5:  {
   6:      private void Page_Load(object sender, System.EventArgs e)
   7:      {
   8:          // get the file name -- fall800.jpg
   9:          string file = Request.QueryString["file"];
  10:   
  11:          // create an image object, using the filename we just retrieved
  12:          System.Drawing.Image image = System.Drawing.Image.FromFile(Server.MapPath(file));
  13:   
  14:          // create the actual thumbnail image
  15:          System.Drawing.Image thumbnailImage = image.GetThumbnailImage(64, 64, new 
                                System.Drawing.Image.GetThumbnailImageAbort(ThumbnailCallback), IntPtr.Zero);
  16:   
  17:          // make a memory stream to work with the image bytes
  18:          MemoryStream imageStream = new MemoryStream();
  19:   
  20:          // put the image into the memory stream
  21:          thumbnailImage.Save(imageStream, System.Drawing.Imaging.Imageformat.Jpeg);
  22:   
  23:          // make byte array the same size as the image
  24:          byte[] imageContent = new Byte[imageStream.Length];
  25:   
  26:          // rewind the memory stream
  27:          imageStream.Position = 0;
  28:   
  29:          // load the byte array with the image
  30:          imageStream.Read(imageContent, 0, (int)imageStream.Length);
  31:   
  32:          // return byte array to caller with image type
  33:          Response.ContentType = "image/jpeg";
  34:          Response.BinaryWrite(imageContent);
  35:      }
  36:   
  37:      ///<summary>
  38:      ///Required, but not used
  39:      ///</summary>
  40:      ///<returns>true</returns>
  41:      public bool ThumbnailCallback()
  42:      {
  43:          return true;
  44:      }
  45:   
  46:      // ... non-applicable infrastructure code removed for clarity ...
  47:   
  48:  }
  49:   
After getting the file name and creating an Image from this file, Listing 3 performs the call to the GetThumbnailImage() method of the Image object, as shown below:
        System.Drawing.Image thumbnailImage = image.GetThumbnailImage(64, 64, new System.Drawing.Image.GetThumbnailImageAbort(ThumbnailCallback), IntPtr.Zero);
Given an Image object, you can call the GetThumbnailImage() method to render a new Image object of the size you want.  The first two parameters are the width and height, respectively.  The next two parameters are not used and have no purpose.  However, they must be included because the GetThumbnailImage() method signature requires their presence.
A byte[] with the image data is required for returning to the caller.  Since the Image object doesn't directly support this, we have to perform a couple translations to get the image data into the proper format.  Here's the sequence:

  1. Create a MemoryStream object.

  2. Save the Image object into the MemoryStream.

  3. Write the MemoryStream into a byte array.
The code (Listing 3) after the GetThumbnailImage() method call is commented to reflect these steps.
Remember to set the ContentType property of the Response object before sending the byte[] back to the caller.  In Listing 3, I hard coded this.  If an application works with multiple image types, you can handle this by (1) parsing the extension from the file name or (2) checking the Rawformat property of the Image object, which returns an Imageformat object.
Source Code
Thumbnails.zip - Visual Studio .NETSolution with full source code for this article.
Summary
presenting thumbnail images is an effective way to reduce bandwidth to speed up image browsing for visitors.  This article covered how to obtain a thumbnail image by specifying an Image control on a web page that referenced another web page.  The other web page produced the thumbnail image and returned it in the Response object for the calling web page to display.

No comments:

Post a Comment

Suggestions are invited from readers