Nota
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
En este tema se proporciona información general sobre cómo puede usar las API del componente de imágenes de Windows (WIC) para leer y escribir metadatos incrustados en archivos de imagen.
En este tema se incluyen las siguientes secciones.
- Requisitos previos
- Introducción
- Lectura de metadatos mediante un lector de consultas
- Escritura de metadatos mediante un escritor de consultas
- Codificación rápida de metadatos
- Temas relacionados
Prerrequisitos
Para comprender este tema, debe estar familiarizado con el sistema de metadatos WIC, tal como se describe en la Introducción a los metadatos de WIC. También debe estar familiarizado con el lenguaje de consulta que se usa para leer y escribir metadatos, como se describe en Introducción al lenguaje de consulta de metadatos.
Introducción
WIC proporciona a los desarrolladores de aplicaciones componentes componentes del modelo de objetos componentes (COM) para leer y escribir metadatos incrustados en archivos de imagen. Hay dos maneras de leer y escribir metadatos:
- Usar un lector o escritor de consultas y una expresión de consulta para consultar bloques de metadatos para bloques anidados o metadatos específicos dentro de un bloque.
- Usar un controlador de metadatos (un lector de metadatos o un escritor de metadatos) para acceder a los bloques de metadatos anidados o metadatos específicos dentro de los bloques de metadatos.
Lo más sencillo es usar un lector o escritor de consultas y una expresión de consulta para acceder a los metadatos. Un lector de consultas (IWICMetadataQueryReader) se usa para leer metadatos mientras se usa un escritor de consultas (IWICMetadataQueryWriter) para escribir metadatos. Ambos usan una expresión de consulta para leer o escribir los metadatos deseados. En segundo plano, un lector de consultas (y escritor) usa un controlador de metadatos para acceder a los metadatos descritos por la expresión de consulta.
El método más avanzado es acceder directamente a los controladores de metadatos. Un controlador de metadatos se obtiene de los fotogramas individuales utilizando un lector de bloques (IWICMetadataBlockReader) o un escritor de bloques (IWICMetadataBlockWriter). Los dos tipos de controladores de metadatos disponibles son el lector de metadatos (IWICMetadataReader) y el escritor de metadatos (IWICMetadataWriter).
El siguiente diagrama del contenido de un archivo de imagen JPEG se usa en los ejemplos de este tema. La imagen representada por este diagrama se creó mediante Microsoft Paint; los metadatos de clasificación se agregaron mediante la característica Galería de fotos de Windows Vista.
Lectura de metadatos mediante un lector de consultas
La manera más fácil de leer metadatos es usar la interfaz del lector de consultas, IWICMetadataQueryReader. El lector de consultas permite leer bloques de metadatos y elementos dentro de bloques de metadatos mediante una expresión de consulta.
Hay tres maneras de obtener un lector de consultas: a través de un descodificador de mapa de bits (IWICBitmapDecoder), a través de sus marcos individuales (IWICBitmapFrameDecode) o a través de un escritor de consultas (IWICMetadataQueryWriter).
Obtención de un lector de consultas
En el código de ejemplo siguiente se muestra cómo obtener un descodificador de mapa de bits de la factoría de imágenes y recuperar un marco de mapa de bits individual. Este código también realiza el trabajo de instalación necesario para obtener un lector de consultas de un marco descodificado.
IWICImagingFactory *pFactory = NULL;
IWICBitmapDecoder *pDecoder = NULL;
IWICBitmapFrameDecode *pFrameDecode = NULL;
IWICMetadataQueryReader *pQueryReader = NULL;
IWICMetadataQueryReader *pEmbedReader = NULL;
PROPVARIANT value;
// Initialize COM
CoInitialize(NULL);
// Initialize PROPVARIANT
PropVariantInit(&value);
//Create the COM imaging factory
HRESULT hr = CoCreateInstance(
CLSID_WICImagingFactory,
NULL,
CLSCTX_INPROC_SERVER,
IID_IWICImagingFactory,
(LPVOID*)&pFactory);
// Create the decoder
if (SUCCEEDED(hr))
{
hr = pFactory->CreateDecoderFromFilename(
L"test.jpg",
NULL,
GENERIC_READ,
WICDecodeMetadataCacheOnDemand,
&pDecoder);
}
// Get a single frame from the image
if (SUCCEEDED(hr))
{
hr = pDecoder->GetFrame(
0, //JPEG has only one frame.
&pFrameDecode);
}
El descodificador de mapa de bits del archivo test.jpg se obtiene mediante el método CreateDecoderFromFilename de la factoría de imágenes. En este método, el cuarto parámetro se establece en el valor WICDecodeMetadataCacheOnDemand de la enumeración WICDecodeOptions . Esto indica al descodificador que almacene en caché los metadatos cuando se necesiten los metadatos; ya sea mediante la obtención de un lector de consultas o el lector de metadatos subyacente. El uso de esta opción permite conservar la secuencia en los metadatos necesarios para la codificación rápida de metadatos y permite la descodificación sin pérdida de la imagen JPEG. Como alternativa, puede usar el otro valor WICDecodeOptions , WICDecodeMetadataCacheOnLoad, que almacena en caché los metadatos de la imagen incrustada en cuanto se carga la imagen.
Para obtener el lector de consultas del marco, realice una llamada sencilla al método GetMetadataQueryReader del marco. En el código siguiente se muestra esta llamada.
// Get the query reader
if (SUCCEEDED(hr))
{
hr = pFrameDecode->GetMetadataQueryReader(&pQueryReader);
}
Del mismo modo, también se puede obtener un lector de consultas en el nivel de descodificador. Una llamada sencilla al método GetMetadataQueryReader del descodificador obtiene el lector de consultas del descodificador. El lector de consultas de un descodificador, a diferencia del lector de consultas de un marco, lee los metadatos de una imagen que está fuera de los marcos individuales. Sin embargo, este escenario no es común y los formatos de imagen nativos no admiten esta funcionalidad. Los CÓDECS de imagen nativa proporcionados por WIC leen y escriben metadatos en el nivel de marco incluso para formatos de fotograma único, como JPEG.
Lectura de metadatos
Antes de pasar a leer realmente los metadatos, examine el siguiente diagrama de un archivo JPEG que incluye bloques de metadatos incrustados y datos reales que se van a recuperar. En este diagrama se proporcionan llamadas a elementos y bloques de metadatos específicos dentro de la imagen que proporcionan la expresión de consulta de metadatos a cada bloque o elemento.
Para consultar bloques de metadatos incrustados o elementos específicos por nombre, llame al método GetMetadataByName . Este método toma una expresión de consulta y un PROPVARIANT donde se devuelve el elemento de metadatos. El código siguiente consulta un bloque de metadatos anidados y convierte el componente IUnknown proporcionado por el valor PROPVARIANT en un lector de consultas si se encuentra.
if (SUCCEEDED(hr))
{
// Get the nested IFD reader
hr = pQueryReader->GetMetadataByName(L"/app1/ifd", &value);
if (value.vt == VT_UNKNOWN)
{
hr = value.punkVal->QueryInterface(IID_IWICMetadataQueryReader, (void **)&pEmbedReader);
}
PropVariantClear(&value); // Clear value for new query
}
La expresión de consulta "/app1/ifd" está consultando el bloque IFD anidado en el bloque App1. El archivo de imagen JPEG contiene el bloque de metadatos anidados IFD, por lo que el PROPVARIANT se devuelve con un tipo de variable (vt) de VT_UNKNOWN
y un puntero a una interfaz IUnknown (punkVal). A continuación, puede consultar la interfaz IUnknown para un lector de consultas.
En el código siguiente se muestra una nueva consulta basada en el nuevo lector de consultas relativo al bloque IFD anidado.
if (SUCCEEDED(hr))
{
hr = pEmbedReader->GetMetadataByName(L"/{ushort=18249}", &value);
PropVariantClear(&value); // Clear value for new query
}
La expresión de consulta "/{ushort=18249}" busca en el bloque IFD la clasificación MicrosoftPhoto incorporada bajo la etiqueta 18249. El valor PROPVARIANT ahora contendrá un tipo de valor de VT_UI2
y un valor de datos de 50.
Sin embargo, no es necesario obtener un bloque anidado antes de consultar valores de datos específicos. Por ejemplo, en lugar de realizar consultas sobre el IFD anidado y luego sobre la clasificación de MicrosoftPhoto, puede usar el bloque de metadatos raíz y la consulta que se muestra en el código siguiente para obtener la misma información.
if (SUCCEEDED(hr))
{
hr = pQueryReader->GetMetadataByName(L"/app1/ifd/{ushort=18249}", &value);
PropVariantClear(&value);
}
Además de consultar elementos de metadatos específicos en un bloque de metadatos, también puede enumerar todos los elementos de metadatos de un bloque de metadatos (no incluidos los elementos de metadatos en bloques de metadatos anidados). Para enumerar los elementos de metadatos del bloque actual, se usa el método GetEnumeration del lector de consultas. Este método obtiene una interfaz IEnumString rellenada con los elementos de metadatos del bloque actual. Por ejemplo, el siguiente código enumera la clasificación XMP y la clasificación de MicrosoftPhoto para el bloque IFD anidado que se obtuvo anteriormente.
IEnumString *metadataItems = NULL;
if (SUCCEEDED(hr))
{
hr = pEmbedReader->GetEnumerator(&metadataItems);
}
Para obtener más información sobre la identificación de etiquetas adecuadas para varios formatos de imagen y formatos de metadatos, vea Consultas de metadatos de formato de imagen nativa.
Métodos de lector de consultas adicionales
Además de leer metadatos, también puede obtener información adicional sobre el lector de consultas y obtener metadatos a través de otros medios. El lector de consultas proporciona dos métodos que proporcionan información sobre el lector de consultas, GetContainerFormat y GetLocation.
Con el lector de consultas incrustado, puede usar GetContainerFormat para determinar el tipo de bloque de metadatos y puede llamar a GetLocation para obtener la ruta de acceso relativa al bloque de metadatos raíz. El código siguiente consulta el lector de consultas incrustado para su ubicación.
// Determine the metadata block format
if (SUCCEEDED(hr))
{
hr = pEmbedReader->GetContainerFormat(&containerGUID);
}
// Determine the query reader's location
if (SUCCEEDED(hr))
{
UINT length;
WCHAR readerNamespace[100];
hr = pEmbedReader->GetLocation(100, readerNamespace, &length);
}
La llamada a GetContainerFormat para el lector de consultas embebido devuelve el GUID del formato de metadatos IFD. La llamada a GetLocation devuelve un espacio de nombres "/app1/ifd"; que proporciona la ruta de acceso relativa desde la que se ejecutarán las consultas posteriores al nuevo lector de consultas. Por supuesto, el código anterior no es muy útil, pero muestra cómo usar el método GetLocation para buscar bloques de metadatos anidados.
Escritura de metadatos mediante un escritor de consultas
Nota:
Algunos de los ejemplos de código proporcionados en esta sección no se muestran en el contexto de los pasos reales necesarios para escribir metadatos. Para ver los ejemplos de código en el contexto de un ejemplo de trabajo, consulte el tutorial Procedimientos: Volver a codificar una imagen con metadatos.
El componente principal para escribir metadatos es el escritor de consultas (IWICMetadataQueryWriter). El escritor de consultas permite establecer y quitar bloques de metadatos y elementos dentro de un bloque de metadatos.
Al igual que el lector de consultas, hay tres maneras de obtener un escritor de consultas: a través de un codificador de mapa de bits (IWICBitmapEncoder), a través de sus fotogramas individuales (IWICBitmapFrameEncode) o a través de un codificador de metadatos rápido (IWICFastMetadataEncoder).
Obtención de un escritor de consultas
El escritor de consultas más común es para un marco individual de un mapa de bits. Este escritor de consultas establece y quita los elementos y bloques de metadatos de un marco de imagen. Para obtener el escritor de consulta de un marco de imagen, llame al método GetMetadataQueryWriter de dicho marco. En el código siguiente se muestra la simple llamada al método para obtener el escritor de consultas de un marco.
IWICMetadataQueryWriter &pFrameQWriter = NULL;
//Obtain a query writer from the frame.
hr = pFrameEncode->GetMetadataQueryWriter(&pFrameQWriter);
Del mismo modo, también se puede obtener un escritor de consultas para el nivel de codificador. Una llamada sencilla al método GetMetadataQueryWriter del codificador obtiene el escritor de consultas del codificador. El escritor de consultas de un codificador, a diferencia del escritor de consultas de un marco, escribe metadatos para una imagen fuera del marco individual. Sin embargo, este escenario no es común y los formatos de imagen nativos no admiten esta funcionalidad. Los códecs de imagen nativos proporcionados por WIC leen y escriben metadatos en el nivel de marco incluso para formatos de fotograma único, como JPEG.
También puede obtener un generador de consultas directamente desde la factoría de creación de imágenes (IWICImagingFactory). Hay dos métodos de generador de imágenes que devuelven un escritor de consultas: CreateQueryWriter y CreateQueryWriterFromReader.
CreateQueryWriter crea un escritor de consultas para el formato de metadatos y el proveedor especificados. Este escritor de consultas permite escribir metadatos para un formato de metadatos específico y agregarlos a la imagen. En el código siguiente se muestra una llamada CreateQueryWriter para crear un escritor de consultas XMP.
IWICMetadataQueryWriter *pXMPWriter = NULL;
// Create XMP block
GUID vendor = GUID_VendorMicrosoft;
hr = pFactory->CreateQueryWriter(
GUID_MetadataFormatXMP,
&vendor,
&pXMPWriter);
En este ejemplo, el nombre GUID_MetadataFormatXMP
amigable se usa como parámetro guidMetadataFormat. Representa el GUID de formato de metadatos XMP y el proveedor representa el controlador creado por Microsoft. Como alternativa, se puede pasar NULL como parámetro pguidVendor con los mismos resultados si no existe ningún otro controlador XMP. Si se instala un controlador XMP personalizado junto con el controlador XMP nativo, pasar NULL para el proveedor dará como resultado el escritor de consultas con el GUID más bajo que se devuelve.
CreateQueryWriterFromReader es similar al método CreateQueryWriter , salvo que rellena previamente el nuevo escritor de consultas con los datos proporcionados por el lector de consultas. Esto resulta útil para volver a codificar una imagen mientras se mantienen los metadatos existentes o para quitar metadatos no deseados. En el código siguiente se muestra una llamada CreateQueryWriterFromReader .
hr = pFrameDecode->GetMetadataQueryReader(&pFrameQReader);
// Copy metadata using query readers
if(SUCCEEDED(hr) && pFrameQReader)
{
IWICMetadataQueryWriter *pNewWriter = NULL;
GUID vendor = GUID_VendorMicrosoft;
hr = pFactory->CreateQueryWriterFromReader(
pFrameQReader,
&vendor,
&pNewWriter);
Agregar metadatos
Después de obtener un escritor de consultas, puede usarlo para agregar bloques de metadatos y elementos. Para escribir metadatos, use el método SetMetadataByName del escritor de consultas. SetMetadataByName toma dos parámetros: una expresión de consulta (wzName) y un puntero a un PROPVARIANT (pvarValue). La expresión de consulta define el bloque o elemento que se va a establecer mientras que PROPVARIANT proporciona el valor de datos real que se va a establecer.
En el ejemplo siguiente se muestra cómo agregar un título mediante el escritor de consultas XMP obtenido anteriormente mediante el método CreateQueryWriter .
// Write metadata to the XMP writer
if (SUCCEEDED(hr))
{
PROPVARIANT value;
PropVariantInit(&value);
value.vt = VT_LPWSTR;
value.pwszVal = L"Metadata Test Image.";
hr = pXMPWriter->SetMetadataByName(L"/dc:title", &value);
PropVariantClear(&value);
}
En este ejemplo, el tipo de valor (vt) se establece en VT_LPWSTR
, lo que indica que se empleará una cadena de texto como valor de datos. Dado que el tipo del valor es una cadena, pwszVal se usa para establecer el título que se va a usar. A continuación, se llama a SetMetadataByName utilizando la expresión de consulta "/dc:title" junto con el PROPVARIANT recién configurado. La expresión de consulta utilizada indica que se debe establecer la propiedad título en el esquema (dc) de la cámara digital. Tenga en cuenta que la expresión no es "/xmp/dc:title"; esto se debe a que el escritor de consultas ya es específico de XMP y no contiene un bloque XMP incrustado, que "/xmp/dc:title" sugeriría.
Hasta este punto no ha agregado ningún metadato a un marco de imagen. Simplemente ha introducido datos en el generador de consultas. Para agregar un bloque de metadatos a un marco, representado por el escritor de consultas, vuelva a llamar a SetMetadataByName utilizando el escritor de consultas como valor de PROPVARIANT. Esto copia eficazmente los metadatos del generador de consultas en el cuadro de imagen. En el código siguiente se muestra cómo agregar los metadatos en el escritor de consultas XMP obtenido anteriormente al bloque de metadatos raíz de un marco.
// Get the frame's query writer and write the XMP query writer to it
if (SUCCEEDED(hr))
{
hr = pFrameEncode->GetMetadataQueryWriter(&pFrameQWriter);
// Copy the metadata in the XMP query writer to the frame
if (SUCCEEDED(hr))
{
PROPVARIANT value;
PropVariantInit(&value);
value.vt = VT_UNKNOWN;
value.punkVal = pXMPWriter;
value.punkVal->AddRef();
hr = pFrameQWriter->SetMetadataByName(L"/", &value);
PropVariantClear(&value);
}
}
En este ejemplo, se usa un tipo de valor (vt) de VT_UNKOWN
; que indica un tipo de valor de interfaz COM. A continuación, el escritor de consultas XMP (piXMPWriter) se usa como valor de PROPVARIANT, agregando una referencia a él mediante el método AddRef. Por último, el escritor de consultas XMP se establece llamando al método SetMetadataByName del marco y pasando la expresión de consulta "/", que indica el bloque raíz y el PROPVARIANT recién establecido.
Nota:
Si el marco ya contiene el bloque de metadatos que está intentando agregar, los metadatos que va a agregar se agregarán y los metadatos existentes se sobrescribirán.
Quitar metadatos
Un escritor de consultas también le permite quitar metadatos llamando al método RemoveMetadataByName . RemoveMetadataByName toma una expresión de consulta y quita el bloque o elemento de metadatos si existe. En el código siguiente se muestra cómo quitar el título que se agregó anteriormente.
if (SUCCEEDED(hr))
{
hr = pFrameQWriter->RemoveMetadataByName(L"/xmp/dc:title");
}
En el código siguiente se muestra cómo quitar todo el bloque de metadatos XMP.
if (SUCCEEDED(hr))
{
hr = pFrameQWriter->RemoveMetadataByName(L"/xmp");
}
Copiar metadatos para volver a codificar
Nota:
El código de esta sección solo es válido cuando los formatos de imagen de origen y destino son los mismos. No se pueden copiar todos los metadatos de una imagen en una sola operación al codificar en un formato de imagen diferente.
Para conservar los metadatos al volver a codificar una imagen en el mismo formato de imagen, hay métodos disponibles para copiar todos los metadatos en una sola operación. Cada una de estas operaciones sigue un patrón similar; cada establece los metadatos del marco descodificado directamente en el nuevo marco que se va a codificar.
El método preferido para copiar metadatos es inicializar el escritor de bloques del nuevo marco con el lector de bloques del marco descodificado. En el código siguiente se muestra este método.
if (SUCCEEDED(hr) && formatsEqual)
{
// Copy metadata using metadata block reader/writer
if (SUCCEEDED(hr))
{
pFrameDecode->QueryInterface(
IID_IWICMetadataBlockReader,
(void**)&pBlockReader);
}
if (SUCCEEDED(hr))
{
pFrameEncode->QueryInterface(
IID_IWICMetadataBlockWriter,
(void**)&pBlockWriter);
}
if (SUCCEEDED(hr))
{
pBlockWriter->InitializeFromBlockReader(pBlockReader);
}
}
En este ejemplo, el lector de bloques y el escritor de bloques se obtienen del marco de origen y del marco de destino, respectivamente. A continuación, el sistema de escritura de bloques se inicializa desde el lector de bloques. Esto inicializa el lector de bloques con los metadatos rellenados previamente del lector de bloques.
Otro método para copiar metadatos consiste en escribir el bloque de metadatos al que hace referencia el lector de consultas mediante el escritor de consultas del codificador. En el código siguiente se muestra este método.
if (SUCCEEDED(hr) && formatsEqual)
{
hr = pFrameDecode->GetMetadataQueryReader(&pFrameQReader);
// Copy metadata using query readers
if(SUCCEEDED(hr))
{
hr = pFrameEncode->GetMetadataQueryWriter(&pFrameQWriter);
if (SUCCEEDED(hr))
{
PropVariantClear(&value);
value.vt=VT_UNKNOWN;
value.punkVal=pFrameQReader;
value.punkVal->AddRef();
hr = pFrameQWriter->SetMetadataByName(L"/", &value);
PropVariantClear(&value);
}
}
}
Aquí se obtiene un lector de consultas del marco descodificado y, a continuación, se usa como valor de propiedad del PROPVARIANT con un tipo de valor establecido en VT_UNKNOWN. El escritor de consultas para el codificador se obtiene y la expresión de consulta "/" se usa para establecer los metadatos en la ruta de navegación raíz. También puede usar este método al establecer bloques de metadatos anidados ajustando la expresión de consulta a la ubicación deseada.
Del mismo modo, puede crear un escritor de consultas basado en el lector de consultas del marco descodificado mediante el método CreateQueryWriterFromReader de la factoría de creación de imágenes. El generador de consultas creado en esta operación se prellenará con los metadatos del lector de consultas y, posteriormente, se podrá configurar en el marco. En el código siguiente se muestra la operación de copia CreateQueryWriterFromReader .
IWICMetadataQueryWriter *pNewWriter = NULL;
GUID vendor = GUID_VendorMicrosoft;
hr = pFactory->CreateQueryWriterFromReader(
pFrameQReader,
&vendor,
&pNewWriter);
if (SUCCEEDED(hr))
{
// Get the frame's query writer
hr = pFrameEncode->GetMetadataQueryWriter(&pFrameQWriter);
}
// Set the query writer to the frame.
if (SUCCEEDED(hr))
{
PROPVARIANT value;
PropVariantInit(&value);
value.vt = VT_UNKNOWN;
value.punkVal = pNewWriter;
value.punkVal->AddRef();
hr = pFrameQWriter->SetMetadataByName(L"/",&value);
}
Este método utiliza un escritor de consultas independiente que se crea a partir de los datos del lector de consultas. A continuación, este nuevo escritor de consultas se incorpora al entorno.
De nuevo, estas operaciones para copiar metadatos solo funcionan cuando las imágenes de origen y destino tienen el mismo formato. Esto se debe a que los diferentes formatos de imagen almacenan los bloques de metadatos en diferentes ubicaciones. Por ejemplo, jpeg y TIFF admiten bloques de metadatos XMP. En imágenes JPEG, el bloque XMP se encuentra en el bloque de metadatos raíz, como se muestra en la información general de metadatos de WIC. Sin embargo, en una imagen TIFF, el bloque XMP está anidado en un bloque IFD raíz. En el diagrama siguiente se muestran las diferencias entre una imagen JPEG y una imagen TIFF con los mismos metadatos de clasificación.
Codificación rápida de metadatos
No siempre es necesario volver a codificar una imagen para escribir nuevos metadatos en ella. Los metadatos también se pueden escribir mediante un codificador de metadatos rápido. Un codificador de metadatos rápido puede escribir una cantidad limitada de metadatos en una imagen sin volver a codificar la imagen. Esto se logra escribiendo los nuevos metadatos en el relleno vacío proporcionado por algunos formatos de metadatos. Los formatos de metadatos nativos que admiten el relleno de metadatos son Exif, IFD, GPS y XMP.
Agregar relleno a bloques de metadatos
Para poder realizar la codificación rápida de metadatos, debe haber espacio en el bloque de metadatos para escribir más metadatos. Si no hay suficiente espacio dentro del relleno existente para escribir los nuevos metadatos, se producirá un error en la codificación rápida de metadatos. Para agregar relleno de metadatos a una imagen, la imagen debe volver a codificarse. Puede agregar relleno de la misma manera que agregaría cualquier otro elemento de metadatos mediante una expresión de consulta, si el bloque de metadatos que está rellenando lo admite. En el ejemplo siguiente se muestra cómo agregar relleno a un bloque IFD incrustado en un bloque App1.
if (SUCCEEDED(hr))
{
// Add metadata padding
PROPVARIANT padding;
PropVariantInit(&padding);
padding.vt = VT_UI4;
padding.uiVal = 4096; // 4KB
hr = pFrameQWriter->SetMetadataByName(L"/app1/ifd/PaddingSchema:padding", &padding);
PropVariantClear(&padding);
}
Para agregar relleno, cree un PROPVARIANT de tipo VT_UI4 y un valor correspondiente al número de bytes de relleno que se van a agregar. Un valor típico es de 4096 bytes. Las consultas de metadatos de JPEG, TIFF y JPEG-XR se encuentran en esta tabla.
Formato de metadatos | Consulta de metadatos JPEG | Consulta de metadatos de TIFF, JPEG-XR |
---|---|---|
IFD | /app1/ifd/PaddingSchema:Padding | /ifd/PaddingSchema:Padding |
EXIF | /app1/ifd/exif/PaddingSchema:Padding | /ifd/exif/PaddingSchema:Padding |
XMP | /xmp/PaddingSchema:Padding | /ifd/xmp/PaddingSchema:Padding |
GPS | /app1/ifd/gps/PaddingSchema:Padding | /ifd/gps/PaddingSchema:Padding |
Obtención de un codificador de metadatos rápidos
Cuando tienes una imagen con relleno de metadatos, se puede obtener un codificador de metadatos rápido mediante los métodos de fábrica de imágenes CreateFastMetadataEncoderFromDecoder y CreateFastMetadataEncoderFromFrameDecode.
Como indica el nombre, CreateFastMetadataEncoderFromDecoder crea un codificador de metadatos rápido para metadatos de nivel de descodificador. Los formatos de imagen nativos proporcionados por WIC no admiten metadatos de nivel de descodificador, pero este método se proporciona en caso de que este formato de imagen se desarrolle en el futuro.
El escenario más común es obtener un codificador de metadatos rápido de un marco de imagen mediante CreateFastMetadataEncoderFromFrameDecode. El código siguiente obtiene el codificador rápido de metadatos de un fotograma ya descodificado y cambia el valor de clasificación en el bloque App1.
if (SUCCEEDED(hr))
{
IWICFastMetadataEncoder *pFME = NULL;
IWICMetadataQueryWriter *pFMEQW = NULL;
hr = pFactory->CreateFastMetadataEncoderFromFrameDecode(
pFrameDecode,
&pFME);
}
Uso del codificador de metadatos rápidos
Desde el codificador rápido de metadatos, puede obtener un generador de consultas. Esto le permite escribir metadatos mediante una expresión de consulta como se mostró anteriormente. Después de establecer los metadatos en el escritor de consultas, aplique el codificador de metadatos rápido para finalizar la actualización de los metadatos. En el código siguiente se muestra cómo establecer y confirmar los cambios de metadatos
if (SUCCEEDED(hr))
{
hr = pFME->GetMetadataQueryWriter(&pFMEQW);
}
if (SUCCEEDED(hr))
{
// Add additional metadata
PROPVARIANT value;
PropVariantInit(&value);
value.vt = VT_UI4;
value.uiVal = 99;
hr = pFMEQW->SetMetadataByName(L"/app1/ifd/{ushort=18249}", &value);
PropVariantClear(&value);
}
if (SUCCEEDED(hr))
{
hr = pFME->Commit();
}
}
Si se produce un error en la confirmación por cualquier motivo, deberá volver a codificar la imagen para asegurarse de que los nuevos metadatos se agregan a la imagen.
Temas relacionados
-
conceptual de
-
Información general del lenguaje de consulta de metadatos de
-
procedimiento: volver a codificar una imagen JPEG con metadatos