How to save image to folder - asp.net

I am using webservice to call method in businesslogics(one class written in vb).I am getting inputppath and path to where i have to save image in that method.I have to create thumbnail and also i have to save original image.Means i want to save masterimage in one folder and its thumnail in different folder. I used following code
Public Function CreateThumbNails(ByVal intWidth As Integer, ByVal strInputFilePath As String, ByVal strFileName As String, ByVal strOutputFilePath As String) As String
Dim lnWidth As Integer = intWidth
Dim lnHeight As Integer = 100
Dim bmpOut As System.Drawing.Bitmap = Nothing
Try
Dim loBMP As New Bitmap(strInputFilePath)
Dim lnRatio As Decimal
Dim lnNewWidth As Integer = 0
Dim lnNewHeight As Integer = 0
If loBMP.Width < lnWidth AndAlso loBMP.Height < lnHeight Then
lnNewWidth = loBMP.Width
lnNewHeight = loBMP.Height
End If
If loBMP.Width > loBMP.Height Then
lnRatio = CDec(lnWidth) / loBMP.Width
lnNewWidth = lnWidth
Dim lnTemp As Decimal = loBMP.Height * lnRatio
lnNewHeight = CInt(lnTemp)
Else
lnRatio = CDec(lnHeight) / loBMP.Height
lnNewHeight = lnHeight
Dim lnTemp As Decimal = loBMP.Width * lnRatio
lnNewWidth = CInt(lnTemp)
End If
' *** This code creates cleaner (though bigger) thumbnails and properly
' *** and handles GIF files better by generating a white background for
' *** transparent images (as opposed to black)
bmpOut = New Bitmap(lnNewWidth, lnNewHeight)
Dim g As Graphics = Graphics.FromImage(bmpOut)
g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic
g.FillRectangle(Brushes.White, 0, 0, lnNewWidth, lnNewHeight)
g.DrawImage(loBMP, 0, 0, lnNewWidth, lnNewHeight)
loBMP.Dispose()
bmpOut.Save(HttpContext.Current.Server.MapPath(strOutputFilePath) + strFileName)
bmpOut.Dispose()
Return strOutputFilePath + strFileName
Catch e As Exception
Throw New Exception("ThumbNail Creation Failed")
Return ""
End Try
End Function
What code i have to include to save original size image in another folder.Can anybody help?

EDIT trigger happy. you don't need to save it from the bitmap. the file is already there. just copy the file.
If I understand your question then you want to save the image from before you manipulate it to a new location on the server.
That file already exists as a file on the server. The file location of that file is passed into your function as a parameter (strInputFilePath).
The simplest thing to do would to use File.Copy() to copy the file to the desired location.

Related

Converting HTML to PDF and attaching to email .NET

I am looking to use PDFSharp to convert a HTML page into a PDF. This then is attached into an email and sent all in one go.
So, I have a aspx page and vb code file in which gets called through a database SQL job.
Protected Sub Page_Load(sender As Object, e As EventArgs) Handles Me.Load
Dim ReqUrl As String, WorkflowID As String = String.Empty
Using con As New SqlConnection(GlobalVariables.ConStr)
Using com As New SqlCommand("EXEC App.GetWorkflowToSend", con)
con.Open()
Using dr = com.ExecuteReader
Try
While dr.Read
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12
ReqUrl = HttpContext.Current.Request.Url.GetLeftPart(UriPartial.Authority) + dr.Item("WorkflowLink")
WorkflowID = dr.Item("WorkflowID")
Dim r As String = HttpContext.Current.Request.Url.GetLeftPart(UriPartial.Authority) + dr.Item("WorkflowLink")
Dim p As String = Server.MapPath("~\Data\Files") + "\" + WorkflowID + ".pdf"
Dim t As Thread = New Thread(CType(
Function()
ConvertHTML(r, p)
SendMail(Nothing, EmailFrom, "email#address", "New PDF Generated " + WorkflowID, r + "<br/>" + p + "<br/>" + WorkflowID, EmailUser, EmailPass, EmailHost, EmailPort, EmailSSL, "", Nothing, p)
End Function, ThreadStart))
t.SetApartmentState(ApartmentState.STA)
t.Start()
Response.Write(r + "<br>")
Response.Write(p)
End While
Catch
SendMail(Nothing, EmailFrom, "email#address", "Error: " + Err.Description, WorkflowID, EmailUser, EmailPass, EmailHost, EmailPort, EmailSSL, "", Nothing)
End Try
End Using
End Using
End Using
End Sub
In the vb code I essentially call a database stored procedure. This returns some records.
For each of these records, I am currently using HttpContext.Current.Request.Url to make up a string which is essentially the the document url.
I also then declare and specify the location as a String of where I want the converted PDF to be stored.
Public Shared Function ConvertHTML(HTMLPage As String, FileName As String) As String
Dim pngfilename As String = Path.GetTempFileName()
Dim res As String = "" ' = ok
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12
'Try
Using wb As System.Windows.Forms.WebBrowser = New System.Windows.Forms.WebBrowser
wb.ScrollBarsEnabled = False
wb.ScriptErrorsSuppressed = True
wb.Navigate(HTMLPage)
While Not (wb.ReadyState = WebBrowserReadyState.Complete)
Application.DoEvents()
End While
wb.Width = wb.Document.Body.ScrollRectangle.Width
wb.Height = wb.Document.Body.ScrollRectangle.Height
If wb.Height > 3000 Then
wb.Height = 3000
End If
' Get a Bitmap representation of the webpage as it's rendered in the WebBrowser control
Dim b As Bitmap = New System.Drawing.Bitmap(wb.Width, wb.Height)
Dim hr As Integer = b.HorizontalResolution
Dim vr As Integer = b.VerticalResolution
wb.DrawToBitmap(b, New Rectangle(0, 0, wb.Width, wb.Height))
wb.Dispose()
If File.Exists(pngfilename) Then
File.Delete(pngfilename)
End If
b.Save(pngfilename, Imaging.ImageFormat.Png)
b.Dispose()
Using doc As PdfSharp.Pdf.PdfDocument = New PdfSharp.Pdf.PdfDocument
Dim page As PdfSharp.Pdf.PdfPage = New PdfSharp.Pdf.PdfPage()
page.Width = PdfSharp.Drawing.XUnit.FromInch(wb.Width / hr)
page.Height = PdfSharp.Drawing.XUnit.FromInch(wb.Height / vr)
doc.Pages.Add(page)
Dim xgr As PdfSharp.Drawing.XGraphics = PdfSharp.Drawing.XGraphics.FromPdfPage(page)
Dim img As PdfSharp.Drawing.XImage = PdfSharp.Drawing.XImage.FromFile(pngfilename)
xgr.DrawImage(img, 0, 0)
doc.Save(FileName)
doc.Close()
img.Dispose()
xgr.Dispose()
End Using
End Using
Return res
End Function
I run the conversion function with these two strings and finally call a mailing function.
PDF Error
The problem I am having at the moment is the attached PDF I receive in the email doesn't contain the correct output and states 'Navigation to the webpage was cancelled'.
http://127.0.0.1/PDF/TTR/4
C:\inetpub\wwwroot\Prod\Data\Files\4.pdf
I also sent the two strings as output within the email and they look ok.
I'm sure there is something small missing whether that be in my conversion function or just in the main code file.

VB.Net OpenXML Conditional Page Break

I am using the OpenXML library to auto generate Word files. I have a function that takes a group of files and merges them into one document. As I merge a new file into a document, I want each file to start on a new page. But, I don't want to have any blank pages. The code I have mostly works, but an issue comes up is if a file being merged in is a filled page, then a page break is still added, resulting in an empty page being added. I am not sure how to best deal with this, to prevent blank pages from being added. Here is my code:
Public Sub MergeFiles(ByVal filePaths As List(Of String), ByVal fileName As String)
Dim newFile As String = HttpRuntime.AppDomainAppPath & "PDF_Templates\TempFolder\catalog-" & Guid.NewGuid.ToString & ".docx"
File.Copy(fileName, newFile)
Dim counter As Integer = 0
For Each filePath As String In filePaths
Dim wordDoc As WordprocessingDocument = WordprocessingDocument.Open(newFile, True)
Using wordDoc
Dim mainPart As MainDocumentPart = wordDoc.MainDocumentPart
Dim altChunkId As String = "altChunkId" & counter
Dim chunk As AlternativeFormatImportPart = mainPart.AddAlternativeFormatImportPart(AlternativeFormatImportPartType.WordprocessingML, altChunkId)
Dim fileStream As FileStream = File.Open(filePath, FileMode.Open)
Using fileStream
chunk.FeedData(fileStream)
End Using
Dim AltChunk As AltChunk = New AltChunk()
AltChunk.Id = altChunkId
' Dont add a page break to the first page.
If counter > 0 Then
Dim last As OpenXmlElement = wordDoc.MainDocumentPart.Document.Body.Elements().LastOrDefault(Function(e) TypeOf e Is Paragraph OrElse TypeOf e Is AltChunk)
last.InsertAfterSelf(New Paragraph(New Run(New Break() With {
.Type = BreakValues.Page
})))
End If
mainPart.Document.Body.InsertAfter(Of AltChunk)(AltChunk, mainPart.Document.Body.Elements(Of Paragraph).Last())
mainPart.Document.Save()
wordDoc.Close()
End Using
counter = counter + 1
Next
End Sub

Extracting Non-Digital "Signature" Images from PDF with iTextSharp

I've been tasked with a project that needs to read the content of a PDF document with populated form fields and save the content to a database. Once the data extracted I should be able to re-create the document using a master copy of the template and re-populated form field data.
Our user base will complete the form/template on a mobile device (specifically Android devices for our environment). They will also be using the Adobe Acrobat Reader mobile app to complete the documents. Once completed, each engineer working on the document will sign the document using the signature function in the mobile app (multiple signatures could be present on multiple pages) and submit the form (which currently emails a copy of the completed PDF to a specific email address).
Once I have a copy of the completed PDF document I am able to read the AcroForm fields using from a .NET application using the iTextSharp library and do whatever I need to do with it (store field "name" and "value" in a database)
Dim reader As PdfReader = New PdfReader(pdfBytes)
Dim pdfFormFields As AcroFields = reader.AcroFields
For Each formField In reader.AcroFields.Fields.Keys
Dim ff As New FormField
ff.Name = formField
ff.Value = pdfFormFields.GetField(formField)
Do_stuff_with(ff)
Next
I'm then able to re-populate the blank pdf template at a later stage with the form data, however am struggling to read the "signature" aspect of it embedded in the file.
When completed via the Acrobat Reader Android app I believe the "signature" isn't technically a signature in the proper "Digital Signature" sense that it can be read using the iTextSharp AcroFields.GetSignatureNames() or AcroFields.GetSignatureDictionary methods. Instead I beleive the signature is stored as a Stream object within an Annotation in the document however I'm currently unable to read and convert this into a Byte Array to store in a database.
I know I will also need to get the page/position of each signature so that I can re-populate at a later stage.
I've tried several methods including extracting all Images from the document but this only extracts embedded images that existed in the template and not the annotation signatures. With a blank dummy document containing just a submit button and signature I get an error after getting the dictionary object PdfName.RESOURCES as if nothing exists.
Dim pdf as New PdfReader(bytes)
For i As Int16 = 1 To pdf.NumberOfPages
Dim pg As PdfDictionary = pdf.GetPageN(i)
Dim res As PdfDictionary = CType(PdfReader.GetPdfObject(pg.Get(PdfName.RESOURCES)), PdfDictionary)
' ###
' ###
' ### Errors on next line with
' ### "Object reference not set to an instance of an object"
' ###
' ###
Dim xobj As PdfDictionary = CType(PdfReader.GetPdfObject(pg.Get(PdfName.XOBJECT)), PdfDictionary)
If xobj IsNot Nothing Then
For Each name As PdfName In xobj.Keys
Dim obj As PdfObject = xobj.Get(name)
If obj.IsIndirect Then
Dim tg As PdfDictionary = CType(PdfReader.GetPdfObject(obj), PdfDictionary)
Dim type As PdfName = CType(PdfReader.GetPdfObject(tg.Get(PdfName.SUBTYPE)), PdfName)
If PdfName.IMAGE.Equals(type) Then
Dim xrefIdx As Integer = CType(obj, PRIndirectReference).Number
Dim pdfObj As PdfObject = pdf.GetPdfObject(xrefIdx)
Dim str As PdfStream = CType(pdfObj, PdfStream)
Dim bytes As Byte() = PdfReader.GetStreamBytesRaw(CType(str, PRStream))
Dim img As iTextSharp.text.Image = iTextSharp.text.Image.GetInstance(CType(obj, PRIndirectReference))
Dim filter As String = tg.Get(PdfName.FILTER).ToString
If filter = "/DCTDecode" Then
Dim img2 As System.Drawing.Image = System.Drawing.Image.FromStream(New MemoryStream(bytes))
Dim stream As MemoryStream = New MemoryStream
img2.Save(stream, System.Drawing.Imaging.ImageFormat.Jpeg)
stream.Position = 0
PdfReader.KillIndirect(obj)
img = iTextSharp.text.Image.GetInstance(stream)
writer.AddDirectImageSimple(img, CType(obj, PRIndirectReference))
End If
End If
End If
Next
End If
Next
If I inspect the document with iText RUPS I can see two Stream objects (Inspect1.png) which I assume are the two signatures in my test document TestDoc_Complete.pdf but I'm unable to extract these either into a Byte Array or Memory Stream so that I can manipulate and save.
Any help (VB/C#) would be appreciated to help me solve this.
Thanks
--EDIT--
I'm now able to loop through the PdfObjects using XrefSize and identify which objects are Streams. I can read the Stream` Bytes and Raw Bytes and output these to a file but these are unreadable by any image viewer.
Dim pdf = New PdfReader(bytes)
Dim obj As PdfObject
For i As Integer = 1 To pdf.XrefSize
Try
obj = pdf.GetPdfObject(i)
If obj IsNot Nothing And obj.IsStream Then
Dim stream As PRStream = CType(obj, PRStream)
Dim type As PdfName = Nothing
Try
type = CType(pdfreader.GetPdfObject(stream.Get(PdfName.FILTER)), PdfName)
Catch ex As Exception
End Try
If type IsNot Nothing And PdfName.FLATEDECODE.Equals(type) Then
Dim b1 As Byte() = pdfreader.GetStreamBytes(stream)
Dim b2 As Byte() = pdfreader.GetStreamBytesRaw(stream)
csLog.AddLog("Stream Length: " & stream.Length, csLogging.DebugLevel.Debug)
csLog.AddLog("bytes1 Length: " & b1.Length, csLogging.DebugLevel.Debug)
csLog.AddLog("bytes2 Length: " & b2.Length, csLogging.DebugLevel.Debug)
Dim fos As FileStream
' ### Write Bytes to file for testing
fos = New FileStream(Server.MapPath(".") & "\bytes1" & i, FileMode.Create)
fos.Write(b1, 0, b1.Length)
fos.Flush()
fos.Close()
' ### Write RawBytes to file for testing
fos = New FileStream(Server.MapPath(".") & "\bytes2" & i, FileMode.Create)
fos.Write(b2, 0, b2.Length)
fos.Flush()
fos.Close()
' ### CONVERSION ATTEMPTS
ConvertAttempt1(b2, i) ' ### Using Raw Bytes
ConvertAttempt2(stream, i)
End If
End If
Catch ex As Exception
End Try
Next
The first file using b1 appears to be a text representation of the PRStream
q
.160714 0 0 .160714 0 0 cm
0.00000 0.00000 0.00000 RG 0.00000 0.00000 0.00000 rg 1 J 1 j 26.48880 w 488.00000 115.43372 m 488.00000 115.43372 l S 20.37600 w 184.00000 155.43372 m 184.00000 155.43372 184.00000 155.43372 182.44000 156.45367 c S 20.37600 w
.....
.....
.....
which I assume are the vector graphic curves/strokes.
The output of b2 (raw bytes) has the same content length of the signatures I am expecting (3305 and 4834) as shown in the two sterams in iText RUPS.
I've attempted to convert the bytes to an image (JPG) but get errors
' ### Conversion attempt 1
Sub ConvertAttempt1(ByVal rawBytes As Byte(), ByVal xRef As Int16)
Try
Using memStream As MemoryStream = New MemoryStream(rawBytes)
memStream.Position = 0
' ###
' ###
' ### Falls over on next line - "Parameter is not valid"
' ###
' ###
Dim img As System.Drawing.Image = System.Drawing.Image.FromStream(memStream)
Dim path As String = System.IO.Path.Combine(Server.MapPath("."), String.Format("convert1_{0}.jpg", xRef))
Dim parms As System.Drawing.Imaging.EncoderParameters = New System.Drawing.Imaging.EncoderParameters(1)
parms.Param(0) = New System.Drawing.Imaging.EncoderParameter(System.Drawing.Imaging.Encoder.Compression, 0)
Dim jpegEncoder As System.Drawing.Imaging.ImageCodecInfo = GetImageEncoder("JPEG")
img.Save(path, jpegEncoder, parms)
End Using
Catch ex As Exception
'csLog.AddLog(ex.Message, csLogging.DebugLevel.Errors)
'csLog.AddLog(ex.StackTrace, csLogging.DebugLevel.Errors)
End Try
End Sub
and
Sub ConvertAttempt2(ByVal stream As PRStream, ByVal xRef As Int16)
' ### Conversion attempt 2
Try
' ###
' ###
' ### Falls over on next line - "Object reference not set to an instance of an object."
' ###
' ###
Dim pdfImage As PdfImageObject = New PdfImageObject(stream)
Dim img As System.Drawing.Image = pdfImage.GetDrawingImage()
Dim path As String = System.IO.Path.Combine(Server.MapPath("."), String.Format("convert2_{0}.jpg", xRef))
Dim parms As System.Drawing.Imaging.EncoderParameters = New System.Drawing.Imaging.EncoderParameters(1)
parms.Param(0) = New System.Drawing.Imaging.EncoderParameter(System.Drawing.Imaging.Encoder.Compression, 0)
Dim jpegEncoder As System.Drawing.Imaging.ImageCodecInfo = GetImageEncoder("JPEG")
img.Save(path, jpegEncoder, parms)
Catch ex As Exception
csLog.AddLog(ex.Message, csLogging.DebugLevel.Errors)
csLog.AddLog(ex.StackTrace, csLogging.DebugLevel.Errors)
End Try
End Sub

Docx File Corrupted after Upload

I have tired many things, searched the internet, and still I cannot figure out what is going on with this code. I still get that my docx files are corrupted, but when I do it with doc file everything is going great.
My Upload Code
Private Sub LbReqUploadAttachment1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles LbReqUploadAttachment1.Click
If FileUplReqAttachment1.HasFile Then
'Then save the attachment to the documents table
Dim type As String = Me.FileUplReqAttachment1.PostedFile.ContentType
Dim myFile As System.Web.HttpPostedFile = Me.FileUplReqAttachment1.PostedFile
Dim nFileLen As Integer = myFile.ContentLength
Dim myData(nFileLen) As Byte
myFile.InputStream.Read(myData, 0, nFileLen)
Dim DocDto As New DocumentsDto
DocDto.Month = Now.ToString("m")
DocDto.Year = Now.Year
DocDto.MimeType = type
DocDto.UploadedById = MyPage.LoggedOnUser.DtoUser.PersonId
DocDto.DocumentBytes = myData.ToArray
DocDto = MyPage.DelegateDocument.CreateDocumentsDto(DocDto)
'Update the order with the new document id
If Me.TbIntlFlagz.Checked Then
Item.AssetID = CStr(DocDto.DocumentID)
Else
Item.AssetID = "0"
End If
' Save Everything
SaveItem()
'Focus after postback
FileUplReqAttachment1.Focus()
End If
'Stay on order screen
Response.Redirect(String.Format("Default.aspx?i={0}&Item={1}", MyPage.DtoPage.PageID, Me.Item.Id))
End Sub
My download code:
Sub ProcessRequest(ByVal context As HttpContext) Implements ttpHandler.ProcessRequest
Dim docba As Byte() = docDto.DocumentBytes
Dim ext As String = Mime.GetExtensionFromMime(docDto.MimeType)
context.Response.ContentType = docDto.MimeType
If String.IsNullOrEmpty(ext) Then
'We can only use the attachment approach if we found a good extension based on the mime type
Else
Dim DispositionHeader As String
If Not context.Request.QueryString.Item("fn") Is Nothing Then
DispositionHeader = String.Format("attachment; filename={0}.{1}", AntiXss.UrlEncode(context.Request.QueryString.Item("fn")), ext)
Else
DispositionHeader = String.Format("attachment; filename={0}.{1}", AntiXss.UrlEncode("Document"), ext)
End If
context.Response.AppendHeader("Content-Disposition", DispositionHeader)
End If
context.Response.Expires = (60 * 24 * 1)
context.Response.OutputStream.Write(docba, 0, docba.Length)
context.Response.Flush()
docba = Nothing
End If
End Sub
I have tired these with no success:
Why are .docx files being corrupted when downloading from an ASP.NET page?
http://www.aspmessageboard.com/showthread.php?230778-Downloaded-docx-files-are-corrupted
https://social.msdn.microsoft.com/Forums/vstudio/en-US/88383fb2-03c6-49f5-afee-ce38497789bd/retrieving-docx-stored-in-sql-server-results-in-there-was-an-error-opening-the-file?forum=vbgeneral
I am uploading the file into a DB, and downloading the file by pressing a hyperlink. When I press the hyperlink and download the file. View at the file it is corrupted.
In VB, when declaring an array you give it the number of elements in the array. This is different from many languages where you specify the last index of the array.
For the code you show, you need to use
Dim myData(nFileLen - 1) As Byte
to make sure that you do not have an extra element in the array.
It appears that the .doc format is not sensitive to this, but .docx is.

Implementing an Image Download in VB.NET

I am trying to implement an image download in vb.net where the client clicks a button and the browser downloads an image for the client from a file in the server.
I tried this:
Private Sub DownloadImage(ByVal ImageURL As String)
Dim Buffer(6000000) As Byte
Response.Clear()
Response.AddHeader("content-disposition", "attachment;filename=" & ImageURL & ".jpg")
Response.ContentType = "image/jpeg"
Response.BinaryWrite(Buffer)
Response.Flush()
Response.End()
End Sub
But this has 2 problems. First, it doesn't actually show up the image when I download it so it doesn't work properly. Secondly I have to manually enter the size of the image to determine the size of the byte array.
Please help me out, I couldn't find any resources on internet and couldn't get my head around it.
Thanks!
This is a sample image handler I've used for several years. It's probably got some room for improvement, but it is intended to be used as the src attribute for an img tag.
<img src="Thumbs.ashx?img=/ImagePath/BigImage.jpg&max=100" />
It's a direct copy-paste of my working code and it's got some references to private code - but it should give you a good start. It will create a thumbnail image so it doesn't have to be regenerated each time, if the thumbnail has already been generated. Hope this helps...
<%# WebHandler Language="VB" Class="GetImage" %>
Imports Web.Utilities
Imports Common
Imports System
Imports System.Drawing
Imports System.Web
Imports System.IO
''' <summary>
''' Resizes the image supplied in the "img" querystring parameter and writes it to the OutputStream in jpg format.
''' The default dimension is a max of 90 pixels (H or W; whichever is larger).
''' The "max" querystring parameter can alter the maximum dimension by supplying a new dimension as an integer.
''' If the file name contains an ampersand, it should be replaced with [amp].
''' </summary>
''' <remarks></remarks>
Public Class GetImage : Implements IHttpHandler
Private thumbFolder As String = "/images/Thumbs/"
Private trapCount As Integer = 0
Public Sub ProcessRequest(ByVal context As HttpContext) Implements IHttpHandler.ProcessRequest
'General.PreventClientCaching()
'context.Response.Cache.SetCacheability(HttpCacheability.NoCache)
Dim maxSize As Integer = 90
Dim img As String = context.Request.QueryString("img")
Dim strMax As String = context.Request.QueryString("max")
If Not strMax.IsNullOrEmpty AndAlso IsNumeric(strMax) Then
maxSize = CInt(strMax)
End If
If maxSize > 1000 Then
maxSize = 1000
End If
If img.IsNullOrEmpty Then
img = "/images/PicUnavailable.jpg"
End If
Try
Dim uri As New System.Uri(img, UriKind.RelativeOrAbsolute)
img = uri.AbsolutePath
Catch ex As Exception
End Try
General.SetContentType(General.FileType.Jpg)
img = img.Replace("[amp]", "&")
ServeImage(context, img, maxSize)
End Sub
Private Sub ServeImage(ByVal context As HttpContext, ByVal imagePath As String, ByVal maximumSize As Integer)
Dim imgFile As Image = Nothing
Dim existingThumb As String = imagePath.Replace("/", "{s}") & "_" & maximumSize.ToString & ".jpg"
Dim doPurge As Boolean
Boolean.TryParse(context.Request.QueryString("purge"), doPurge)
' Check to see if the thumbnail has already been generated and it's older than the source.
' If it is, delete it.
If File.Exists(context.Server.MapPath(thumbFolder & existingThumb)) Then
If doPurge Then
File.Delete(context.Server.MapPath(thumbFolder & existingThumb))
Else
If File.GetLastWriteTime(context.Server.MapPath(thumbFolder & existingThumb)) < File.GetLastWriteTime(context.Server.MapPath(imagePath)) Then
Try
File.Delete(context.Server.MapPath(thumbFolder & existingThumb))
Catch ex As Exception
End Try
End If
End If
End If
' If the thumbnail already exists, write the byte array to the output stream
If File.Exists(context.Server.MapPath(thumbFolder & existingThumb)) Then
Dim fs As FileStream = Nothing
Try
fs = New FileStream(context.Server.MapPath(thumbFolder & existingThumb), IO.FileMode.Open, IO.FileAccess.Read, IO.FileShare.Read)
Dim imgLen As Long = fs.Length()
Dim imgData(imgLen) As Byte
fs.Read(imgData, 0, Integer.Parse(imgLen.ToString()))
context.Response.OutputStream.Write(imgData, 0, Integer.Parse(imgLen.ToString()))
Catch ex2 As UnauthorizedAccessException
'context.Server.Transfer(img)
Throw
Catch exIO As IOException
'context.Server.Transfer(img)
Throw
Finally
If Not fs Is Nothing Then
fs.Dispose()
fs = Nothing
End If
End Try
' the file doesn't exist, so render it to the output stream and save it to the thumbnail
Else
Try
imgFile = Image.FromFile(context.Server.MapPath(imagePath))
Dim maxDim As Integer = maximumSize
Dim maxH As Integer = maximumSize
Dim maxW As Integer = maximumSize
'If img.Height > maxH OrElse img.Width > maxW Then
Dim thumb As Image
Dim gfx As Graphics
Dim rect As Rectangle
If imgFile.Height >= imgFile.Width Then 'portrait or square
Dim newW As Integer
newW = CInt((maxH / imgFile.Height) * imgFile.Width)
thumb = New Bitmap(newW, maxDim)
gfx = Graphics.FromImage(thumb)
gfx.CompositingQuality = Drawing2D.CompositingQuality.HighQuality
gfx.InterpolationMode = Drawing2D.InterpolationMode.HighQualityBicubic
gfx.SmoothingMode = Drawing2D.SmoothingMode.AntiAlias
rect = New Rectangle(0, 0, newW, maxDim)
Else 'landscape
Dim newH As Integer
newH = CInt((maxW / imgFile.Width) * imgFile.Height)
thumb = New Bitmap(maxDim, newH)
gfx = Graphics.FromImage(thumb)
gfx.CompositingQuality = Drawing2D.CompositingQuality.HighQuality
gfx.InterpolationMode = Drawing2D.InterpolationMode.HighQualityBicubic
gfx.SmoothingMode = Drawing2D.SmoothingMode.AntiAlias
rect = New Rectangle(0, 0, maxDim, newH)
End If
gfx.DrawImage(imgFile, rect)
thumb.Save(context.Response.OutputStream, Drawing.Imaging.ImageFormat.Jpeg)
thumb.Save(context.Server.MapPath(thumbFolder & existingThumb), Drawing.Imaging.ImageFormat.Jpeg)
gfx.Dispose()
thumb.Dispose()
gfx = Nothing
thumb = Nothing
Catch ex As Exception
Dim fs As FileStream = Nothing
Try
fs = New FileStream(context.Server.MapPath(imagePath), IO.FileMode.Open, IO.FileAccess.Read, IO.FileShare.Read)
Dim imgLen As Long = fs.Length()
Dim imgData(imgLen) As Byte
fs.Read(imgData, 0, Integer.Parse(imgLen.ToString()))
context.Response.OutputStream.Write(imgData, 0, Integer.Parse(imgLen.ToString()))
Catch ex2 As UnauthorizedAccessException
'context.Server.Transfer(img)
Throw
Catch exIO As IOException
'context.Server.Transfer(img)
If trapCount > 0 Then
Throw
End If
trapCount += 1
ServeImage(context, "/images/PicUnavailable.jpg", maximumSize)
Finally
If Not fs Is Nothing Then
fs.Dispose()
fs = Nothing
End If
End Try
Finally
If Not imgFile Is Nothing Then
imgFile.Dispose()
imgFile = Nothing
End If
End Try
End If
End Sub
Public ReadOnly Property IsReusable() As Boolean Implements IHttpHandler.IsReusable
Get
Return False
End Get
End Property
End Class

Resources