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.NET Page

Normal code for displaying images in ASP.NET includes 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.NET Page to Display Thumbnail Image: Thumbnail.aspx
<asp:Image runat="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.NET page 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.NET Page 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 theCodebehind page MakeThumbnail.aspx.cs (Listing 3).

Listing 3: Code to Create a Thumbnail Image: MakeThumbnail.aspx.cs
/// <summary>
/// Creates a thumbnail image from a file spec in the calling URL.
/// </summary>
public class MakeThumbnail : System.Web.UI.Page
{
   private void Page_Load(object sender, System.EventArgs e)
   {
       // get the file name -- fall800.jpg
       string file = Request.QueryString["file"];

       // create an image object, using the filename we just retrieved
       System.Drawing.Image image = System.Drawing.Image.FromFile(Server.MapPath(file));

       // create the actual thumbnail image
       System.Drawing.Image thumbnailImage = image.GetThumbnailImage(64, 64, newSystem.Drawing.Image.GetThumbnailImageAbort(ThumbnailCallback), IntPtr.Zero);

       // make a memory stream to work with the image bytes
       MemoryStream imageStream = new MemoryStream();

       // put the image into the memory stream
       thumbnailImage.Save(imageStream, System.Drawing.Imaging.Imageformat.Jpeg);

       // make byte array the same size as the image
       byte[] imageContent = new Byte[imageStream.Length];

       // rewind the memory stream
       imageStream.Position = 0;

       // load the byte array with the image
       imageStream.Read(imageContent, 0, (int)imageStream.Length);

       // return byte array to caller with image type
       Response.ContentType = "image/jpeg";
       Response.BinaryWrite(imageContent);
   }

   /// <summary>
   /// Required, but not used
   /// </summary>
   /// <returns>true</returns>
   public bool ThumbnailCallback()
   {
       return true;
   }

   // ... non-applicable infrastructure code removed for clarity ...

}

After getting the file name and creating an Image from this file, Listing 3 performs the call to the GetThumbnailImage() method of theImage object, as shown below:

       System.Drawing.Image thumbnailImage = image.GetThumbnailImage(64, 64, newSystem.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 .NET Solution 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.

Follow Joe Mayo on Twitter.