VBA – WIA – Convert the Image Format

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.

38 responses on “VBA – WIA – Convert the Image Format

  1. Fab1

    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

    1. Jon Leopold

      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.

    2. James Martin

      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

  2. Daniel PINO

    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”

  3. Daniel PINO

    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

    1. Daniel Pineault Post author

      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"
      1. Leo

        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,

  4. Jim P

    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!

  5. Stephen

    This is excellent, and just what I’ve been searching for. Thank you so much for sharing.

  6. Maria Henriques

    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

  7. Roy Costa

    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!

  8. kelly mort

    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

  9. Manuel

    Set oWIA = CreateObject(“WIA.ImageFile”) is returning nothing every time? Reference to WIA v2 is added.

    1. Daniel Pineault Post author

      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?

  10. Frank

    When I convert a PNG to JPG i get a black background instead of the original white background. Do you know how to fix?

  11. Benjamin

    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?

  12. Robert Moritz

    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

  13. Ton Slijpen

    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

    1. Daniel Pineault Post author

      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.

  14. Daniel Visconti Penteado

    Thanks!
    The list “With WIA we can very easily work with and convert between” is missing PNG and GIF is duplicated.

  15. Brian Thyme

    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? 🙂

    1. Daniel Pineault Post author

      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.

  16. Patrick DE RIDDER

    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

  17. Andrade

    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.

    1. Daniel Pineault Post author

      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:

      magick C:\Temp\transparent.png -background "#ED7FFF" -flatten C:\Temp\Non-Transparent.jpg

      Or

      magick C:\Temp\transparent.png -compose over -background "#000000" -flatten C:\Temp\Non-Transparent.jpg

      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.