Componente de Imágenes de Windows en Direct2D: Decodificación y Procesamiento de Imágenes
El Componente de Imágenes de Windows (WIC) ofrece un conjunto de interfaces COM para decodificar imágenes comprimidas desde archivos, flujos o memoria. Los objetos clave incluyen IWICBitmapDecoder como contenedor de fotogramas y metadatos, IWICBitmapFrameDecode para acceder a los píxeles de fotogramas individuales, y IWICBitmapSourceTransform para transformaciones en tiempo real.
Interfaces adicionales como IWICBitmap para datos raster mutables en memoria, IWICFormatConverter para cambios de formato, y IWICBitmapScaler, IWICBitmapClipper e IWICBitmapFlipRotator para modificaciones también se utilizan. Todas las operaciones comienzan creando una fábrica: IWICImagingFactory o 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)
);
La fábrica utiliza el contexto CLSCTX_INPROC_SERVER para cargarse en el proceso actual.
Decodificación desde Archivos, Flujos y Memoria
Para cargar desde un archivo, usa CreateDecoderFromFilename con la ruta (wchar_t*), proveedor preferido (nullptr), modo GENERIC_READ y caché WICDecodeMetadataCacheOnLoad.
ComPtr<IWICBitmapDecoder> pDecoder;
hr = pFactory->CreateDecoderFromFilename(
L"C:\\images\\photo.jpg",
nullptr,
GENERIC_READ,
WICDecodeMetadataCacheOnLoad,
&pDecoder
);
Desde un IStream (vía SHCreateStreamOnFile) — usa CreateDecoderFromStream. Para memoria: CreateStream con InitializeFromMemory, luego 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étodos de IWICBitmapDecoder
Esta interfaz proporciona acceso a la estructura de la imagen:
- *QueryCapability(IStream, DWORD): Verifica las capacidades del decodificador (máscara de bits: CanDecodeSomeImages, CanDecodeAllImages*, etc.).
- *GetContainerFormat(GUID): GUID del formato de contenedor (p. ej., GUID_ContainerFormatJpeg**).
- *GetFrameCount(UINT)**: Número de fotogramas.
- GetFrame(UINT, IWICBitmapFrameDecode) : Fotograma por índice.
- GetPreview/IGetThumbnail(IWICBitmapSource) : Vista previa o miniatura.
- GetMetadataQueryReader(IWICMetadataQueryReader) : Metadatos globales.
La lista completa de métodos ofrece control sobre caché, paletas y contextos de color.
Métodos de IWICBitmapFrameDecode
Hereda IWICBitmapSource (GetSize, GetPixelFormat, GetResolution, CopyPixels, CopyPalette) más:
- GetThumbnail(IWICBitmapSource) — Miniatura del fotograma.
- GetColorContexts(UINT, IWICColorContext, UINT*) — Perfiles ICC.
- GetMetadataQueryReader(IWICMetadataQueryReader) — Metadatos del fotograma (EXIF, XMP).
CopyPixels extrae datos a un búfer especificado, considerando el stride y la región.
Ejemplo Completo de Decodificación con Salida de Información
#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);
}
}
// Further processing of frames, metadata, and pixels
CoUninitialize();
return 0;
}
Este ejemplo muestra la inicialización de COM, creación de la fábrica, configuración del decodificador y QueryCapability. Para código de producción, agrega GetFrame, CopyPixels y transformaciones.
Puntos Clave
- WIC decodifica imágenes sin cargar todo en memoria, compatible con flujos y caché de metadatos.
- IWICBitmapDecoder maneja el contenedor, mientras que IWICBitmapFrameDecode gestiona fotogramas individuales y píxeles.
- CreateDecoderFromFilename/Stream/Memory cubre todos los escenarios de entrada.
- GetFrameCount/GetFrame/GetMetadataQueryReader proporcionan acceso a la estructura y datos EXIF.
- Siempre verifica HRESULT y usa ComPtr para RAII.
— Editorial Team
Aún no hay comentarios.