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.
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:
- *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.
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
Zatím žádné komentáře.