A while ago I needed to create a function to allow a user to upload an image and have the system resize it to a thumbnail - preserving the aspect ratio, while at the same time ensuring that neither of the maximum constraints of the thumbnail width or height where breached - and then save it to the server.

The function had to be written for an ASP.NET server and ideally in VBScript to fit in with the rest of the project. To further complicate matters it was a hybrid project… a halfway house in a migration from Classic ASP to dot Net.

I did the usual trawl around Google looking for code fragments to base the function on and to my surprise almost every one of them ended up producing either terrible quality thumbnails (relying on the .net GetThumbnailImage function) or huge filesizes. It was only as a result of a lot more diligent searching that I was able to solve the latter problem and so I thought I’d share it.

You can either click to go to a working sample, with source online and in a zip file or just grab the source from here and play….

<form action="https://www.paypal.com/cgi-bin/webscr" method="post">
If you think this has saved you time, effort and storage space, maybe you’d like to </form><div style="width:100%;height:250px;overflow:scroll;">
<table border="1" cellspacing="0" cellpadding="4" bgcolor="#FFFFFF"><tr align="left"><td><pre> 1: <%@ Page Trace="False" Language="vb" aspcompat="false" debug="true" validateRequest="false"%>
2:
<%@ Import Namespace=System.Drawing %>
3:
<%@ Import Namespace=System.Drawing.Imaging %>
4:
<%@ Import Namespace=System %>
5:
<%@ Import Namespace=System.Web %>
6: <SCRIPT LANGUAGE="VBScript" runat="server">
7: const Lx = 200 ' max width for thumbnails
8: const Ly = 240 ' max height for thumbnails
9: const upload_dir = "/upload_resize_test/" ' directory to upload file
10: const upload_original = "sample" ' filename to save original as (suffix added by script)
11: const upload_thumb = "thumb" ' filename to save thumbnail as (suffix added by script)
12: const upload_max_size = 25 ' max size of the upload (KB) note: this doesn't override any server upload limits
13: dim fileExt ' used to store the file extension (saves finding it mulitple times)
14: dim newWidth, newHeight as integer ' new width/height for the thumbnail
15: dim l2 ' temp variable used when calculating new size
16: dim fileFld as HTTPPostedFile ' used to grab the file upload from the form
17: Dim originalimg As System.Drawing.Image ' used to hold the original image
18: dim msg ' display results
19: dim upload_ok as boolean ' did the upload work ?
20: </script>
21:
<%
22: randomize() ' used to help the cache-busting on the preview images
23:
upload_ok = false
24: if lcase(Request.ServerVariables("REQUEST_METHOD"))="post" then
25: fileFld = request.files(0) ' get the first file uploaded from the form (note:- you can use this to itterate through more than one image)
26:
if fileFld.ContentLength > upload_max_size * 1024 then
27: msg = "Sorry, the image must be less than " & upload_max_size & "Kb"
28: else
29: try
30: originalImg = System.Drawing.Image.FromStream(fileFld.InputStream)
31: ' work out the width/height for the thumbnail. Preserve aspect ratio and honour max width/height
32:
' Note: if the original is smaller than the thumbnail size it will be scaled up
33:
If (originalImg.Width/Lx) > (originalImg.Width/Ly) Then
34: L2 = originalImg.Width
35: newWidth = Lx
36: newHeight = originalImg.Height * (Lx / L2)
37: if newHeight > Ly then
38: newWidth = newWidth * (Ly / newHeight)
39: newHeight = Ly
40: end if
41: Else
42: L2 = originalImg.Height
43: newHeight = Ly
44: newWidth = originalImg.Width * (Ly / L2)
45: if newWidth > Lx then
46: newHeight = newHeight * (Lx / newWidth)
47: newWidth = Lx
48: end if
49: End If
50:
51: Dim thumb As New Bitmap(newWidth, newHeight)
52:
53: 'Create a graphics object
54:
Dim gr_dest As Graphics = Graphics.FromImage(thumb)
55:
56: ' just in case it's a transparent GIF force the bg to white
57:
dim sb = new SolidBrush(System.Drawing.Color.White)
58: gr_dest.FillRectangle(sb, 0, 0, thumb.Width, thumb.Height)
59:
60: 'Re-draw the image to the specified height and width
61:
gr_dest.DrawImage(originalImg, 0, 0, thumb.Width, thumb.Height)
62:
63: try
64: fileExt = System.IO.Path.GetExtension(fileFld.FileName).ToLower()
65: originalImg.save(Server.MapPath(upload_dir & upload_original & fileExt), originalImg.rawformat)
66: thumb.save(Server.MapPath(upload_dir & upload_thumb & fileExt), originalImg.rawformat)
67: msg = "Uploaded " & fileFld.FileName & " to " & Server.MapPath(upload_dir & upload_original & fileExt)
68: upload_ok = true
69: catch
70: msg = "Sorry, there was a problem saving the image."
71: end try
72: ' Housekeeping for the generated thumbnail
73:
if not thumb is nothing then
74: thumb.Dispose()
75: thumb = nothing
76: end if
77: catch
78: msg = "Sorry, that was not an image we could process."
79: end try
80: end if
81:
82: ' House Keeping !
83:
if not originalImg is nothing then
84: originalImg.Dispose()
85: originalImg = nothing
86: end if
87:
88: end if
89: %>
90: <html>
91: <head>
92: <title>ASP.NET File Upload and Resize Sample</title>
93: <META NAME="Description" CONTENT="ASP.NET File Upload and Resize Sample (Hybrid VB.NET)">
94: <META NAME="Keywords" CONTENT="ASP.NET, ASP, NET, VB, VBScript, Image, Upload, Resize, Thumbnail, Constrain, Filesize, File, Size, Free">
95: <META NAME="Copyright" CONTENT="Rufan-Redi Pty Ltd 2005">
96: <META NAME="Author" CONTENT="System developed by Jeremy at http://www.Rufan-Redi.com">
97: </head>
98: <body>
99:
100: <p><b>Hybrid ASP.NET File Upload and Resize Sample (VB.NET)</b>
101: <br>Upload and resize a GIP/JPG/PNG images, ensuring filesizes are optimum.</p>
102:
103: <form enctype="multipart/form-data" method="post" runat="server">
104: <table>
105: <tr><td>Select the file to upload:</td><td><input type="file" name="upload_file"></td></tr>
106: <tr><td colspan=2>Max upload size
<%=upload_max_size%>Kb, gif/jpg/png only</td></tr>
107: <tr><td colspan=2><input type="submit" value="Upload"></td></tr>
108: </table>
109: </form>
110:
111:
<%
112: if upload_ok then
113: %>
114: <table>
115: <tr>
116: <td valign=top><img src="
<%=upload_dir & upload_original & fileExt & "?" & rnd()%>"></td>
117: <td valign=top><img src="
<%=upload_dir & upload_thumb & fileExt & "?" & rnd()%>"></td>
118: </tr>
119: </table>
120:
<%
121: else
122: response.write(msg)
123: end if
124: %>
125: </body>
126: </html>

</pre></td></tr></table>
</div>