The code below is throwing error:
System.Runtime.InteropServices.COMException: Exception from HRESULT: 0x80072EE4
on code line:
Dim bdDecoder As BitmapDecoder = BitmapDecoder.Create(streamPhoto, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.None)
Why? The requested URL exists and returns a 200. Google is not helping on this one.
Private Sub ResizeAndSave(ByVal imageURL As String)
Dim imgRequest As WebRequest = WebRequest.Create(imageURL)
Dim imgResponse As WebResponse = imgRequest.GetResponse()
Dim strThumbnail As String = "success.png"
Dim streamPhoto As Stream = imgResponse.GetResponseStream()
Dim memStream As New MemoryStream
streamPhoto.CopyTo(memStream)
Dim bfPhoto As BitmapFrame = ReadBitmapFrame(memStream)
Dim nThumbnailSize As Integer = 200, nWidth As Integer, nHeight As Integer
If bfPhoto.Width > bfPhoto.Height Then
nWidth = nThumbnailSize
nHeight = CInt(bfPhoto.Height * nThumbnailSize / bfPhoto.Width)
Else
nHeight = nThumbnailSize
nWidth = CInt(bfPhoto.Width * nThumbnailSize / bfPhoto.Height)
End If
Dim bfResize As BitmapFrame = FastResize(bfPhoto, nWidth, nHeight)
Dim baResize As Byte() = ToByteArray(bfResize)
Dim saveToPath As String = Server.MapPath(ConfigurationManager.AppSettings("products_photospath")) + "\49\" + strThumbnail
File.WriteAllBytes(saveToPath, baResize)
Console.WriteLine("Resize done!!!")
End Sub
Private Shared Function FastResize(bfPhoto As BitmapFrame, nWidth As Integer, nHeight As Integer) As BitmapFrame
Dim tbBitmap As New TransformedBitmap(bfPhoto, New ScaleTransform(nWidth / bfPhoto.Width, nHeight / bfPhoto.Height, 0, 0))
Return BitmapFrame.Create(tbBitmap)
End Function
Private Shared Function ToByteArray(bfResize As BitmapFrame) As Byte()
Using msStream As New MemoryStream()
Dim pbdDecoder As New PngBitmapEncoder()
pbdDecoder.Frames.Add(bfResize)
pbdDecoder.Save(msStream)
Return msStream.ToArray()
End Using
End Function
Private Shared Function ReadBitmapFrame(streamPhoto As Stream) As BitmapFrame
Dim bdDecoder As BitmapDecoder = BitmapDecoder.Create(streamPhoto, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.None)
Return bdDecoder.Frames(0)
End Function
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
ResizeAndSave("http://cdn2.emobassets.eu/media/catalog/product/1/1/1116220.jpg")
End Sub
UPDATE 1
Ok, images are now saved. But the resize only works correctly on the example .png file, and NOT on the .jpg file.
The Dell logo is saved in 200x199 px preserving transparancy, which is perfect.
The other file 1116220.jpg
is saved in 625x441px...why is that not respecting the desired max width/height of 200px?
I checked into the code and the only difference I can spot is that for the png file the dimensions are a round number:
bfPhoto.Width 2000
bfPhoto.Height 1994
After FastResize
executes that becomes
bfResize.Width 200
bfResize.Height 199
Where for the jpg the dimensions are
bfPhoto.Width 982,719970703125
bfPhoto.Height 695,039978027344
After FastResize
executes that becomes
bfResize.Width 200
bfResize.Height 141,119995117188
So I tried to see if it was related to that image and tried with another jpg file: https://upload.wikimedia.org/wikipedia/commons/d/d8/Square-1_solved.jpg
Where for the jpg the dimensions are
bfPhoto.Width 600
bfPhoto.Height 600
After FastResize
executes that becomes
bfResize.Width
bfResize.Height
That does work, so now I know it's not related to the file being a .jpg. It seems to be related to the dimensions of image 1116220.jpg
, but I don't know if I can work around that by scaling differently or in some other way...
My code:
Private Sub ResizeAndSave(ByVal maxWidth As Integer, ByVal maxHeight As Integer, ByVal imageURL As String)
Dim imgRequest As WebRequest = WebRequest.Create(imageURL)
Dim imgResponse As WebResponse = imgRequest.GetResponse()
Dim streamPhoto As Stream = imgResponse.GetResponseStream()
Dim memStream As New MemoryStream
streamPhoto.CopyTo(memStream)
memStream.Position = 0
Dim bfPhoto As BitmapFrame = ReadBitmapFrame(memStream)
Dim newWidth, newHeight As Integer
Dim scaleFactor As Double
If bfPhoto.Width > maxWidth Or bfPhoto.Height > maxHeight Then
If bfPhoto.Width > maxWidth Then
scaleFactor = maxWidth / bfPhoto.Width
newWidth = Math.Round(bfPhoto.Width * scaleFactor, 0)
newHeight = Math.Round(bfPhoto.Height * scaleFactor, 0)
End If
If newHeight > maxHeight Then
scaleFactor = maxHeight / newHeight
newWidth = Math.Round(newWidth * scaleFactor, 0)
newHeight = Math.Round(newHeight * scaleFactor, 0)
End If
End If
Dim bfResize As BitmapFrame = FastResize(bfPhoto, newWidth, newHeight)
Dim baResize As Byte() = ToByteArray(bfResize)
Dim strThumbnail As String = "success" + Date.Now.Second.ToString + ".png"
Dim saveToPath As String = Server.MapPath(ConfigurationManager.AppSettings("products_photospath")) + "\49\" + strThumbnail
File.WriteAllBytes(saveToPath, baResize)
End Sub
Private Shared Function FastResize(bfPhoto As BitmapFrame, nWidth As Integer, nHeight As Integer) As BitmapFrame
Dim tbBitmap As New TransformedBitmap(bfPhoto, New ScaleTransform(nWidth / bfPhoto.Width, nHeight / bfPhoto.Height, 0, 0))
Return BitmapFrame.Create(tbBitmap)
End Function
Private Shared Function ToByteArray(bfResize As BitmapFrame) As Byte()
Using msStream As New MemoryStream()
Dim pbdDecoder As New PngBitmapEncoder()
pbdDecoder.Frames.Add(bfResize)
pbdDecoder.Save(msStream)
Return msStream.ToArray()
End Using
End Function
Private Shared Function ReadBitmapFrame(streamPhoto As Stream) As BitmapFrame
Dim bdDecoder As BitmapDecoder = BitmapDecoder.Create(streamPhoto, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.None)
Return bdDecoder.Frames(0)
End Function
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
ResizeAndSave(200, 200, "https://upload.wikimedia.org/wikipedia/commons/8/82/Dell_Logo.png")
ResizeAndSave(200, 200, "http://cdn2.emobassets.eu/media/catalog/product/1/1/1116220.jpg")
End Sub
User contributions licensed under CC BY-SA 3.0