Retour à l'accueil

WIC dans Direct2D : décodage d'images

L'article décrit les interfaces clés de WIC pour le décodage d'images dans Windows. Des exemples de création d'un décodeur à partir d'un fichier, d'un flux et de la mémoire avec les méthodes IWICBitmapDecoder et IWICBitmapFrameDecode sont fournis. Le code complet démontre l'intégration dans une application.

Décodage d'images via WIC : guide complet
Advertisement 728x90

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.

Google AdInline article slot

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 :

Google AdInline article slot
  • *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.

Google AdInline article slot

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

Advertisement 728x90

Lire ensuite