I was continuing to explore the power of Windows Image Acquisition (WIA) and put together the following function to convert an image from one format to another.
With WIA we can very easily work with and convert between:
- bmp
- gif
- jpg
- png
- tiff
file formats and the beauty is this is all built-in and available to us natively!
The Code
Public Enum wiaFormat
BMP = 0
GIF = 1
JPEG = 2
PNG = 3
TIFF = 4
End Enum
'---------------------------------------------------------------------------------------
' Procedure : WIA_ConvertImage
' Author : Daniel Pineault, CARDA Consultants Inc.
' Website : http://www.cardaconsultants.com
' Purpose : Convert an image's format using WIA
' Copyright : The following is release as Attribution-ShareAlike 4.0 International
' (CC BY-SA 4.0) - https://creativecommons.org/licenses/by-sa/4.0/
' Req'd Refs: Uses Late Binding, so none required
'
' Windows Image Acquisition (WIA)
' https://msdn.microsoft.com/en-us/library/windows/desktop/ms630368(v=vs.85).aspx
'
' Input Variables:
' ~~~~~~~~~~~~~~~~
' sInitialImage : Fully qualified path and filename of the original image to resize
' sOutputImage : Fully qualified path and filename of where to save the new image
' lFormat : Format to convert the image into
' lQuality : Quality level to be used for the conversion process (1-100)
'
' Usage:
' ~~~~~~
' Call WIA_ConvertImage("C:\Users\Public\Pictures\Sample Pictures\Chrysanthemum.png", _
' "C:\Users\MyUser\Desktop\Chrysanthemum_2.jpg", _
' JPEG, 50)
'
' Revision History:
' Rev Date(yyyy/mm/dd) Description
' **************************************************************************************
' 1 2017-01-18 Initial Release
' 2 2018-09-20 Updated Copyright
'---------------------------------------------------------------------------------------
Public Function WIA_ConvertImage(sInitialImage As String, _
sOutputImage As String, _
lFormat As wiaFormat, _
Optional lQuality As Long = 85) As Boolean
On Error GoTo Error_Handler
Dim oWIA As Object 'WIA.ImageFile
Dim oIP As Object 'ImageProcess
Dim sFormatID As String
Dim sExt As String
'Convert our Enum over to the proper value used by WIA
Select Case lFormat
Case 0
sFormatID = "{B96B3CAB-0728-11D3-9D7B-0000F81EF32E}"
sExt = "BMP"
Case 1
sFormatID = "{B96B3CB0-0728-11D3-9D7B-0000F81EF32E}"
sExt = "GIF"
Case 2
sFormatID = "{B96B3CAE-0728-11D3-9D7B-0000F81EF32E}"
sExt = "JPEG"
Case 3
sFormatID = "{B96B3CAF-0728-11D3-9D7B-0000F81EF32E}"
sExt = "PNG"
Case 4
sFormatID = "{B96B3CB1-0728-11D3-9D7B-0000F81EF32E}"
sExt = "TIFF"
End Select
If lQuality > 100 Then lQuality = 100
'Should check if the output file already exists and if so,
'prompt the user to overwrite it or not
Set oWIA = CreateObject("WIA.ImageFile")
Set oIP = CreateObject("WIA.ImageProcess")
oIP.Filters.Add oIP.FilterInfos("Convert").FilterID
oIP.Filters(1).Properties("FormatID") = sFormatID
oIP.Filters(1).Properties("Quality") = lQuality
oWIA.LoadFile sInitialImage
Set oWIA = oIP.Apply(oWIA)
'Overide the specified ext with the appropriate one for the choosen format
oWIA.SaveFile Left(sOutputImage, InStrRev(sOutputImage, ".")) & LCase(sExt)
WIA_ConvertImage = True
Error_Handler_Exit:
On Error Resume Next
If Not oIP Is Nothing Then Set oIP = Nothing
If Not oWIA Is Nothing Then Set oWIA = Nothing
Exit Function
Error_Handler:
MsgBox "The following error has occurred" & vbCrLf & vbCrLf & _
"Error Number: " & Err.Number & vbCrLf & _
"Error Source: WIA_ConvertImage" & vbCrLf & _
"Error Description: " & Err.Description & _
Switch(Erl = 0, "", Erl <> 0, vbCrLf & "Line No: " & Erl) _
, vbOKOnly + vbCritical, "An Error has Occurred!"
Resume Error_Handler_Exit
End Function
Usage Example(s)
The function is very straightforward to use. Say we have an image
C:/Images/Flowers.bmp
and we want to convert it to a gif and save it to
C:/Users/Dev/Desktop/MyFlowers.gif
then we would do something along the lines of:
? WIA_ConvertImage("C:/Images/Flowers.bmp", "C:/Users/Dev/Desktop/MyFlowers.gif", GIF)
and it will return True => successful or False => unsuccessful.
Nice post`s on WIA Daniel. You had a play with WIA OCR yet? Could I suggest you do another one in your “Purchase” series that would cover:- Scan/Import document, OCR document, Autocomplete forms/fields from OCR data, Cheers
Excellent sharing.
How can I define to resize 640 x 360
Thanks
This function is for converting an image from one format to another. To resize an image you want to use the function found at: http://www.devhut.net/2017/01/18/vba-resize-image/
It works great but somehow the converted pic (Jpg->Bmp)is turned 90 degrees? Any clue?
No, no clue why that would happen and I’ve never experienced anything like that myself. All I can suggest is to use the Roation filter to correct the issue, see: VBA – WIA – Rotate an Image.
The problem I’m having is that if the image is taller than it is wide it is rotated 90 degrees. The reason I’m here is that Access reports automatically rotates jpeg/jpg files so I was looking to convert them to png files because those aren’t rotated. Unfortunately, they’re being rotated when they convert to png.
Not used WIA yet, these macros look useful … Been using this amended macro to import images saved from outlook item and to import at cursor point in a docx macro save of email. Had to add an error handler to delete out images below a certain height to stop adding email banners and signatures. Extracted the text from a text view of bas file on my phone, so comments are cropped.
Sub Macrol 28_06_2022()
FoldertoDocxMacrol() Inserts image Files into Macro ES docx (not pdf) that are saved by Outlook Macro A
(so Run Macro I after Macros ES and A in Outlook)
‘SOURCE: https://excel-macro tutorialhorizon.com/vba-excel-addinsert-multiple-images pictures-from-a-folder
‘https://excel-macro.tutorialhorizon.com/vba-excel-addinsert-multiple-imagespictures-from-a-folder-in-word-document/
Word Application ScreenUpdating = False
‘If Macro is pressed in error with no file in Open Word App (added by jam61mar@gmail.com)
If Word Application Documents.Count = 0 Then
Exit Sub End If
FninsertMultipleimages (“C:\traajsmattach\”)
‘Error Handler needed to not select * heic files have had to abandon attachments today as cant delete heic (work IT Dept have resolved codecs)
Word Application.ScreenUpdating = True
End Sub
Private Function FninsertMultiplelmages(strFolderPath)
Dim objWord Dim objDoc
Dim objSelection
Dim objShapes
Dim objShape” Dim oShape As inlineshape”
Dim Shape As Shape Dim objFSO
Dim objFolder
Set objWord = GetObject(, “Word. Application”) 01/11/2021 Changed Create for Get & inserted a comma in
‘CREDIT: microsoft public word vba general narkive.com/wqS1d0hC/stop-multiple-instances-of-word-openin Set objFSO = CreateObject(“Scripting.FileSystemObject”)
Set objFolder= objFSO.GetFolder(strFolderPath)
Set objDoc = Word.ActiveDocument
Set objSelection = Word.ActiveDocument
For Each img in objFolder.files
imgpath=img.Path
“saw 09112021 macro delete the original signature & email banners: “stackoverflow.com/questions/20553813/adjust-image-properties-with-addpicture-method-word-w Set oShape = objSelection Inlineshapes AddPicture(imgpath)
If oShape Height < 180 Then oShape Delete
End If
You are just too good. Bravo !!!
Beautiful.
Have you considered adding an Imagemagick function that loops to allow fine tuning of image?
Excellent ! Amazing. Works very well. The best function of its kind. THANK YOU
Another way to overwrite a file
Before the
Call WIA_ConvertImage(“C:\Users\Public\Pictures\Sample Pictures\Chrysanthemum.jpg”, _
‘ “C:\Users\MyUser\Desktop\Chrysanthemum_2.jpg”, _
‘ JPEG)
I used this line
If Len(DIR(“C:\Users\MyUser\Desktop\Chrysanthemum_2.jpg”)) 0 Then Kill “C:\Users\MyUser\Desktop\Chrysanthemum_2.jpg”
Tip: When I save the file the function saved it with the JPEG extension “E” should change JPEG by JPG in the whole function.
THANKS
It’s perfect. Can anyone tell me how to add LZW compression for TIFF? Thanks.
I uses LZW by default. When I run the function and review the file properties is specifies LZW compression.
If you want to be 100% certain, you could add the following into the function, but this only applies to TIFF files so be sure to code it conditionally.
oIP.Filters(1).Properties("Compression") = "LZW"Thank you for the quick response.
Please excuse me if I insist too much, I would have one more question and that is:
– do some filesize limitations apply, because I can’t converted any file that is bigger than 128MB, no matter the system I try on (win7… win10, 1 GB RAM… up to 4 GB RAM and so on)?
I undestand the ‘Imagefile’ is created in memory, I checked and there was enough free memory but no luck…
Many thanks,
Sadly, when it comes to the inner workings of WIA I can’t help. Only Microsoft Engineers could help with such an issue and tell you if there are limits, if there is a way to configure things … Your best bet is to post a very detailed question in say https://social.msdn.microsoft.com/Forums/office/en-US/home?forum=accessdev&filter=alltypes&sort=lastpostdesc and hope a Microsoft Engineer see it and decides to help (fingers crossed).
This is awesome! Wondering however with TIFF files, they often contain multiple images, which is one of the main advantages/uses for TIFF files. Is there a way to iterate through each image/layer in a TIFF file and have it convert to individual images? Thanks so much in advance!
This is excellent, and just what I’ve been searching for. Thank you so much for sharing.
Hello
The macro was working in a computer with Office 365. Now I’m working in a computer with Office 2016 and I got the error:
Error number: -2147024809
Error Source: WIA ConvertImage
Error Description: The parameter is incorrect
in the line
oWIA.LoadFile sInitialImage
For a test, I’ve created a very simple macro with the necessary lines to open an image file and the results are the same.
Microsoft WIA reference is installed.
Appreciate any help
How are you calling the function exactly? Can you post your code.
This is VERY interesting. Is there anyway to leverage this to convert to a pdf? How does it handle multi-page Tiffs for example? Thanks!
No, WIA does not support PDFs, so you’d need to turn to something else for that.
I am on office 2016. How do I call the macro?
I am new to this. And I want to verify this:
1. In a folder containing images, I check if there are images other than jpeg files.
2. Show alert of status- whether there are or there are not.
3. If there are non JPEG images, then convert all of them to same location, deleting the old files
4. The location of the image folder is same as that of the workbook
Set oWIA = CreateObject(“WIA.ImageFile”) is returning nothing every time? Reference to WIA v2 is added.
My code uses late binding, so no reference libraries need to be setup. As for the error itself, I’m not sure what to say. What OS are you running? What version of Office, bitness, build no? Does your VBA code compile without errors?
When I convert a PNG to JPG i get a black background instead of the original white background. Do you know how to fix?
Thank you very much.
I use it to transform a PNG into a GIF in order to insert it into a UserForm. However, I have a problem. The GIF file I get doesn’t handle the transparency (shadow around a text) in the image well. But if I convert the same PNG using a soft it’s perfect.
It comes from me using the wrong procedure?
I”m late to the game, can you convert from PNG to Bmp? everytime I try with this code it creates a file with a black background
Hi Daniel,
Ton from the Netherlands her.
To start with: thank you very much for your excellent work!
I have a problem that you could probably help me with.
I download an image file from Google Drive with the function URLDownloadToFile Lib “urlmon” Alias “URLDownloadToFileA” but than the file cannot be read (File Type currently not supported).
This is the link I use to download the file:
https://drive.google.com/uc?id=1Nzp-ed6uOt1C8GQcl9olxg7FHI1UnMon
If you could have a look at it that would be great!
Thanks
Ton
The link requires authentication.
That said, I’ve never tried downloading a Google Drive doc. I will try to play around with this next week, but I highly suspect it is all about authentication.
Thanks!
The list “With WIA we can very easily work with and convert between” is missing PNG and GIF is duplicated.
Thank you for pointing out the typo! It is fixed now.
Hi I am testing this code, and it seems to work. But whenever I try to use the same code twice, it should prompt me if i want to overwrite file, but it doesn’t do anything, errors either. And I would like to always just overwrite the file. Help? 🙂
There’s no prompting in my code, this is something you would need to check and prompt for yourself.
If you run it again, does it not automatically overwrite the file? You could also simply see if the file exists already and use a Kill statement if it does.
Hy Daniel ,
I’m Patrick from Belgium 😉
Thk’s for your great job .I wanted to test the function i’ve an error
? WIA_ConvertImage(“C:\Users\a35273\Pictures\XBird.ico”, “C:\Workspace\test\images\XBird.bmp”, BMP, 100)
False
and i’ve got the error popup,i tested tif to bmp,tif to jpg , ico, to jpeg always the same .
if you’ve got the solution it will be welcome
Regards
I do not believe WIA supports ico files. If you look at the documentation at https://learn.microsoft.com/en-us/previous-versions/windows/desktop/wiaaut/-wiaaut-consts-formatid it only lists: bmp, png, gif, jpeg and tiff. You’d need to use another approach to convert ico files.
Hello Daniel,
Incredible work you shared here, thank you so much for your contribution.
I just found one problem when converting PNG with transparency to JPG:
the transparent pixels become black in the JPG, which make the image look strange.
Do you know how to make the transparent pixels become white?
Thank you in advance, I wish all the best to you.
You would probably need to turn towards using GDI+ to change, or add a background color. If you go that route, you might as well perform the conversion using GDI+ as well.
Another option would be to use ImageMagick and do a call like:
Or
The beauty here is all it takes is a single line and you can add any background color you want and it can also convert your image to any other format at the same time.