Windows Imaging Component in Direct2D: Bilder dekodieren und verarbeiten
Die Windows Imaging Component (WIC) stellt eine Reihe von COM-Schnittstellen zur Verfügung, um komprimierte Bilder aus Dateien, Streams oder Speicher zu dekodieren. Wichtige Objekte sind IWICBitmapDecoder als Container für Frames und Metadaten, IWICBitmapFrameDecode für den Zugriff auf Pixel in einzelnen Frames sowie IWICBitmapSourceTransform für Transformationen in Echtzeit.
Zusätzliche Schnittstellen wie IWICBitmap für veränderbare Rasterdaten im Speicher, IWICFormatConverter für Formatänderungen sowie IWICBitmapScaler, IWICBitmapClipper und IWICBitmapFlipRotator für Modifikationen werden ebenfalls genutzt. Alle Operationen beginnen mit der Erstellung einer Factory: IWICImagingFactory oder 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)
);
Die Factory nutzt den Kontext CLSCTX_INPROC_SERVER, um in den aktuellen Prozess geladen zu werden.
Dekodieren aus Dateien, Streams und Speicher
Zum Laden aus einer Datei verwenden Sie CreateDecoderFromFilename mit dem Pfad (wchar_t*), bevorzugtem Anbieter (nullptr), GENERIC_READ-Modus und WICDecodeMetadataCacheOnLoad-Zwischenspeicherung.
ComPtr<IWICBitmapDecoder> pDecoder;
hr = pFactory->CreateDecoderFromFilename(
L"C:\\images\\photo.jpg",
nullptr,
GENERIC_READ,
WICDecodeMetadataCacheOnLoad,
&pDecoder
);
Aus einem IStream (via SHCreateStreamOnFile) — nutzen Sie CreateDecoderFromStream. Für Speicher: CreateStream mit InitializeFromMemory, dann 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);
IWICBitmapDecoder-Methoden
Diese Schnittstelle ermöglicht den Zugriff auf die Bildstruktur:
- *QueryCapability(IStream, DWORD)*: Prüft Decoder-Fähigkeiten (Bitmaske: CanDecodeSomeImages, CanDecodeAllImages usw.).
- *GetContainerFormat(GUID)**: GUID des Container-Formats (z. B. GUID_ContainerFormatJpeg).
- *GetFrameCount(UINT)**: Anzahl der Frames.
- GetFrame(UINT, IWICBitmapFrameDecode) : Frame nach Index.
- GetPreview/IGetThumbnail(IWICBitmapSource) : Vorschau oder Vorschaubild.
- GetMetadataQueryReader(IWICMetadataQueryReader) : Globale Metadaten.
Die vollständige Methodenliste bietet Kontrolle über Zwischenspeicherung, Paletten und Farbkontexte.
IWICBitmapFrameDecode-Methoden
Erbt IWICBitmapSource (GetSize, GetPixelFormat, GetResolution, CopyPixels, CopyPalette) zuzüglich:
- GetThumbnail(IWICBitmapSource**) — Frame-Vorschaubild.
- GetColorContexts(UINT, IWICColorContext*, UINT) — ICC-Profile.
- GetMetadataQueryReader(IWICMetadataQueryReader**) — Frame-Metadaten (EXIF, XMP).
CopyPixels extrahiert Daten in einen angegebenen Puffer unter Berücksichtigung von Stride und Region.
Vollständiges Dekodierungsbeispiel mit Infomeldungen
#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);
}
}
// Weitere Verarbeitung von Frames, Metadaten und Pixeln
CoUninitialize();
return 0;
}
Dieses Beispiel zeigt COM-Initialisierung, Factory-Erstellung, Decoder-Setup und QueryCapability. Für Produktionscode ergänzen Sie GetFrame, CopyPixels und Transformationen.
Wichtige Erkenntnisse
- WIC dekodiert Bilder, ohne alles in den Speicher zu laden, und unterstützt Streams sowie Metadaten-Zwischenspeicherung.
- IWICBitmapDecoder verwaltet den Container, während IWICBitmapFrameDecode einzelne Frames und Pixel handhabt.
- CreateDecoderFromFilename/Stream/Memory deckt alle Eingabeszenarien ab.
- GetFrameCount/GetFrame/GetMetadataQueryReader ermöglichen Zugriff auf Struktur und EXIF-Daten.
- Prüfen Sie immer HRESULT und nutzen Sie ComPtr für RAII.
— Editorial Team
Noch keine Kommentare.