JPEG图片加载错误

3

这个错误已经有很多帖子了,但我似乎找不到解决方案。当我使用 LoadPicture() 函数在用户窗体上的图像控件中编程加载图片时,会出现以下错误:

运行时错误 481 - 无效图片

手动加载时会出现类似的

无效图片

消息。

通过我的互联网搜索,我发现了许多关于这个错误的建议;大多数帖子倾向于是因为用户上传了一个 png 或其他无效图像(例如损坏的 jpg),一些人认为我的 temp 文件夹已满,还有一些人认为病毒是原因(我对最后一个持怀疑态度)。

在我的应用程序中,我的图片是

  • 一个 jpg(在他们的 LoadPicture() 文章的备注部分中,MSDN 列出了可接受的格式

  • 没有损坏(至少,我可以用 Windows 照片查看器/ Chrome/ Paint 正常查看它)

  • 相对较小(即,它是 ~1MPx,我测试了一个 200MPx 的 jpeg,没有任何错误)

唯一有点不寻常的事情是,我正在使用以下代码直接从网络下载:

Public Declare Function URLDownloadToFile Lib "urlmon" _
    Alias "URLDownloadToFileA" _
    (ByVal pCaller As Long, _
    ByVal szURL As String, _
    ByVal szFileName As String, _
    ByVal dwReserved As Long, _
    ByVal lpfnCB As Long) As Long 'api to download files

Sub setPicTest()
    Dim tmpImg As MSForms.Image 'create an image control on UserForm1 at runtime
    Set tmpImg = UserForm1.Controls.Add("Forms.Image.1")
    tmpImg.Picture = getImg("https://s-media-cache-ak0.pinimg.com/originals/22/e2/4d/22e24d3b5703a1c1cc43df5b13f53fd2.png")
End Sub

Function getImg(url As String) As IPictureDisp 'loads a picture from a url
    Dim strFile As String 'file save location
    strFile = Environ("Temp") & "\Temp.jpg" 'save *as jpeg* in %temp% folder
    Debug.Print URLDownloadToFile(0, url, strFile, 0, 0) 'download file to temp folder
    Set getImg = LoadPicture(strFile) 'load image -error-
    Kill strFile 'clean up temp file
End Function

当我进行步骤时,一切都按预期运行。
  • 我的用户窗体上出现了一个空的(没有图片)图像控件
  • 在我的临时文件夹中出现了一个名为temp.jpg的文件
    • 这个文件似乎没有损坏

但是接下来代码执行时出现了错误。这特别令人惊讶,因为这段代码对于小缩略图图片一直都能正常工作,只有这些高分辨率的图片好像无法正常工作。


1
这是一个png文件。将其重命名为jpg不会有任何帮助 :) - Siddharth Rout
2个回答

5
这是一个png文件,更改文件名为jpg不会有所帮助。URLDownloadToFile下载文件,但不会更改文件类型。
话虽如此,这里有一种实现你想要的方式 ;)
逻辑:
1. 插入临时工作表。 2. 直接将图像插入工作表。 3. 插入图表。 4. 将图像复制到图表并将其导出为.Jpg格式。 5. 使用LoadPicture加载图像。 6. 删除我们创建的对象和临时文件。
代码
Sub setPicTest()
    Dim wsTemp As Worksheet
    Dim tmpImg As MSForms.Image
    Dim PicPath As String, tmpPath As String
    Dim oCht As Chart

    Set tmpImg = UserForm1.Controls.Add("Forms.Image.1")

    Set wsTemp = ThisWorkbook.Sheets.Add

    '~~> This is the .PNG image
    PicPath = "https://s-media-cache-ak0.pinimg.com/originals/22/e2/4d/22e24d3b5703a1c1cc43df5b13f53fd2.png"
    '~~> This will be the .JPG image
    tmpPath = Environ("Temp") & "\Temp.jpg"

    With wsTemp
        .Pictures.Insert(PicPath).ShapeRange.LockAspectRatio = msoTrue
        DoEvents
        Set oCht = Charts.Add
        .Shapes(1).CopyPicture xlScreen, xlBitmap

        With oCht
            .Paste
            .Export Filename:=tmpPath, Filtername:="JPG"
        End With
        DoEvents

        tmpImg.Picture = LoadPicture(tmpPath)

        '~~> Clean Up
        On Error Resume Next
        Application.DisplayAlerts = False
        .Delete
        oCht.Delete
        Application.DisplayAlerts = True
        On Error GoTo 0
    End With

    '~~> Delete the temp image
    Kill tmpPath
End Sub

编辑

为了测试目的,我使用了以下设置

Set tmpImg = UserForm1.Controls.Add("Forms.Image.1")

With tmpImg
    .Left = 20        '~~> This property does not shown in Intellisense
    .Width = 300      '~~> This property does not shown in Intellisense
    .Height = 300     '~~> This property does not shown in Intellisense
    .Top = 10         '~~> This property does not shown in Intellisense

    .PictureAlignment = fmPictureAlignmentCenter
    .PictureSizeMode = fmPictureSizeModeStretch
End With

屏幕截图

![在此输入图片描述


这是一种比我看到的一些API方法要简单得多(或者至少更容易理解)的方法。我知道我错在哪里了,我想我试图避免使用除内置的LoadPicture()之外的任何东西,而且我只是假设因为文件显示出来了,它就已经成功转换成了jpg格式(而不仅仅是重命名)。我还发现了可能是一种稍微更直接的方法(但与您的方法相比,兼容性较差/执行时间可能更长)。 - Greedo

0
如@Siddharth Rout所指出的那样,即使对于Windows资源管理器来说,我下载的文件看起来像是一个jpeg文件,但它实际上仍然是一个png文件,这正是导致错误的原因。相信我,我的实际代码比我在这里发布的要复杂得多,因此文件的png扩展名被隐藏了起来,更难以发现!
无论如何,他提供了一种将该png文件放入图像控件中的解决方法。我选择采用的另一种选项是:
Function getImg(url As String) As IPictureDisp 'loads a picture from a url
    Dim strFile As String 'file save location
    strFile = Environ("Temp") & "\Temp.png" 'save with more extensions like png in %temp% folder
    Debug.Print URLDownloadToFile(0, url, strFile, 0, 0) 'download file to temp folder
    With New WIA.ImageFile
        .LoadFile strFile
        Set getImgPng = .FileData.Picture 'return same thing as LoadPicture() would
    End With
    Kill strFile 'clean up temp file
End Function

WIA.ImageFile 对象需要引用 Microsoft Windows Image Acquisition Library v2.0,该库在 Windows Vista 或更新版本中可用。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接