WPF图像大小调整错误:System.Runtime.InteropServices.COMException:来自HRESULT的异常:0x80072EE4

时间:2016-02-02 21:04:17

标签: wpf image-processing comexception

以下代码抛出错误:

  

System.Runtime.InteropServices.COMException:来自HRESULT的异常:   0x80072EE4

代码行上的


Dim bdDecoder As BitmapDecoder = BitmapDecoder.Create(streamPhoto, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.None)

为什么呢?请求的网址存在并返回200. Google没有帮助解决此问题。

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

更新1

好的,现在保存了图像。但是调整大小只能在示例.png文件中正常工作,而不能在.jpg文件上正常工作。 戴尔徽标以200x199像素保存,保留了透明度,这是完美的。 另一个文件1116220.jpg保存在625x441px中......为什么不符合200px所需的最大宽度/高度?

我检查了代码,我发现的唯一区别是对于png文件,尺寸是一个整数:

bfPhoto.Width   2000
bfPhoto.Height  1994

FastResize执行后变为

bfResize.Width  200
bfResize.Height 199

jpg的尺寸在哪里

bfPhoto.Width   982,719970703125
bfPhoto.Height  695,039978027344

FastResize执行后变为

bfResize.Width  200
bfResize.Height 141,119995117188

所以我试着看看它是否与该图像有关并尝试使用另一个jpg文件:https://upload.wikimedia.org/wikipedia/commons/d/d8/Square-1_solved.jpg

jpg的尺寸在哪里

bfPhoto.Width   600
bfPhoto.Height  600

FastResize执行后变为

bfResize.Width
bfResize.Height

这确实有效,所以现在我知道它与文件无关。它似乎与图像1116220.jpg的尺寸有关,但我不知道我是否可以通过不同的缩放或以其他方式解决这个问题......

我的代码:

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

0 个答案:

没有答案