Reputation: 5543
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
A jpg (which MSDN lists as an acceptable format in the remarks section of their LoadPicture()
article)
Not corrupt (at least, I can view it with windows photoviewer/ Chrome/ Paint fine)
Relatively small (as in, it is ~1MPx and a 200MPx jpeg I tested loaded without any errors)
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
temp.jpg
appears in my temp folder
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
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
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:
.Jpg
LoadPicture
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
Upvotes: 5