In Part 1 we examined how to create an ASP.NET Web page,
ShowImage.aspx, that would display an image. This ASP.NET Web page could then be referenced
via an HTML <img> tag. In this part we'll look at how to extend the ShowImage.aspx
so that it can produce thumbnail images; then, we'll see how to tie this lesson together with the lessons
learned from the article Displaying a List of Scaled Images.
Altering ShowImage.aspx to Create a Thumbnail
Earlier we saw that we could create an ASP.NET Web page called ShowImage.aspx that could
be passed in an image file name and display the image. In addition to accepting the file name, let's
augment this ASP.NET Web page so that we can pass in an optional height and width. When a height and
width are passed in, the image displayed is first dynamically resized to the specified height and width.
The following code implements the needed changes in ShowImage.aspx.
<%@Import Namespace="System.Drawing.Imaging" %>
<script language="VB" runat="server">
Function ThumbnailCallback() as Boolean
Return False
End Function
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")
'Read in the width and height
Dim imageHeight as Integer = Request.QueryString("h")
Dim imageWidth as Integer = Request.QueryString("w")
'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
Dim fullSizeImg as System.Drawing.Image
fullSizeImg = System.Drawing.Image.FromFile(Server.MapPath(imageUrl))
'Do we need to create a thumbnail?
Response.ContentType = "image/gif"
If imageHeight > 0 and imageWidth > 0 then
Dim dummyCallBack as System.Drawing.Image.GetThumbNailImageAbort
dummyCallBack = New _
System.Drawing.Image.GetThumbnailImageAbort(AddressOf ThumbnailCallback)
Dim thumbNailImg as System.Drawing.Image
thumbNailImg = fullSizeImg.GetThumbnailImage(imageWidth, imageHeight, _
dummyCallBack, IntPtr.Zero)
thumbNailImg.Save(Response.OutputStream, ImageFormat.Gif)
'Clean up / Dispose...
ThumbnailImg.Dispose()
Else
fullSizeImg.Save(Response.OutputStream, ImageFormat.Gif)
End If
'Clean up / Dispose...
fullSizeImg.Dispose()
End Sub
</script>
Most of the code has remained the same. The important additions are two new variables, imageHeight
and imageWidth, which are assigned the QueryString values h and w.
An If statement is used to check if the height and width have been specified; if they have,
then the image is resized using the GetThumbnailImage() method call. If the height and
width have not been specified, then the image is outputted without any resizing.
Resizing Images that Already Include Thumbnails
Alert 4Guys readers Travis R. wrote in to say:
Just wanted to comment on your article in which you use the GetThumbNailImage() method
to resize an image. I used some of your code example and using images off of one of my digital
cameras and it worked just fine. When I used images off of another digital camera, however, I found
that the resized images (resized from 1600x1200 to 400x300) looked horrible. They appeared as
though I used a very high compression or something when saving the image.
Upon further looking at Microsoft's documentation I found the cause of the problem. The problem is
that the GetThumbNailImage() method resizes an image from the original image if their is
no thumbnail embedded in the image. The problem is, most digital cameras do embed a thumbnail image
in the image. So, what's happening is that the tiny thumbnail image embedded in the picture is
being sized from something like 32x12 to 400x300 which gives the horrible picture quality. Just an
FYI.
4Guys enthusiast Doug P. chimes in with a workaround:
I've found that if you rotate the original image 360 degrees it solves this problem. I guess rotating the image
causes it to lose the embedded thumbnail and the full size image is then resized when the GetThumbnailImage()
method is called. Give it a try, just add in the following code right before you call the GetThumbnailImage() method:
Putting It All Together: Using ShowImage.aspx to Display the Images in a Directory
Now that we have examined how to dynamically resize an image using the
GetThumbnailImage() method call, let's discuss how to integrate this with the
ASP.NET Web page that listed the images in a directory. (If you have not read the article
that this article is based on - Displaying a List of Scaled Images - you
should do so now.)
In Displaying a List of Scaled Images we saw an ASP.NET Web page
that used the Image class to determine the height and width of each image in a directory.
If the height or width were beyond certain bounds, the image's height and width attributes were scaled
via the height and width attributes of the <img> tag.
The code to do this was as follows:
For Each s in Directory.GetFiles(Server.MapPath(IMAGE_DIRECTORY), "*.gif")
'Get information about the image
Dim currentImage as System.Drawing.Image = System.Drawing.Image.FromFile(s)
imgHeight = currentImage.Height
imgWidth = currentImage.Width
If imgWidth > maxWidth OR imgHeight > maxHeight then
... some calculations ...
End If
html = "<a href=""" & IMAGE_DIRECTORY & Path.GetFileName(s) & """>" & _
"<img src=""" & IMAGE_DIRECTORY & Path.GetFileName(s) & """" & _
"height=""" & imgHeight & """ width=""" & imgWidth & """>" & _
"</a>"
pics.Add(html)
Next
Simple enough. Now, to use the dynamic resizing, rather than having the <img>
tag's src property refer to the actual image URL, we'll have it refer to ShowImage.aspx,
passing in the image's URL, height, and width through the QueryString. This will change the code that
sets the html variable to:
For Each s in Directory.GetFiles(Server.MapPath(IMAGE_DIRECTORY), "*.gif")
...
If imgHeight <> currentImage.Height Or imgWidth <> currentImage.Width then
html = "<a href=""" & IMAGE_DIRECTORY & Path.GetFileName(s) & """>" & _
"<img src=""ShowImage.aspx?img=" & Path.GetFileName(s) & "&w=" & _
imgWidth & "&h=" & imgHeight & """ " & _
"height=""" & imgHeight & """ width=""" & imgWidth & """>" & _
"</a>"
Else
html = "<a href=""" & IMAGE_DIRECTORY & Path.GetFileName(s) & """>" & _
"<img src=""ShowImage.aspx?img=" & Path.GetFileName(s) & """ " & _
"height=""" & imgHeight & """ width=""" & imgWidth & """>" & _
"</a>"
End If
...
Next
The reason there's an If statement is because we don't always need to resize the image.
That is, if the image is within the size constraints, then the image doesn't need to be resized.
In such a case, the QueryString for ShowImage.aspx does not include the w
and h parameters.
Conclusion
In this article we examined how to dynamically resize an image using the
GetThumbnailImage() method of the Image class. Using this method and
an ASP.NET Web page designed for displaying images, we retooled an earlier demo to allow for
the images to be dynamically resized, as opposed to just scaling the image through the <img>
tag's height and width attributes.