WPF Image Resizing error: System.Runtime.InteropServices.COMException: Exception from HRESULT: 0x80072EE4

0

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.jpgis 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
wpf
image-processing
comexception
asked on Stack Overflow Feb 2, 2016 by Flo • edited Feb 3, 2016 by Flo

0 Answers

Nobody has answered this question yet.


User contributions licensed under CC BY-SA 3.0