Well, I somehow missed that last post of yours - failed to get the email notification. Anyway, here's what I ended up doing:

VB Code:
  1. <%@ Page Language="VB" Debug="False" Trace="False" %>
  2. <%@Import Namespace="System.Drawing" %>
  3. <%@Import Namespace="System.Drawing.Imaging" %>
  4. <%@Import Namespace="System.Drawing.Drawing2D" %>
  5.  
  6. <script language="VB" runat="server">
  7. Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
  8.   Dim strImage As String = Replace(Request.QueryString("image"), "%20", " ")
  9.   Dim strAlbum as String = Replace(Request.QueryString("album"), "%20", " ")
  10.  
  11.   If strImage = String.Empty Or strAlbum = String.Empty Then Exit Sub
  12.   If InStr(strImage, "/") <> 0 Or InStr(strImage, "\") <> 0 Or _
  13.    InStr(strAlbum, "/") <> 0 Or InStr(strAlbum, "\") <> 0 Then
  14.     Exit Sub
  15.   End If
  16.  
  17.   Dim sWidth = Request("w")
  18.   Dim sHeight = Request("h")
  19.  
  20.   If Not sHeight = String.Empty And Not sWidth = String.Empty Then
  21.     sWidth = Integer.Parse(sWidth)
  22.     sHeight = Integer.Parse(sHeight)
  23.   Else
  24.     sWidth = 20
  25.     sHeight = 20
  26.   End If
  27.  
  28.   Dim strPath As String = Server.MapPath("photos/" & strAlbum & "/" & strImage)
  29.   Dim fsMain As System.IO.FileStream = New System.IO.FileStream(strPath, _
  30.    System.IO.FileMode.OpenOrCreate, System.IO.FileAccess.Read)
  31.  
  32.   'Cache.Remove(strPath & "_" & sWidth & "_" & sHeight)
  33.   Dim bytImage As Byte() = Cache.Get(strPath & "_" & sWidth & "_" & sHeight)
  34.  
  35.   Dim msTempStream As System.IO.MemoryStream
  36.   Dim imgMain As System.Drawing.Image
  37.  
  38.   If bytImage Is Nothing Then
  39.     ReDim bytImage(fsMain.Length)
  40.     fsMain.Read(bytImage, 0, fsMain.Length)
  41.     fsMain.Close()
  42.  
  43.     msTempStream = New System.IO.MemoryStream(bytImage)
  44.     imgMain = System.Drawing.Image.FromStream(msTempStream)
  45.  
  46.     Dim lnRatio As Decimal
  47.     Dim lnNewWidth As Integer = 0
  48.     Dim lnNewHeight As Integer = 0
  49.     If (imgMain.Width > imgMain.Height) Then
  50.       lnRatio = Integer.Parse(sWidth) / imgMain.Width
  51.       lnNewWidth = Integer.Parse(sWidth)
  52.       Dim lnTemp As Decimal = imgMain.Height * lnRatio
  53.       lnNewHeight = lnTemp
  54.     Else
  55.       lnRatio = Integer.Parse(sHeight) / imgMain.Height
  56.       lnNewHeight = Integer.Parse(sHeight)
  57.       Dim lnTemp As Decimal = imgMain.Width * lnRatio
  58.       lnNewWidth = lnTemp
  59.     End If
  60.  
  61.     Dim imgThumbnail As System.Drawing.Image = New Bitmap(lnNewWidth, lnNewHeight)
  62.     Dim graThumbnail As System.Drawing.Graphics = System.Drawing.Graphics.FromImage(imgThumbnail)
  63.  
  64.     graThumbnail.InterpolationMode = InterpolationMode.HighQualityBicubic
  65.     graThumbnail.SmoothingMode = SmoothingMode.HighQuality
  66.     graThumbnail.PixelOffsetMode = PixelOffsetMode.HighQuality
  67.     graThumbnail.CompositingQuality = CompositingQuality.HighQuality
  68.     graThumbnail.DrawImage(imgMain, 0, 0, lnNewWidth, lnNewHeight)
  69.  
  70.     Dim iciInfo() As ImageCodecInfo = ImageCodecInfo.GetImageEncoders()
  71.     Dim encpMain As EncoderParameters = New EncoderParameters(1)
  72.     encpMain.Param(0) = New EncoderParameter(System.Drawing.Imaging.Encoder.Quality, 100L)
  73.  
  74.     Dim strOutputFilename As String = String.Empty
  75.     strOutputFilename = Request.QueryString("OutputFilename")
  76.  
  77.     If Not strOutputFilename = String.Empty Then
  78.       Try
  79.         imgThumbnail.Save(Server.MapPath("photos/" & strAlbum & "/") & strOutputFilename, ImageFormat.Jpeg)
  80.       Catch ex As Exception
  81.         imgThumbnail.Dispose()
  82.         Return
  83.       End Try
  84.     End If
  85.  
  86.     Response.ContentType = "image/jpeg"
  87.     Dim msSaveStream As System.IO.MemoryStream = New System.IO.MemoryStream
  88.     imgThumbnail.Save(msSaveStream, iciInfo(1), encpMain)
  89.     msSaveStream.WriteTo(Response.OutputStream)
  90.     Dim bytSave(msSaveStream.Length) As Byte
  91.     msSaveStream.Position = 0
  92.     msSaveStream.Read(bytSave, 0, msSaveStream.Length)
  93.     Cache.Insert(strPath & "_" & sWidth & "_" & sHeight, _
  94.      bytSave, Nothing, DateTime.MaxValue, TimeSpan.Zero)
  95.     imgThumbnail.Dispose()
  96.   Else
  97.     msTempStream = New System.IO.MemoryStream(bytImage)
  98.     Response.ContentType = "image/jpeg"
  99.     msTempStream.WriteTo(Response.OutputStream)
  100.  
  101.     Dim strOutputFilename As String = String.Empty
  102.     strOutputFilename = Request.QueryString("OutputFilename")
  103.  
  104.     If Not strOutputFilename = String.Empty Then
  105.       Try
  106.         imgMain = System.Drawing.Image.FromStream(msTempStream)
  107.         imgMain.Save(Server.MapPath("photos/" & strAlbum & "/") & strOutputFilename, ImageFormat.Jpeg)
  108.       Catch ex As Exception
  109.         imgMain.Dispose()
  110.         Return
  111.       End Try
  112.       imgMain.Dispose()
  113.     End If
  114.   End If
  115. End Sub
  116. </script>

There's a distinct lack of comments, but essentially, instead of caching the Image object, I cache a byte array containing the image.

What do you reckon? Is there going to be a big difference in speed?