When you think ASP, think...
Recent Articles
All Articles
ASP.NET Articles
ASPFAQs.com
Message Board
Related Web Technologies
User Tips!
Coding Tips
Search

Sections:
Book Reviews
Sample Chapters
Commonly Asked Message Board Questions
JavaScript Tutorials
MSDN Communities Hub
Official Docs
Security
Stump the SQL Guru!
Web Hosts
XML
Information:
Advertise
Feedback
Author an Article

ASP ASP.NET ASP FAQs Message Board Feedback
 
Print this Page!
Published: Wednesday, January 22, 2003

True Image Resizing

By Scott Mitchell


Introduction


In an article I wrote last week, Displaying a List of Scaled Images, I looked at how to display the images in a directory through an ASP.NET Web page. Next, this article examined how to obtain the height and width of each image by using the Image class in the System.Drawing namespace. This information was used to scale the images so that if the images were beyond a certain height or width, their height and widths were reduced so that the image could be proportioned so that it fit onto a page.

- continued -

One caveat I mentioned in the article, though, was that while the image was being displayed at a different resolution, the image's file size was not changed. That is, I used the <img> tag to do the resizing. For example, if one of the images to display was a file named BigFile.gif, which was 100 KB in size and 400 pixels by 400 pixels, the image would be resized to 200 pixels by 200 pixels by constructing the resulting <img> tag like so:

<img src="BigFile.gif" width="200" height="200" />

While this has the effect of having the image display in the browser as a 200x200 image, the image's file size has not changed. That is, the entire 100 KB image file is downloaded from the Web server; this image is then resized on the browser. Of course this is suboptimal. Clearly since the resized image is less than 400x400, it's file size should be less than the initial 100 KB.

In this article we will examine how to actually resize the image using the Image.GetThumbnailImage() method.

First Things First - Displaying Images from an ASP.NET Web Page


For reasons that will become clear soon enough, the first thing I'd like to discuss is how to create an ASP.NET Web page that can display an image. Specifically, let's look at how to create an ASP.NET Web page that takes in, through its QueryString, the URL of an image to display. That is, assume that our ASP.NET Web page to display images is called ShowImage.aspx; then, if we want to display the image /images/BillGates.jpg from a Web page, we should be able to do so using the following HTML markup:

<img src="ShowImage.aspx?img=/images/BillGates.jpg" />

To create such an ASP.NET Web page, we will use the Image class in the System.Drawing namespace. The Image class contains a Save() method that can take two input arguments: the stream to save the image to, and the format of the image. Fortunately, the Response object contains an OutputStream property, which is the stream whose data is sent back to the client on a Web request.

If you are a trifle confused, don't worry, the following code example should help clarify things:

<%@Import Namespace="System.Drawing.Imaging" %>
<script language="VB" runat="server">
  Sub Page_Load(sender as Object, e as EventArgs)
  
    'Read in the image filename to create a thumbnail of
    Dim imageUrl as String = Request.QueryString("img")
    
    'Make sure that the image URL doesn't contain any /'s or \'s
    If imageUrl.IndexOf("/") >= 0 Or imageUrl.IndexOf("\") >= 0 then
      'We found a / or \
      Response.End()
    End If
    
    'Add on the appropriate directory
    imageUrl = "/images/" & imageUrl
    
    'Get the image.    
    Dim fullSizeImg as System.Drawing.Image
    fullSizeImg = System.Drawing.Image.FromFile(Server.MapPath(imageUrl))
    
    'Set the ContentType to "image/gif" and output the image's data
    Response.ContentType = "image/gif"
    fullSizeImg.Save(Response.OutputStream, ImageFormat.Gif)  
    
    'Dispose/clean up...
    fullSizeImg.Dispose()
  End Sub
</script>
[View a Live Demo!]

The particularly important lines are bolded. Before we examine these bold lines, though, take a moment to examine the first few lines of the Page_Load event handler. Note that the first thing we do is read in the QueryString parameter img and store it in the variable imageUrl. Next, we make sure that the imageUrl variable doesn't contain any / and \ characters. This is because we don't want the user to be able to view any image. Just those images in a specified directory (namely /images/ for this example).

The Importance of the Check for the / and \ Characters
Why, exactly, should we check for the / and \ characters in the img QueryString variable? The reason this check exists is because if we allowed for just any input, the user could enter the path for an image that we might not want them to see. They could, for instance, see an image that resides in a directory that has HTTP read permissions turned off. For example, imagine that the Web site's directory is located at C:\Inetpub\wwwroot, and there are some sensitive images in the directory C:\Inetpub\wwwroot\someDir\PrivateImages. A user who knew about this directory could request to see images in that directory by visiting the URL:

http://www.yoursite.com/ShowImage.aspx?img=/someDir/PrivateImages/privImage1.gif

For this reason, the script checks to ensure that characters that allow for directory traversal are not allowed in the input.

After the check for / and \ characters, the imageUrl variable is updated by having the proper directory name - /images/ - prepended to it. Next, an instance of the Image class is created and assigned to the Image instance returned by the image found at the URL specified by imageUrl. Finally, the Web page's content type is set to "image/gif" and the image is squirted out to the Response.OutputStream as an image of type ImageFormat.Gif.

Resizing an Image Using the GetThumbnailImage() Method


The Image class contains a GetThumbnailImage() method that allows an image to be dynamically resized on the fly. This dynamic resizing has an impact on the resulting image's file size; that is, if you have an original image at, say, 400x400 with a 100 KB file size, using GetThumbnailImage() to create a 50x50 image will reduce the file size, perhaps to, say, 25 KB.

The GetThumbnailImage() method is a method of the Image class. When an Image instance calls this method, the image is resized to a specified height and width, and another Image instance is returned, which is the resized image. Specifically, the GetThumbnailImage() method has the following form:

	Public Function GetThumbnailImage( _
	   ByVal thumbWidth As Integer, _
	   ByVal thumbHeight As Integer, _
	   ByVal callback As Image.GetThumbnailImageAbort, _
	   ByVal callbackData As IntPtr _
	) As Image

The thumbWidth and thumbHeight methods specify the width and height of the resulting thumbnail image. For the third parameter, callback, you need to provide a delegate. (A delegate is a reference type that refers to a method. If you have had experience with C or C++, it is similar to a function pointer.) To supply the delegate, you must provide in your ASP.NET Web page a function of the following form:

Public Function FunctionName as Boolean
  Return False
End Function

And then, in the subroutine or function where you make the GetThumbnailImage() method call, you must add the following lines of code:

Dim dummyCallBack as System.Drawing.Image.GetThumbNailImageAbort
dummyCallBack = New _
      System.Drawing.Image.GetThumbnailImageAbort(AddressOf FunctionName)

Where FunctionName in this code snippet and the previous code snippet are equal to the same value.

For the last parameter of the GetThumbnailImage() method - callbackData - you must pass in the value IntPtr.Zero. These last two parameters may seem a bit weird - don't fret over their details, just use the code provided here.

A simple example of using the GetThumbnailImage() method call can be seen below.

Function ThumbnailCallback() as Boolean
  Return False
End Function

Sub Page_Load(sender as Object, e as EventArgs)
  'Create the delegate
  Dim dummyCallBack as System.Drawing.Image.GetThumbNailImageAbort
  dummyCallBack = New _
    System.Drawing.Image.GetThumbnailImageAbort(AddressOf ThumbnailCallback)
      
  Dim fullSizeImg as System.Drawing.Image
  fullSizeImg = System.Drawing.Image.FromFile("C:\Images\someImage.gif")
  
  Dim thumbNailImg as System.Drawing.Image
  thumbNailImg = fullSizeImg.GetThumbnailImage(100, 100, _
                                         dummyCallBack, IntPtr.Zero)

  ...
End Sub

The above code creates an Image instance thumbNailImg that is a dynamically-resized version of the image C:\Images\someImage.gif. Specifically, the thumbnail image is 100x100.

Now that we have seen how to create a thumbnail, let's look at how to encorporate this functionality with the ShowImage.aspx Web page. We'll cover this in Part 2.

  • Read Part 2!



  • ASP.NET [1.x] [2.0] | ASPMessageboard.com | ASPFAQs.com | Advertise | Feedback | Author an Article