Zpět na domů

WIC v Direct2D: dekódování obrázků

Materiál popisuje klíčová rozhraní WIC pro dekódování obrázků ve Windows. Uvádějí se příklady vytvoření dekodéru ze souboru, proudu a paměti s metodami IWICBitmapDecoder a IWICBitmapFrameDecode. Kompletní kód demonstruje integraci do aplikace.

Dekódování obrázků přes WIC: kompletní průvodce
Advertisement 728x90

Windows Imaging Component v Direct2D: dekódování a zpracování obrázků

Windows Imaging Component (WIC) poskytuje sadu COM rozhraní pro dekódování komprimovaných obrázků ze souborů, proudů nebo paměti. Klíčové objekty: IWICBitmapDecoder jako kontejner snímků a metadat, IWICBitmapFrameDecode pro přístup k pixelům jednotlivých snímků, IWICBitmapSourceTransform pro transformace za běhu.

Dále se používají IWICBitmap pro modifikovatelná bitmapová data v paměti, IWICFormatConverter pro změnu formátu, a také IWICBitmapScaler, IWICBitmapClipper a IWICBitmapFlipRotator pro úpravy. Všechny operace začínají vytvořením továrny IWICImagingFactory nebo 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)
);

Továrna spravuje kontext CLSCTX_INPROC_SERVER pro načítání v aktuálním procesu.

Google AdInline article slot

Dekódování ze souboru, proudu a paměti

Pro načítání ze souboru se používá CreateDecoderFromFilename s parametry cesty (wchar_t*), preferovaného výrobce (nullptr), režimem GENERIC_READ a ukládáním metadat WICDecodeMetadataCacheOnLoad.

ComPtr<IWICBitmapDecoder> pDecoder;
 hr = pFactory->CreateDecoderFromFilename(
     L"C:\\images\\photo.jpg",
     nullptr,
     GENERIC_READ,
     WICDecodeMetadataCacheOnLoad,
     &pDecoder
 );

Z proudu IStream (SHCreateStreamOnFile) — CreateDecoderFromStream. Pro paměť: CreateStream s InitializeFromMemory, poté 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);

Metody IWICBitmapDecoder

Rozhraní poskytuje přístup ke struktuře obrázku:

Google AdInline article slot
  • *QueryCapability(IStream, DWORD)*: kontrola možností dekodéru (bitová maska: CanDecodeSomeImages, CanDecodeAllImages a další).
  • *GetContainerFormat(GUID)**: GUID formátu kontejneru (GUID_ContainerFormatJpeg).
  • *GetFrameCount(UINT)**: počet snímků.
  • GetFrame(UINT, IWICBitmapFrameDecode) : snímek podle indexu.
  • GetPreview/IGetThumbnail(IWICBitmapSource) : náhled nebo miniatura.
  • GetMetadataQueryReader(IWICMetadataQueryReader) : globální metadata.

Úplný seznam metod zajišťuje kontrolu nad ukládáním, paletou a barevnými kontexty.

Metody IWICBitmapFrameDecode

Dědí z IWICBitmapSource (GetSize, GetPixelFormat, GetResolution, CopyPixels, CopyPalette) a navíc:

  • GetThumbnail(IWICBitmapSource**) — miniatura snímku.
  • GetColorContexts(UINT, IWICColorContext*, UINT) — ICC profily.
  • GetMetadataQueryReader(IWICMetadataQueryReader**) — metadata snímku (EXIF, XMP).

CopyPixels extrahuje data do daného bufferu s ohledem na stride a region.

Google AdInline article slot

Kompletní příklad dekódování s výpisem informací

#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"=== IWICBitmapDecoder methods ===\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: capabilities = 0x%08X\n", caps);
        }
    }

    // Další zpracování snímků, metadat a pixelů
    CoUninitialize();
    return 0;
}

Příklad demonstruje inicializaci COM, továrnu, dekodér a QueryCapability. Pro produkci přidejte zpracování GetFrame, CopyPixels a transformací.

Co je důležité

  • WIC dekóduje obrázky bez úplného načtení do paměti, podporuje proudy a ukládání metadat.
  • IWICBitmapDecoder spravuje kontejner, IWICBitmapFrameDecode — jednotlivé snímky s pixely.
  • CreateDecoderFromFilename/Stream/Memory pokrývají všechny vstupní scénáře.
  • Metody GetFrameCount/GetFrame/GetMetadataQueryReader dávají přístup ke struktuře a EXIF.
  • Vždy kontrolujte HRESULT a používejte ComPtr pro RAII.

— Editorial Team

Advertisement 728x90

Číst dál