Greedo
Greedo

Reputation: 5543

Load Picture error for JPEG

There's loads of posts on this error already but I can't seem to find a solution; when loading a picture programmatically (with the LoadPicture() function) to an image control on a userform I get this error:

Run-time error 481 - Invalid picture

and a similar

Invalid picture

message when it's loaded manually.

From my internet searches I've found a whole load of advice on this error; most posts tend to be because the user is uploading a png or other invalid image (such as a corrupt jpg), some suggest that my temp folder is full, others think a virus is the reason (I'm sceptical about that last one).

In my application, my picture is

The only thing slightly unusual is that I'm downloading this straight from the web using the following code:

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

As I step through, everything runs as expected

But then code execution breaks on the error. This is particularly surprising as the code has been working fine for little thumbnail images, it's just these full resolution images don't seem to be working.

Upvotes: 3

Views: 4455

Answers (2)

Greedo
Greedo

Reputation: 5543

As @Siddharth Rout points out, even though to windows explorer the file I downloaded looks like a jpeg, it was indeed still a png which is what caused the error. Believe me when I say that my actual code was a lot less clear than what I posted here and so the png extension of the file was hidden and much harder to spot!

Anyway, he provides one answer for getting the png into an image control. Another option that I'm going with would be:

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

The WIA.ImageFile object requires a reference to the Microsoft Windows Image Acquisition Library v2.0 which is available in Windows Vista or newer.

Upvotes: 0

Siddharth Rout
Siddharth Rout

Reputation: 149335

It is a png file. Renaming it to jpg will not help. URLDownloadToFile downloads a file. It doesn't change the file type.

Having said that here is one way to achieve what you want ;)

Logic:

  1. Insert a temp worksheet
  2. Insert the image directly into the worksheet
  3. Insert a Chart
  4. Copy the image to the chart and export it as .Jpg
  5. Load the image using LoadPicture
  6. Delete objects and the temp file that we created.

Code

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

EDIT

For testing purpose I used these setting

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

Screenshot

![enter image description here

Upvotes: 5

Related Questions