Windows Imaging Component dans Direct2D : Décodage et traitement des images
Windows Imaging Component (WIC) fournit un ensemble d'interfaces COM pour décoder des images compressées à partir de fichiers, de flux ou de mémoire. Les objets clés incluent IWICBitmapDecoder comme conteneur pour les trames et les métadonnées, IWICBitmapFrameDecode pour accéder aux pixels des trames individuelles, et IWICBitmapSourceTransform pour des transformations en temps réel.
D'autres interfaces comme IWICBitmap pour les données raster modifiables en mémoire, IWICFormatConverter pour les changements de format, et IWICBitmapScaler, IWICBitmapClipper, et IWICBitmapFlipRotator pour les modifications sont également utilisées. Toutes les opérations commencent par la création d'une usine : IWICImagingFactory ou IWICImagingFactory2.
#include <wincodec.h>
#include <wrl/client.h>
using Microsoft::WRL::ComPtr;
ComPtr<IWICImagingFactory> pFactory;
HRESULT hr = CoCreateInstance(
CLSID_WICImagingFactory,
nullptr,
CLSCTX_INPROC_SERVER,
IID_IWICImagingFactory,
reinterpret_cast<void**>(&pFactory)
);
L'usine utilise le contexte CLSCTX_INPROC_SERVER pour se charger dans le processus courant.
Décodage à partir de fichiers, flux et mémoire
Pour charger depuis un fichier, utilisez CreateDecoderFromFilename avec le chemin (wchar_t*), le fournisseur préféré (nullptr), le mode GENERIC_READ, et le cache WICDecodeMetadataCacheOnLoad.
ComPtr<IWICBitmapDecoder> pDecoder;
hr = pFactory->CreateDecoderFromFilename(
L"C:\\images\\photo.jpg",
nullptr,
GENERIC_READ,
WICDecodeMetadataCacheOnLoad,
&pDecoder
);
Depuis un IStream (via SHCreateStreamOnFile) — utilisez CreateDecoderFromStream. Pour la mémoire : CreateStream avec InitializeFromMemory, puis CreateDecoderFromStream.
ComPtr<IStream> pStream;
SHCreateStreamOnFile(L"C:\\images\\photo.jpg", STGM_READ, &pStream);
ComPtr<IWICBitmapDecoder> pDecoder;
pFactory->CreateDecoderFromStream(pStream.Get(), nullptr, WICDecodeMetadataCacheOnLoad, &pDecoder);
ComPtr<IWICStream> pStream;
pFactory->CreateStream(&pStream);
pStream->InitializeFromMemory(pBuffer, cbSize);
ComPtr<IWICBitmapDecoder> pDecoder;
pFactory->CreateDecoderFromStream(pStream.Get(), nullptr, WICDecodeMetadataCacheOnLoad, &pDecoder);
Méthodes de IWICBitmapDecoder
Cette interface donne accès à la structure de l'image :
- *QueryCapability(IStream, DWORD)* : Vérifie les capacités du décodeur (bitmask : CanDecodeSomeImages, CanDecodeAllImages, etc.).
- *GetContainerFormat(GUID)** : GUID du format conteneur (ex. : GUID_ContainerFormatJpeg).
- *GetFrameCount(UINT)** : Nombre de trames.
- GetFrame(UINT, IWICBitmapFrameDecode) : Trame par index.
- GetPreview/IGetThumbnail(IWICBitmapSource) : Aperçu ou vignette.
- GetMetadataQueryReader(IWICMetadataQueryReader) : Métadonnées globales.
La liste complète des méthodes offre un contrôle sur le cache, les palettes et les contextes de couleur.
Méthodes de IWICBitmapFrameDecode
Hérite de IWICBitmapSource (GetSize, GetPixelFormat, GetResolution, CopyPixels, CopyPalette) plus :
- GetThumbnail(IWICBitmapSource**) — Vignette de la trame.
- GetColorContexts(UINT, IWICColorContext*, UINT) — Profils ICC.
- GetMetadataQueryReader(IWICMetadataQueryReader**) — Métadonnées de la trame (EXIF, XMP).
CopyPixels extrait les données dans un tampon spécifié, en tenant compte de la foulée et de la région.
Exemple complet de décodage avec affichage des infos
#include <windows.h>
#include <wincodec.h>
#include <wrl/client.h>
#include <iostream>
#include <vector>
#include <propvarutil.h>
using Microsoft::WRL::ComPtr;
void PrintGUID(const GUID& guid) {
wchar_t str[39];
StringFromGUID2(guid, str, 39);
wprintf(L"%s", str);
}
int wmain(int argc, wchar_t* argv[]) {
if (argc < 2) {
wprintf(L"Usage: WICFullDemo.exe <imagefile>\n");
return 1;
}
const wchar_t* filename = argv[1];
HRESULT hr = CoInitializeEx(nullptr, COINIT_MULTITHREADED);
if (FAILED(hr)) return 1;
ComPtr<IWICImagingFactory> pFactory;
hr = CoCreateInstance(CLSID_WICImagingFactory, nullptr, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&pFactory));
if (FAILED(hr)) {
CoUninitialize();
return 1;
}
ComPtr<IWICBitmapDecoder> pDecoder;
hr = pFactory->CreateDecoderFromFilename(filename, nullptr, GENERIC_READ, WICDecodeMetadataCacheOnLoad, &pDecoder);
if (FAILED(hr)) {
CoUninitialize();
return 1;
}
wprintf(L"=== Méthodes IWICBitmapDecoder ===\n");
ComPtr<IStream> pStream;
SHCreateStreamOnFile(filename, STGM_READ, &pStream);
if (SUCCEEDED(hr)) {
DWORD caps = 0;
hr = pDecoder->QueryCapability(pStream.Get(), &caps);
if (SUCCEEDED(hr)) {
wprintf(L"QueryCapability: capacités = 0x%08X\n", caps);
}
}
// Traitement ultérieur des trames, métadonnées et pixels
CoUninitialize();
return 0;
}
Cet exemple montre l'initialisation COM, la création de l'usine, la configuration du décodeur et QueryCapability. Pour du code de production, ajoutez GetFrame, CopyPixels et les transformations.
Points clés à retenir
- WIC décode les images sans tout charger en mémoire, en supportant les flux et le cache des métadonnées.
- IWICBitmapDecoder gère le conteneur, tandis que IWICBitmapFrameDecode s'occupe des trames individuelles et des pixels.
- CreateDecoderFromFilename/Stream/Memory couvre tous les scénarios d'entrée.
- GetFrameCount/GetFrame/GetMetadataQueryReader donnent accès à la structure et aux données EXIF.
- Vérifiez toujours HRESULT et utilisez ComPtr pour le RAII.
— Editorial Team
Aucun commentaire pour le moment.