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.
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:
|
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:
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:
|
And then, in the subroutine or function where you make the GetThumbnailImage()
method call,
you must add the following lines of code:
|
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.
|
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.