Hello everyone,
I'm pleased to share a UDF I developed to work with IWICImagingFactory from the Windows Imaging Component (WIC), focused exclusively on reading and writing image metadata.
π Why this UDF?
IWICImagingFactory is a powerful API but can also be particularly confusing when working with metadata. Its layers of abstraction, data formats, and interface complexity can easily distract you from your goals without a clear structure.
π§© Key Features:
π Read and write metadata using WIC interfaces (IWICMetadataQueryReader, IWICMetadataQueryWriter)
πΎ Supports common formats (JPEG, PNG, TIFF, etc.)
π§ Built using an object-oriented model via AutoItObject to encapsulate complexity and avoid side effects
β οΈ Full support for PROPVARIANT and VARIANT types, essential for COM interaction
π Handles the WIC metadata query language (e.g., /app1/ifd/exif:{ushort=36867} for Date Taken)
π Works with WIC-compliant hierarchical metadata queries
π§ Prerequisites / Recommended Knowledge
Solid understanding of COM programming in AutoIt
Familiarity with PROPVARIANT/VARIANT (types, conversion, init/cleanup)
Knowledge of WIC metadata schema and hierarchy
Comfortable with object-oriented programming in AutoIt (using AutoItObject)
π§ͺ Why use an object-oriented approach?
IWICImagingFactory is as flexible as it is tricky. Exploring it directly can lead to unexpected behaviors or technical detours.
The object-oriented approach helps contain this complexity, structure features properly, and avoid common pitfalls when dealing with raw COM interfaces.
π Whatβs Included in the UDF
A main object WICImageMeta (or similar) that encapsulates the image, reader/writer, and associated interfaces
Straightforward methods like .ReadMeta($sPath), .WriteMeta($sPath, $vValue, $sType), .Save($sDest), etc.
Automatic resource management (Release, Cleanup)
Examples for reading/writing EXIF, XMP, and other metadata
π· Quick Usage Example
#include <MsgBoxConstants.au3>
#include <WinAPI.au3>
#include <Array.au3>
#include "IWICImagingMetadata.au3" ; This is your custom UDF for WIC metadata
; Path to a test image (replace with your own file path)
Local $sFilename = @DesktopDir & "\screenshot.png"
; === 1. Create the WIC Imaging Factory ===
; This is the entry point for all WIC operations
Local $oFactory = _WIC_ImagingFactory()
If Not IsObj($oFactory) Then
MsgBox(0, "Error", "Failed to create WIC Imaging Factory")
Exit
EndIf
; === 2. Create a decoder from the image file ===
; This will analyze the image format and prepare for frame extraction
Local $oDecoder = $oFactory.createDecoderFromFileName($sFilename)
If Not IsObj($oDecoder) Then
MsgBox(0, "Error", "Failed to create image decoder: @error=" & @error)
$oFactory = 0
Exit
EndIf
; === 3. Get the first frame of the image ===
; Most still images have a single frame; this retrieves it from the decoder
Local $oFrame = $oFactory.createBitmapFrameDecode($oDecoder)
If Not IsObj($oFrame) Then
MsgBox($MB_ICONERROR, "Error", "Failed to retrieve image frame: @error=" & @error)
$oDecoder = 0
$oFactory = 0
Exit
EndIf
; === 4. Get a metadata query reader from the frame ===
; This reader allows you to query metadata values using WIC metadata paths
Local $oQueryReader = $oFactory.getMetadataQueryReader($oFrame)
If Not IsObj($oQueryReader) Then
MsgBox(0, "Error", "Failed to get metadata query reader: @error=" & @error)
$oFrame = 0
$oDecoder = 0
$oFactory = 0
Exit
EndIf
; === 5. Enumerate available metadata names ===
; This step is crucial to explore what metadata is actually present.
; It returns an array of metadata query paths that can be used.
Local $aNames = $oFactory.enumerateMetaDataNames($oQueryReader)
If @error Then
ConsoleWrite("Error: Failed to enumerate metadata names: @error=" & @error & @CRLF)
Else
ConsoleWrite("Available metadata names: " & _ArrayToString($aNames, "|") & @CRLF)
EndIf
; === 6. Read a specific metadata value ===
; In this case, we're trying to read a textual field: "Creation Time" in a PNG tEXt chunk
Local $sQuery = "/tEXt/{str=Creation Time}"
Local $vData = $oFactory.queryMetadataByName($oQueryReader, $sQuery)
If Not @error Then
ConsoleWrite("Metadata read: " & $sQuery & " = " & $vData & @CRLF)
Else
ConsoleWrite("Error: Failed to read " & $sQuery & " : @error=" & @error & @CRLF)
EndIf
; === NOTE ===
; If your query selects a metadata **block**, then `vData` may be another IWICMetadataQueryReader object.
; In that case, you must call `queryMetadataByName` again, passing this sub-reader to reach nested values.
π¬ Conclusion
If you've worked with image metadata using WIC before, you know it's a technical challenge.
This UDF aims to simplify the process while preserving full control for those who need fine-grained access.
Feel free to try it out, give feedback, or suggest improvements.
Enjoy digging into the hidden data of your images! πΈ
IWICImagingMetadata.au3