Jump to content

Recommended Posts

Posted

Β 

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.

image.png.812dd127a02a91908e9cf1fcc015a8e3.png

Β 

πŸ’¬ 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

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...