Volver al inicio

WIC en Direct2D: decodificación de imágenes

El material describe las interfaces clave de WIC para decodificar imágenes en Windows. Se proporcionan ejemplos de creación de un decodificador desde archivo, flujo y memoria con IWICBitmapDecoder e IWICBitmapFrameDecode. El código completo demuestra la integración en una aplicación.

Decodificación de imágenes vía WIC: guía completa
Advertisement 728x90

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.

Google AdInline article slot

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:

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

Google AdInline article slot

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

Advertisement 728x90

Leer después