I have the following code in my IHttpHandler:
Dim MemoryStream1 As New System.IO.MemoryStream
MemoryStream1.Write(SqlDataReader1("cover"), 0, SqlDataReader1("cover").Length - 1)
Dim Bitmap1 As System.Drawing.Bitmap = System.Drawing.Bitmap.FromStream(MemoryStream1)
Dim Width1 As Integer = Bitmap1.Width
Dim Height1 As Integer = Bitmap1.Height
Dim Width2 As Integer = 90
Dim Height2 As Integer = Height1 * Width1 / Width1
Dim Bitmap2 As System.Drawing.Bitmap = New System.Drawing.Bitmap(Width2, Height2)
Dim Graphics1 As System.Drawing.Graphics = System.Drawing.Graphics.FromImage(Bitmap2)
Graphics1.DrawImage(Bitmap1, 0, 0, Width2, Height2)
Dim MemoryStream2 As New System.IO.MemoryStream
Bitmap2.Save(MemoryStream2, System.Drawing.Imaging.ImageFormat.Png)
context.Response.BinaryWrite(MemoryStream2.ToArray)
It works but I'm not sure that it is the right way to resize an image. How to simplify that code?
Thanks in advance!
Public Function ResizeImage(imgToResize As Image, size As Size) As Byte()
Dim sourceWidth As Integer = imgToResize.Width
Dim sourceHeight As Integer = imgToResize.Height
Dim nPercent As Single = 0
Dim nPercentW As Single = 0
Dim nPercentH As Single = 0
nPercentW = (CSng(size.Width) / CSng(sourceWidth))
nPercentH = (CSng(size.Height) / CSng(sourceHeight))
If nPercentH < nPercentW Then
nPercent = nPercentH
Else
nPercent = nPercentW
End If
Dim destWidth As Integer = CInt(Math.Truncate(sourceWidth * nPercent))
Dim destHeight As Integer = CInt(Math.Truncate(sourceHeight * nPercent))
Dim b As New Bitmap(destWidth, destHeight)
Dim g As Graphics = Graphics.FromImage(DirectCast(b, Image))
g.InterpolationMode = InterpolationMode.HighQualityBicubic
g.DrawImage(imgToResize, 0, 0, destWidth, destHeight)
g.Dispose()
Return b.ToByteArray()
End Function
This function will resize an image to a specified size keeping its proporstion. It was in C# and I put it through an online converter so may not be 100% correct
ToByteArray() is an extension method I wrote to store the image in a DB i can give you that also if you like.
Basically the code is correct, but there are some problems with it:
You are skipping the last byte when you write into the first memory stream. The last property in the Write call should be the length, not the length minus one.
Your calculation of Height2 is incorrect. The expression Height1 * Width1 / Width1 will always evaluate to the value of Height1. You should use Height1 * Width2 / Width1 instead.
You are not disposing your memory streams, bitmaps or graphics objects. Use Using blocks to make sure that the objects are disposed.
You can simplify the code somewhat by creating the first memory stream from the byte array instead of writing the array to the stream:
Using MemoryStream1 As New System.IO.MemoryStream(SqlDataReader1("cover"))
Using Bitmap1 As System.Drawing.Bitmap = System.Drawing.Bitmap.FromStream(MemoryStream1)
Dim Width1 As Integer = Bitmap1.Width
Dim Height1 As Integer = Bitmap1.Height
Dim Width2 As Integer = 90
Dim Height2 As Integer = Height1 * Width2 / Width1
Using Bitmap2 As System.Drawing.Bitmap = New System.Drawing.Bitmap(Width2, Height2)
Using Graphics1 As System.Drawing.Graphics = System.Drawing.Graphics.FromImage(Bitmap2)
Graphics1.DrawImage(Bitmap1, 0, 0, Width2, Height2)
End Using
Using MemoryStream2 As New System.IO.MemoryStream
Bitmap2.Save(MemoryStream2, System.Drawing.Imaging.ImageFormat.Png)
context.Response.BinaryWrite(MemoryStream2.ToArray)
End Using
End Using
End Using
End Using
Related
I want to store bitmap image to byte, but in run time i'm getting error like
Conversion From type Image Format to Type Integer is Not Valid
Please Any one Help Me
For Each file As UploadedFile In` DOC.UploadedFiles`
Context.Cache.Remove(Session.SessionID + "UploadedFile")
Dim stream As Stream = file.InputStream
GenerateThumbnails(0.5, stream)
Dim DocumentImgName = file.FileName
Dim imgData As Byte() = New Byte(ViewState("CompressedImageData")) {}
Dim DocumentSplit = DocumentImgName.Split(".")
Dim ImgName = DocumentSplit(0)
Dim ImgExt = DocumentSplit(1)
stream.Read(imgData, 0, imgData.Length)
ViewState("imgData") = imgData
ViewState("FileName") = ImgName
ViewState("FileExtension") = ImgExt
Dim ms As New MemoryStream()
ms.Write(imgData, 0, imgData.Length)
Next
Private Sub GenerateThumbnails(ByVal scaleFactor As Double, ByVal sourcePath As Stream)
Using image__1 = Image.FromStream(sourcePath)
' can given width of image as we want
Dim newWidth = CInt(image__1.Width * scaleFactor)
' can given height of image as we want
Dim newHeight = CInt(image__1.Height * scaleFactor)
Dim thumbnailImg = New Bitmap(newWidth, newHeight)
Dim thumbGraph = Graphics.FromImage(thumbnailImg)
thumbGraph.CompositingQuality = CompositingQuality.HighQuality
thumbGraph.SmoothingMode = SmoothingMode.HighQuality
thumbGraph.InterpolationMode = InterpolationMode.HighQualityBicubic
Dim imageRectangle = New Rectangle(0, 0, newWidth, newHeight)
thumbGraph.DrawImage(image__1, imageRectangle)
ViewState("CompressedImageData") = image__1.RawFormat
End Using
End Sub
You Can Store an Image data after Convert it to Byte datatype as below:
Dim ms As New Syste.IO.MemoryStream
Me.PictureBox1.Image.Save(ms, PictureBox1.Image.RawFormat)
Dim byteImage() As Byte = ms.ToArray
Then You can Store The byteImage() to a field wich its type is Image Or Varbinary.
I use a Http Handler in my project,and i want to when client send to me a simple request ,i want read my files on server and return to client my image file url,and then client read this url and download the image.
This is example of how to retrieve image thumbnail, but you can modify its to retrieve whole picture, not thumbnail.
Public Sub ProcessRequest(ByVal context As HttpContext) Implements IHttpHandler.ProcessRequest
Dim ID As String = HttpContext.Current.Request.QueryString("HotelCode")
Dim con As String = ConfigurationManager.ConnectionStrings("hotelbedsConnectionString").ConnectionString
Dim logCon As New SqlConnection(con)
Dim cmd As New SqlCommand("Select ImagePath From HOTEL_IMAGES WHERE HotelCode = #HotelCode AND Order_='1'", logCon)
cmd.CommandType = CommandType.Text
cmd.Parameters.Add("HotelCode", SqlDbType.Int, 0).Value = ID
logCon.Open()
Dim MyData() As Byte
Dim wc = New WebClient
Dim path As String = cmd.ExecuteScalar()
If path Is Nothing Then
MyData = wc.DownloadData("http://www.blogasp.net/Images/nopic.jpg")
Else
MyData = wc.DownloadData("http://www.hotelbeds.com/giata/" & path)
End If
Dim ms As System.IO.MemoryStream = New System.IO.MemoryStream(MyData)
Dim img As System.Drawing.Image = Image.FromStream(ms)
Dim w As Integer = 100 '*** Fix Width ***'
Dim ratio As Double = img.Height / img.Width
Dim h As Integer = ratio * w
Dim thumbnail As Image = New Bitmap(w, h)
Dim graphics__2 As Graphics = Graphics.FromImage(thumbnail)
graphics__2.InterpolationMode = InterpolationMode.HighQualityBicubic
graphics__2.SmoothingMode = SmoothingMode.HighQuality
graphics__2.PixelOffsetMode = PixelOffsetMode.HighQuality
graphics__2.CompositingQuality = CompositingQuality.HighQuality
graphics__2.DrawImage(img, 0, 0, w, h)
Dim info As ImageCodecInfo() = ImageCodecInfo.GetImageEncoders()
Dim encoderParameters As EncoderParameters
encoderParameters = New EncoderParameters(1)
encoderParameters.Param(0) = New EncoderParameter(Encoder.Quality, 100L)
thumbnail.Save(HttpContext.Current.Response.OutputStream, info(1), encoderParameters)
logCon.Close()
Finalize()
End Sub
I have an issue where only the last page of my pdf is stored.
The pdf should be multiple pages long, and this works fine if I just send the pdf to the browser using Response and the mms memory stream, however I need to add it as a pdf to an email and therefore are writing mms to bytes to create a new memorystream when I create my email attachment. This is to get around the closed stream error.
This is my code
Public Shared Function SendPrePackLabels(ByVal bf_id As String, mail As String) As Boolean
Dim pars(0) As SqlParameter
pars(0) = New SqlParameter("#bf_id", SqlDbType.VarChar) With {.Value = bf_id}
Dim p As String
Dim reader As PdfReader
Dim mms As New MemoryStream
Dim rt() As Byte
Dim i As Integer = 0
Using dc As Document = New Document
Using sc As PdfSmartCopy = New PdfSmartCopy(dc, System.Web.HttpContext.Current.Response.OutputStream)
dc.Open()
With SqlHelper.ExecuteDataset(Stiletto.cnStrRMIS, CommandType.StoredProcedure, "BPM_spPrepack_Labels", pars).Tables(0)
For Each dr As DataRow In .Rows
Dim pdfr As New PdfReader("http://192.168.0.221/template.pdf")
Using ms As New MemoryStream
Using pdfs As New PdfStamper(pdfr, ms)
Dim fields As AcroFields = pdfs.AcroFields
fields.GenerateAppearances = True
fields.SetField("pono", dr.Item("po_no").ToString)
fields.SetField("ref", dr.Item("alt_code").ToString)
fields.SetField("colour", dr.Item("colour").ToString)
fields.SetField("code", dr.Item("sizerun_hdr_id").ToString)
For k As Integer = 1 To dr.Table.Columns.Count - 6
Dim j As Integer = k + 5
fields.SetField("s" & k, dr.Table.Columns(j).ColumnName.ToString)
If dr.Item(dr.Table.Columns(j).ColumnName.ToString).ToString = "" Then
p = "0"
Else
p = dr.Item(dr.Table.Columns(j).ColumnName.ToString).ToString
End If
fields.SetField("p" & k, p)
Next
fields.SetField("pack", dr.Item("sizerun_hdr_id").ToString)
Dim bcfont As BaseFont = BaseFont.CreateFont("http://192.168.0.221/ean.ttf", BaseFont.CP1252, BaseFont.EMBEDDED)
fields.SetFieldProperty("barcode", "textfont", bcfont, Nothing)
fields.SetFieldProperty("barcode", "textsize", 60.0F, Nothing)
Dim mBarcode As String = "219" & dr.Item("sizerun_hdr_id").ToString
Dim cLength As Integer = mBarcode.Length
Dim zerostoadd As Integer = 12 - cLength
Dim digit12barcode As String = mBarcode.PadRight(12, CChar("0"))
Dim FinalBarcode As String = returnCheckDigitedBarcode(digit12barcode)
fields.SetField("barcode", FinalBarcode)
Dim par(1) As SqlParameter
par(0) = New SqlParameter("#sizerun_hdr_id", SqlDbType.VarChar) With {.Value = dr.Item("sizerun_hdr_id").ToString}
par(1) = New SqlParameter("#ean13", SqlDbType.VarChar) With {.Value = FinalBarcode}
SqlHelper.ExecuteScalar(Stiletto.cnStrRMIS, CommandType.StoredProcedure, "BPM_spSizeRunEAN13", par)
pdfs.FormFlattening = True
ms.Flush()
End Using
reader = New PdfReader(ms.ToArray)
sc.AddPage(sc.GetImportedPage(reader, 1))
mms = ms
End Using
Next
End With
End Using
End Using
Dim bt() As Byte = mms.ToArray
Try
If mail.Length > 0 Then
Dim eMsg As New MailMessage()
eMsg.From = New MailAddress("myemail#mydomain.co.uk")
eMsg.To.Add(New MailAddress(mail))
Dim title As String = "<h3>Here are the Prepack Labels.</h3>"
eMsg.Subject = "Prepack Labels"
eMsg.Body = "<html>" & title & "</html>"
eMsg.IsBodyHtml = True
Dim att As Attachment = New Attachment(New MemoryStream(bt), "Prepack Labels.pdf", "application/pdf")
eMsg.Attachments.Add(att)
Dim SMTP1 As New SmtpClient
SMTP1.Host = "EX"
SMTP1.Send(eMsg)
att.Dispose()
End If
Return True
Catch ex As Exception
Return False
End Try
End Function
I'm not sure of your exact problem but I'm pretty sure your life would be easier if you broke you giant function into smaller more specific functions that do only one thing. Also, I really recommend never writing to the raw ASP.Net stream until after you've created a PDF. Instead, always write to a MemoryStream, grab the bytes and do something with them.
The code below break it into four functions. CreatePdf() loops through the database and calls CreateSinglePdf() for each row in the table, merging them with your PdfSmartCopy. SendEmail() is blissfully unaware of iTextSharp completely and just receives a raw array of bytes that is assumed to be a PDF. This is all kicked off by SendPrePackLabels() which is where you'd probably want to also Response.BinaryWrite() your bytes.
Public Shared Function SendPrePackLabels(ByVal bf_id As String, mail As String) As Boolean
Dim bt = CreatePdf(bf_id)
Return SendEmail(bt, mail)
End Function
Public Shared Function CreateSinglePdf(dr As DataRow) As Byte()
Using ms As New MemoryStream
Using pdfr As New PdfReader("http://192.168.0.221/template.pdf")
Using pdfs As New PdfStamper(pdfr, ms)
Dim fields As AcroFields = pdfs.AcroFields
fields.GenerateAppearances = True
fields.SetField("pono", dr.Item("po_no").ToString)
fields.SetField("ref", dr.Item("alt_code").ToString)
fields.SetField("colour", dr.Item("colour").ToString)
fields.SetField("code", dr.Item("sizerun_hdr_id").ToString)
Dim p As String
For k As Integer = 1 To dr.Table.Columns.Count - 6
Dim j As Integer = k + 5
fields.SetField("s" & k, dr.Table.Columns(j).ColumnName.ToString)
If dr.Item(dr.Table.Columns(j).ColumnName.ToString).ToString = "" Then
p = "0"
Else
p = dr.Item(dr.Table.Columns(j).ColumnName.ToString).ToString
End If
fields.SetField("p" & k, p)
Next
fields.SetField("pack", dr.Item("sizerun_hdr_id").ToString)
Dim bcfont As BaseFont = BaseFont.CreateFont("http://192.168.0.221/ean.ttf", BaseFont.CP1252, BaseFont.EMBEDDED)
fields.SetFieldProperty("barcode", "textfont", bcfont, Nothing)
fields.SetFieldProperty("barcode", "textsize", 60.0F, Nothing)
Dim mBarcode As String = "219" & dr.Item("sizerun_hdr_id").ToString
Dim cLength As Integer = mBarcode.Length
Dim zerostoadd As Integer = 12 - cLength
Dim digit12barcode As String = mBarcode.PadRight(12, CChar("0"))
Dim FinalBarcode As String = returnCheckDigitedBarcode(digit12barcode)
fields.SetField("barcode", FinalBarcode)
Dim par(1) As SqlParameter
par(0) = New SqlParameter("#sizerun_hdr_id", SqlDbType.VarChar) With {.Value = dr.Item("sizerun_hdr_id").ToString}
par(1) = New SqlParameter("#ean13", SqlDbType.VarChar) With {.Value = FinalBarcode}
SqlHelper.ExecuteScalar(Stiletto.cnStrRMIS, CommandType.StoredProcedure, "BPM_spSizeRunEAN13", par)
pdfs.FormFlattening = True
End Using
End Using
Return ms.ToArray()
End Using
End Function
Public Shared Function CreatePdf(ByVal bf_id As String) As Byte()
Dim pars(0) As SqlParameter
pars(0) = New SqlParameter("#bf_id", SqlDbType.VarChar) With {.Value = bf_id}
Using ms As New System.IO.MemoryStream
Using dc As Document = New Document
Using sc As PdfSmartCopy = New PdfSmartCopy(dc, ms)
dc.Open()
With SqlHelper.ExecuteDataset(Stiletto.cnStrRMIS, CommandType.StoredProcedure, "BPM_spPrepack_Labels", pars).Tables(0)
For Each dr As DataRow In .Rows
Dim pageBytes = CreateSinglePdf(dr)
Using reader = New PdfReader(pageBytes)
sc.AddPage(sc.GetImportedPage(reader, 1))
End Using
Next
End With
End Using
End Using
Return ms.ToArray()
End Using
End Function
Public Shared Function SendEmail(bt As Byte(), mail As String) As Boolean
Try
If mail.Length > 0 Then
Dim eMsg As New MailMessage()
eMsg.From = New MailAddress("myemail#mydomain.co.uk")
eMsg.To.Add(New MailAddress(mail))
Dim title As String = "<h3>Here are the Prepack Labels.</h3>"
eMsg.Subject = "Prepack Labels"
eMsg.Body = "<html>" & title & "</html>"
eMsg.IsBodyHtml = True
Dim att As Attachment = New Attachment(New MemoryStream(bt), "Prepack Labels.pdf", "application/pdf")
eMsg.Attachments.Add(att)
Dim SMTP1 As New SmtpClient
SMTP1.Host = "EX"
SMTP1.Send(eMsg)
att.Dispose()
End If
Return True
Catch ex As Exception
Return False
End Try
End Function
I have two datatables (dtSF and CurveFitTable) that contain two different values which I have to multiply. The objective is to produce a datatable that contains the product of two values from two different datatables. The twist is, the CurveFitTable came from different csv files in a directory which I already defined.
What I intended to do is to have a datatable like the adjustedCopy table in the image below. Unfortunately, what I'm getting is a single datatable which kept on being overwritten and whenever I attempt to databind it to the grid, the datatable seems to be empty. Please help. T.T
This is my code:
Dim adjusteddemandtable As New DataTable()
Dim adjustedcopy As New DataTable()
Dim multiply_SF As Double
Dim adjusted_Demand As Double
Dim initial_Demand As Double
Dim basecurvestamp As Date
adjusteddemandtable.Columns.Add("Base Curve", GetType(Date))
adjusteddemandtable.Columns("Base Curve").SetOrdinal(0)
adjusteddemandtable.Columns.Add("Adjusted_Demand", GetType(Double))
Dim CurveFitTatble As New DataTable()
Try
For Each filename As String In System.IO.Directory.GetFiles(BackUpDirectory)
CurveFitTatble = GetDataTabletFromCSVFile(filename)
For Each row2 As DataRow In dtSF.Rows()
For Each row As DataRow In CurveFitTatble.Rows()
initial_Demand = row(1)
basecurvestamp = row(0)
multiply_SF = row2(0)
adjusted_Demand = multiply_SF * initial_Demand
Dim rowa As DataRow = adjusteddemandtable.Rows.Add()
rowa(0) = basecurvestamp
rowa(1) = adjusted_Demand
Next
Next
adjustedcopy.Merge(adjusteddemandtable, True, MissingSchemaAction.AddWithKey)
Next
GridView1.DataSource = adjustedcopy
GridView1.DataBind()
Catch ex As Exception
ErrorMessageBox(ex.Message)
End Try
I think, I'm missing something or overlooked an important step. Please advise. Thanks in advance.
I just did what #jmcilhinney told me (that is to replace nested Foreach nested loop. Here is my new code (and fortunately, it is working as its expected output requires)
Try
Dim y As Integer = System.IO.Directory.GetFiles(BackUpDirectory).Length
Dim row1 As DataRow
Dim i As Integer = 0
While i < y
row1 = dtSF.Rows(i)
Dim filenames As String() = System.IO.Directory.GetFiles(BackUpDirectory)
Dim filename As String = filenames(i)
multiply_SF = row1(0)
CurveFitTatble = New DataTable()
Dim TS_Name As String = "TmeStamp" + "_" & i
Dim AD_Name As String = "AdjustedDemand" + "_" & i
If i = 0 Then
adjusteddemandtable.Columns.Add(TS_Name, GetType(Date))
adjusteddemandtable.Columns(TS_Name).SetOrdinal(i)
adjusteddemandtable.Columns.Add(AD_Name, GetType(Double))
adjusteddemandtable.Columns(AD_Name).SetOrdinal(i + 1)
ElseIf i > 0 Then
adjusteddemandtable.Columns.Add(TS_Name, GetType(Date))
adjusteddemandtable.Columns(TS_Name).SetOrdinal(i + 1)
adjusteddemandtable.Columns.Add(AD_Name, GetType(Double))
adjusteddemandtable.Columns(AD_Name).SetOrdinal(i + 2)
End If
'If row1(0) = filename Then
CurveFitTatble = GetDataTabletFromCSVFile(filename)
'For Each row As DataRow In CurveFitTatble.Rows()
Dim row As DataRow
For j As Integer = 0 To CurveFitTatble.Rows.Count - 1
row = CurveFitTatble.Rows(j)
initial_Demand = row(1)
basecurvestamp = row(0)
adjusted_Demand = multiply_SF * initial_Demand
Dim rowa As DataRow = adjusteddemandtable.Rows.Add()
If i = 0 Then
rowa(i) = basecurvestamp
rowa(i + 1) = adjusted_Demand
ElseIf i > 0 Then
rowa(i + 1) = basecurvestamp
rowa(i + 2) = adjusted_Demand
End If
Next
i = i + 1
End While
Catch ex As Exception
ErrorMessageBox(ex.Message)
End Try
i was searching google for some kind solution and i found one, i tried to implement it in my code but it doesn't work. The problem is that after resizing white images they gets gray border.
Here is the link of soloution i found:
It says:
This problem is occuring because you are interpolating your image data to a
new size, but along the edges there are no pixels to interpolate and .NET
uses black pixels for these edges by default. To fix this you need to use an
ImageAttributes class in your DrawImage call....
https://groups.google.com/group/microsoft.public.dotnet.framework.drawing/browse_thread/thread/d834851b49274fd9/81a4fd43694457ac?hl=en&lnk=st&q=DrawImage+resized+border#81a4fd43694457ac
CODE 1: And this is my code WITH IMPLEMENTATION OF ImageAttributes:
Private Shared Function ResizeImageFile(ByVal imageFile As Byte(), ByVal targetSize As Integer) As Byte()
Using oldImage As System.Drawing.Image = System.Drawing.Image.FromStream(New MemoryStream(imageFile))
Dim newSize As Size = CalculateDimensions(oldImage.Size, targetSize)
Using newImage As New Bitmap(newSize.Width, newSize.Height, PixelFormat.Format32bppRgb)
Using canvas As Graphics = Graphics.FromImage(newImage)
Using ia As New ImageAttributes
ia.SetWrapMode(Drawing2D.WrapMode.TileFlipXY)
canvas.SmoothingMode = SmoothingMode.AntiAlias
canvas.InterpolationMode = InterpolationMode.HighQualityBicubic
canvas.PixelOffsetMode = PixelOffsetMode.HighQuality
canvas.DrawImage(oldImage, New Rectangle(New Point(0, 0), newSize), 0, 0, newImage.Width, newImage.Height, GraphicsUnit.Pixel, ia)
Dim m As New MemoryStream()
newImage.Save(m, ImageFormat.Png)
Return m.GetBuffer()
End Using
End Using
End Using
End Using
End Function
Private Shared Function CalculateDimensions(ByVal oldSize As Size, ByVal targetSize As Integer) As Size
Dim newSize As New Size()
If oldSize.Height > oldSize.Width Then
newSize.Width = CInt((oldSize.Width * (CSng(targetSize) / CSng(oldSize.Height))))
newSize.Height = targetSize
Else
newSize.Width = targetSize
newSize.Height = CInt((oldSize.Height * (CSng(targetSize) / CSng(oldSize.Width))))
End If
Return newSize
End Function
CODE 2: CODE THAT COUSES A GRAY BORDER ON WHITE IMAGE
Here is the image after resizing:
new image size in width = 400px
Private Shared Function ResizeImageFile(ByVal imageFile As Byte(), ByVal targetSize As Integer) As Byte()
Using oldImage As System.Drawing.Image = System.Drawing.Image.FromStream(New MemoryStream(imageFile))
Dim newSize As Size = CalculateDimensions(oldImage.Size, targetSize)
Using newImage As New Bitmap(newSize.Width, newSize.Height, PixelFormat.Format32bppRgb)
Using canvas As Graphics = Graphics.FromImage(newImage)
canvas.SmoothingMode = SmoothingMode.AntiAlias
canvas.InterpolationMode = InterpolationMode.HighQualityBicubic
canvas.PixelOffsetMode = PixelOffsetMode.HighQuality
canvas.DrawImage(oldImage, New Rectangle(New Point(0, 0), newSize))
Dim m As New MemoryStream()
newImage.Save(m, ImageFormat.Png)
Return m.GetBuffer()
End Using
End Using
End Using
End Function
Private Shared Function CalculateDimensions(ByVal oldSize As Size, ByVal targetSize As Integer) As Size
Dim newSize As New Size()
If oldSize.Height > oldSize.Width Then
newSize.Width = CInt((oldSize.Width * (CSng(targetSize) / CSng(oldSize.Height))))
newSize.Height = targetSize
Else
newSize.Width = targetSize
newSize.Height = CInt((oldSize.Height * (CSng(targetSize) / CSng(oldSize.Width))))
End If
Return newSize
End Function
UPDATE 30.07.2011.:
CODE 1 solved the problem with the gray borders on white images, but there is new problem. The problem is in this line of code:
canvas.DrawImage(oldImage, New Rectangle(New Point(0, 0), newSize), 0, 0, newImage.Width, newImage.Height, GraphicsUnit.Pixel, ia)
With this code I get output image with desired width and height and without gray borders but the oldImage isn't scaled.
For example:
If I want to upload, resize and save the image that is orginaly for instance 640x480px and that the targetSize is 400px. As output I get an image that is width: 400px, height: 300px, without gray borders, but oldImage isn't resized/scaled to 400px. Insted of this, oldImage is drawn with the original resolution. How to scale oldImage to be drawn correctly? Can someone point me to the right solution or modify the code?
Thanx to everyone, but I found the solution to all my problems.
The CODE 1 didn't work correctly because of the following line of code:
canvas.DrawImage(oldImage, New Rectangle(New Point(0, 0), newSize), 0, 0, newImage.Width, newImage.Height, GraphicsUnit.Pixel, ia)
SOLUTION:
canvas.DrawImage(oldImage, New Rectangle(New Point(0, 0), newSize), 0, 0, oldImage.Width, oldImage.Height, GraphicsUnit.Pixel, ia)
HERE IS THE FULL WORKING CODE (resized image without gray/black borders):
Private Shared Function ResizeImageFile(ByVal imageFile As Byte(), ByVal targetSize As Integer) As Byte()
Using oldImage As System.Drawing.Image = System.Drawing.Image.FromStream(New MemoryStream(imageFile))
Dim newSize As Size = CalculateDimensions(oldImage.Size, targetSize)
Using newImage As New Bitmap(newSize.Width, newSize.Height, PixelFormat.Format32bppRgb)
Using canvas As Graphics = Graphics.FromImage(newImage)
Using ia As New ImageAttributes
ia.SetWrapMode(Drawing2D.WrapMode.TileFlipXY)
canvas.SmoothingMode = SmoothingMode.AntiAlias
canvas.InterpolationMode = InterpolationMode.HighQualityBicubic
canvas.PixelOffsetMode = PixelOffsetMode.HighQuality
canvas.DrawImage(oldImage, New Rectangle(New Point(0, 0), newSize), 0, 0, oldImage.Width, oldImage.Height, GraphicsUnit.Pixel, ia)
Dim m As New MemoryStream()
newImage.Save(m, ImageFormat.Png)
Return m.GetBuffer()
End Using
End Using
End Using
End Using
End Function
Private Shared Function CalculateDimensions(ByVal oldSize As Size, ByVal targetSize As Integer) As Size
Dim newSize As New Size()
If oldSize.Height > oldSize.Width Then
newSize.Width = CInt((oldSize.Width * (CSng(targetSize) / CSng(oldSize.Height))))
newSize.Height = targetSize
Else
newSize.Width = targetSize
newSize.Height = CInt((oldSize.Height * (CSng(targetSize) / CSng(oldSize.Width))))
End If
Return newSize
End Function
Here is a function out of a class I have, you will have to replace some of the class Properties(ThumbNailSize.Width, ThumbNailSize.Height):
public void ResizeImage(HttpPostedFile fil, string sPhysicalPath,
string sOrgFileName,string sThumbNailFileName,
ImageFormat oFormat, int rez)
{
try
{
System.Drawing.Image oImg = System.Drawing.Image.FromStream(fil.InputStream);
decimal pixtosubstract = 0;
decimal percentage;
//default
Size ThumbNailSizeToUse = new Size();
if (ThumbNailSize.Width < oImg.Size.Width || ThumbNailSize.Height < oImg.Size.Height)
{
if (oImg.Size.Width > oImg.Size.Height)
{
percentage = (((decimal)oImg.Size.Width - (decimal)ThumbNailSize.Width) / (decimal)oImg.Size.Width);
pixtosubstract = percentage * oImg.Size.Height;
ThumbNailSizeToUse.Width = ThumbNailSize.Width;
ThumbNailSizeToUse.Height = oImg.Size.Height - (int)pixtosubstract;
}
else
{
percentage = (((decimal)oImg.Size.Height - (decimal)ThumbNailSize.Height) / (decimal)oImg.Size.Height);
pixtosubstract = percentage * (decimal)oImg.Size.Width;
ThumbNailSizeToUse.Height = ThumbNailSize.Height;
ThumbNailSizeToUse.Width = oImg.Size.Width - (int)pixtosubstract;
}
}
else
{
ThumbNailSizeToUse.Width = oImg.Size.Width;
ThumbNailSizeToUse.Height = oImg.Size.Height;
}
Bitmap bmp = new Bitmap(ThumbNailSizeToUse.Width, ThumbNailSizeToUse.Height);
bmp.SetResolution(rez, rez);
System.Drawing.Image oThumbNail = bmp;
bmp = null;
Graphics oGraphic = Graphics.FromImage(oThumbNail);
oGraphic.CompositingQuality = CompositingQuality.HighQuality;
oGraphic.SmoothingMode = SmoothingMode.HighQuality;
oGraphic.InterpolationMode = InterpolationMode.HighQualityBicubic;
Rectangle oRectangle = new Rectangle(0, 0, ThumbNailSizeToUse.Width, ThumbNailSizeToUse.Height);
oGraphic.DrawImage(oImg, oRectangle);
oThumbNail.Save(sPhysicalPath + sThumbNailFileName, oFormat);
oImg.Dispose();
}
catch (Exception ex)
{
Response.Write(ex.Message);
}
}