Visão geral da leitura e gravação de metadados de imagem
Este tópico fornece uma visão geral de como você pode usar as APIs do Windows Imaging Component (WIC) para ler e gravar metadados incorporados em arquivos de imagem.
Este tópico contém as seguintes seções.
- Pré-requisitos
- Introdução
- Lendo metadados usando um leitor de consulta
- Escrevendo metadados usando um gravador de consulta
- Codificação rápida de metadados
- Tópicos relacionados
Pré-requisitos
Para entender este tópico, você deve estar familiarizado com o sistema de metadados WIC, conforme descrito no Visão geral dos metadados WIC. Você também deve estar familiarizado com a linguagem de consulta usada para ler e gravar metadados, conforme descrito em Visão geral da linguagem de consulta de metadados.
Introdução
O WIC fornece aos desenvolvedores de aplicativos componentes COM (Component Object Model) para ler e gravar metadados incorporados em arquivos de imagem. Há duas maneiras de ler e gravar metadados:
- Usando um leitor/gravador de consulta e uma expressão de consulta para consultar blocos de metadados para blocos aninhados ou metadados específicos dentro de um bloco.
- Usando um manipulador de metadados (um leitor de metadados ou um gravador de metadados) para acessar os blocos de metadados aninhados ou metadados específicos dentro dos blocos de metadados.
O mais fácil deles é usar um leitor/gravador de consulta e uma expressão de consulta para acessar os metadados. Um leitor de consulta (IWICMetadataQueryReader) é usado para ler metadados, enquanto um gravador de consulta (IWICMetadataQueryWriter) é usado para gravar metadados. Ambos usam uma expressão de consulta para ler ou gravar os metadados desejados. Nos bastidores, um leitor e gravador de consultas utiliza um gestor de metadados para aceder aos metadados descritos pela expressão de consulta.
O método mais avançado é acessar diretamente os manipuladores de metadados. Um manipulador de metadados é obtido dos quadros individuais usando um leitor de blocos (IWICMetadataBlockReader) ou um gravador de bloco (IWICMetadataBlockWriter). Os dois tipos de manipuladores de metadados disponíveis são o leitor de metadados (IWICMetadataReader) e o gravador de metadados (IWICMetadataWriter).
O diagrama a seguir do conteúdo de um arquivo de imagem JPEG é usado em todos os exemplos neste tópico. A imagem representada por este diagrama foi criada usando o Microsoft Paint; os metadados de classificação foram adicionados usando o recurso Galeria de Fotos do Windows Vista.
Lendo metadados usando um leitor de consultas
A maneira mais fácil de ler metadados é usar a interface do leitor de consultas, IWICMetadataQueryReader. O leitor de consultas permite ler blocos de metadados e itens dentro de blocos de metadados usando uma expressão de consulta.
Há três maneiras de obter um leitor de consulta: através de um decodificador de bitmap (IWICBitmapDecoder), através de seus quadros individuais (IWICBitmapFrameDecode), ou através de um gravador de consulta (IWICMetadataQueryWriter).
Obtendo um leitor de consultas
O código de exemplo a seguir mostra como obter um decodificador de bitmap da fábrica de imagens e recuperar um quadro de bitmap individual. Esse código também executa o trabalho de configuração necessário para obter um leitor de consulta de um quadro decodificado.
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);
}
O decodificador de bitmap para o ficheiro test.jpg é obtido utilizando o método CreateDecoderFromFilename da fábrica de imagem. Nesse método, o quarto parâmetro é definido como o valor WICDecodeMetadataCacheOnDemand da enumeraçãoWICDecodeOptions. Isto instrui o decodificador a armazenar em cache os metadados quando necessário, seja através de um leitor de consulta ou do leitor de metadados subjacente. O uso dessa opção permite que você mantenha o fluxo para os metadados necessários para a codificação rápida de metadados e permite a decodificação sem perdas da imagem JPEG. Como alternativa, pode utilizar o outro valor de WICDecodeOptions, WICDecodeMetadataCacheOnLoad, que armazena em cache os metadados de imagem incorporados assim que a imagem é carregada.
Para obter o leitor de consulta do quadro, faça uma chamada simples para o método GetMetadataQueryReader do quadro. O código a seguir demonstra essa chamada.
// Get the query reader
if (SUCCEEDED(hr))
{
hr = pFrameDecode->GetMetadataQueryReader(&pQueryReader);
}
Da mesma forma, um leitor de consultas também pode ser obtido no nível do decodificador. Uma simples chamada para o método de GetMetadataQueryReader do do decodificador obtém o leitor de consultas do decodificador. O leitor de consultas de um decodificador, ao contrário do leitor de consultas de um quadro, lê metadados para uma imagem que está fora dos quadros individuais. No entanto, esse cenário não é comum e os formatos de imagem nativos não oferecem suporte a esse recurso. O CODECS de imagem nativo fornecido pelo WIC lê e grava metadados no nível do quadro, mesmo para formatos de quadro único, como JPEG.
Leitura de metadados
Antes de passar para a leitura de metadados, observe o diagrama a seguir de um arquivo JPEG que inclui blocos de metadados incorporados e dados reais para recuperar. Este diagrama fornece textos explicativos para blocos e itens específicos de metadados na imagem, apresentando a expressão de consulta de metadados para cada bloco ou item.
Para consultar blocos de metadados incorporados ou itens específicos por nome, chame o GetMetadataByName método. Este método utiliza uma expressão de consulta e um PROPVARIANT no qual o item de metadados é retornado. O código a seguir consulta um bloco de metadados aninhado e converte o componente IUnknown fornecido pelo valor PROPVARIANT em leitor de consultas, se encontrado.
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
}
A expressão de consulta "/app1/ifd" está consultando o bloco IFD aninhado no bloco App1. O arquivo de imagem JPEG contém o bloco de metadados aninhado IFD, portanto o PROPVARIANT é retornado com um tipo de variável (vt) de VT_UNKNOWN
e um ponteiro para uma interface IUnknown (punkVal). Em seguida, você consulta a interface IUnknown para um leitor de consulta.
O código a seguir demonstra uma nova consulta com base no novo leitor de consulta relativo ao bloco IFD aninhado.
if (SUCCEEDED(hr))
{
hr = pEmbedReader->GetMetadataByName(L"/{ushort=18249}", &value);
PropVariantClear(&value); // Clear value for new query
}
A expressão de consulta "/{ushort=18249}" procura no bloco IFD a classificação MicrosoftPhoto incorporada na tag 18249. O valor PROPVARIANT agora conterá um tipo de valor de VT_UI2
e um valor de dados de 50.
No entanto, não é necessário obter um bloco aninhado antes de consultar valores de dados específicos. Por exemplo, em vez de consultar o IFD aninhado e, em seguida, a classificação MicrosoftPhoto, pode-se usar o bloco de metadados raiz e a consulta mostrada no código a seguir para obter as mesmas informações.
if (SUCCEEDED(hr))
{
hr = pQueryReader->GetMetadataByName(L"/app1/ifd/{ushort=18249}", &value);
PropVariantClear(&value);
}
Além de consultar itens de metadados específicos em um bloco de metadados, você também pode enumerar todos os itens de metadados em um bloco de metadados (não incluindo itens de metadados em blocos de metadados aninhados). Para enumerar os itens de metadados no bloco atual, o método GetEnumeration do leitor de consulta é usado. Esse método obtém um IEnumString interface preenchida com os itens de metadados no bloco atual. Por exemplo, o seguinte código enumera a classificação XMP e a classificação MicrosoftPhoto para o bloco IFD aninhado previamente obtido.
IEnumString *metadataItems = NULL;
if (SUCCEEDED(hr))
{
hr = pEmbedReader->GetEnumerator(&metadataItems);
}
Para obter mais informações sobre como identificar tags apropriadas para vários formatos de imagem e metadados, consulte Native Image Format Metadata Queries.
Métodos adicionais para leitor de consultas
Além de ler metadados, você também pode obter informações adicionais sobre o leitor de consulta e obter metadados por outros meios. O leitor de consulta fornece dois métodos que fornecem informações sobre o leitor de consulta, GetContainerFormat e GetLocation.
Com o leitor de consulta incorporado, você pode usar GetContainerFormat para determinar o tipo de bloco de metadados e pode chamar GetLocation para obter o caminho relativo ao bloco de metadados raiz. O código a seguir consulta o leitor de consulta incorporado para sua localização.
// 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);
}
A chamada para GetContainerFormat para o leitor de consulta incorporado retorna o GUID do formato de metadados IFD. A chamada para GetLocation retorna um namespace de "/app1/ifd", fornecendo o caminho relativo a partir do qual serão realizadas as consultas subsequentes ao novo leitor de consultas. É claro que o código anterior não é muito útil, mas demonstra como usar o método GetLocation para localizar blocos de metadados aninhados.
Gravando metadados usando um escritor de consultas
Observação
Alguns dos exemplos de código fornecidos nesta seção não são mostrados no contexto das etapas reais necessárias para gravar metadados. Para exibir os exemplos de código no contexto de um exemplo de trabalho, consulte o tutorial Como: Recodificar uma imagem com metadados.
O principal componente para escrever metadados é o gravador de consulta (IWICMetadataQueryWriter). O gravador de consultas permite definir e remover blocos e itens de metadados dentro de um bloco de metadados.
Como o leitor de consultas, há três maneiras de obter um escritor de consultas: através de um codificador de bitmap (IWICBitmapEncoder), através de seus frames individuais (IWICBitmapFrameEncode), ou através de um codificador rápido de metadados (IWICFastMetadataEncoder).
Obtendo um gravador de consultas
O gerador de consulta mais comum é para uma imagem individual de um bitmap. Este escritor de consultas configura e remove os blocos e itens de metadados de uma moldura de imagem. Para obter o gravador de consulta de um quadro de imagem, chame o do quadro GetMetadataQueryWriter método. O código abaixo demonstra como chamar um método simples para obter o escritor de consultas de um fotograma.
IWICMetadataQueryWriter &pFrameQWriter = NULL;
//Obtain a query writer from the frame.
hr = pFrameEncode->GetMetadataQueryWriter(&pFrameQWriter);
Da mesma forma, um gerador de consultas também pode ser obtido para o nível do codificador. Uma simples chamada para o método GetMetadataQueryWriter do codificador obtém o do codificador. Um escritor de consultas de um codificador, ao contrário de um escritor de consultas de quadro, escreve metadados para uma imagem fora do quadro individual. No entanto, esse cenário não é comum e os formatos de imagem nativos não oferecem suporte a esse recurso. Os codecs de imagem nativos fornecidos pelo WIC leem e gravam metadados no nível do quadro, mesmo para formatos de quadro único, como JPEG.
Você também pode obter um escritor de consultas diretamente da fábrica de processamento de imagens (IWICImagingFactory). Há dois métodos de fábrica de imagens que retornam um gravador de consultas: CreateQueryWriter e CreateQueryWriterFromReader.
CreateQueryWriter cria um gravador de consulta para o formato e fornecedor de metadados especificados. Este editor de consultas permite-lhe escrever metadados para um formato de metadados específico e adicioná-los à imagem. O código a seguir demonstra uma chamada para CreateQueryWriter para criar um gravador de consulta XMP.
IWICMetadataQueryWriter *pXMPWriter = NULL;
// Create XMP block
GUID vendor = GUID_VendorMicrosoft;
hr = pFactory->CreateQueryWriter(
GUID_MetadataFormatXMP,
&vendor,
&pXMPWriter);
Neste exemplo, o nome amigável GUID_MetadataFormatXMP
é usado como o parâmetro guidMetadataFormat. Ele representa o GUID do formato de metadados XMP e o fornecedor representa o manipulador criado pela Microsoft. Como alternativa, NULL pode ser passado como o parâmetro pguidVendor com os mesmos resultados se nenhum outro manipulador XMP existir. Se um manipulador XMP personalizado for instalado ao lado do manipulador XMP nativo, passar NULL para o fabricante resultará no retorno do gravador de consulta com o GUID mais baixo.
CreateQueryWriterFromReader é semelhante ao método CreateQueryWriter, exceto que ele preenche previamente o novo gravador de consulta com os dados fornecidos pelo leitor de consulta. Isso é útil para recodificar uma imagem enquanto mantém os metadados existentes ou para remover metadados indesejados. O código a seguir demonstra uma chamada de 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);
Adicionando metadados
Depois de obter um escritor de consultas, pode utilizá-lo para adicionar blocos e itens de metadados. Para gravar metadados, use o método SetMetadataByName do gravador de consultas. SetMetadataByName usa dois parâmetros: uma expressão de consulta (wzName) e um ponteiro para um PROPVARIANT (pvarValue). A expressão de consulta define o bloco ou item a ser definido, enquanto o PROPVARIANT fornece o valor de dados real a ser definido.
O exemplo a seguir demonstra como adicionar um título usando o gravador de consulta XMP obtido anteriormente usando o CreateQueryWriter método.
// 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);
}
Neste exemplo, o tipo de valor (vt) é definido como VT_LPWSTR
, indicando que uma cadeia de caracteres será usada como o valor de dados. Como o tipo do valor é uma string, pwszVal é usado para definir o título.
SetMetadataByName é então chamado usando a expressão de consulta "/dc:title" e o recém-definido PROPVARIANT. A expressão de consulta usada indica que a propriedade title no esquema da câmera digital (dc) deve ser definida. Observe que a expressão não é "/xmp/dc:title"; isso porque o escritor de consultas já é específico para XMP e não contém um bloco XMP incorporado, como "/xmp/dc:title" poderia sugerir.
Até este ponto, você não adicionou nenhum metadados a um quadro de imagem. Você simplesmente preencheu um escritor de consultas com dados. Para adicionar a um quadro um bloco de metadados representado pelo gravador de consulta, chame novamente SetMetadataByName usando o gravador de consulta como o valor do PROPVARIANT. Isso efetivamente copia os metadados no gravador de consulta para o quadro de imagem. O código a seguir demonstra como adicionar os metadados no gravador de consulta XMP obtidos anteriormente ao bloco de metadados raiz de um quadro.
// 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);
}
}
Neste exemplo, um tipo de valor (vt) de VT_UNKOWN
é usado; indicando um tipo de valor de interface COM. O gravador de consulta XMP (piXMPWriter) é então usado como o valor do PROPVARIANT, adicionando uma referência a ele usando o método AddRef. Finalmente, o escritor de consultas XMP é definido utilizando o método SetMetadataByName do quadro e passando a expressão de consulta "/", que indica o bloco raiz, juntamente com o PROPVARIANT recém-definido.
Observação
Se o quadro já contiver o bloco de metadados que você está tentando adicionar, os metadados que você está adicionando serão adicionados e os metadados existentes substituídos.
Removendo metadados
Um gravador de consulta também permite remover metadados chamando o método RemoveMetadataByName. RemoveMetadataByName usa uma expressão de consulta e remove o bloco ou item de metadados, se existir. O código a seguir demonstra como remover o título que foi adicionado anteriormente.
if (SUCCEEDED(hr))
{
hr = pFrameQWriter->RemoveMetadataByName(L"/xmp/dc:title");
}
O código a seguir demonstra como remover todo o bloco de metadados XMP.
if (SUCCEEDED(hr))
{
hr = pFrameQWriter->RemoveMetadataByName(L"/xmp");
}
Copiando metadados para recodificação
Observação
O código nesta seção é válido somente quando os formatos de imagem de origem e de destino são os mesmos. Não é possível copiar todos os metadados de uma imagem em uma única operação ao codificar para um formato de imagem diferente.
Para preservar metadados enquanto recodifica uma imagem para o mesmo formato de imagem, há métodos disponíveis para copiar todos os metadados em uma única operação. Cada uma destas operações segue um padrão semelhante; Cada um define os metadados do quadro decodificado diretamente no novo quadro que está sendo codificado.
O método preferido para copiar metadados é inicializar o gravador de blocos do novo quadro com o leitor de blocos do quadro decodificado. O código a seguir demonstra esse 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);
}
}
Neste exemplo, o leitor de blocos e o gravador de blocos são obtidos do quadro de origem e do quadro de destino, respectivamente. O gravador de bloco é então inicializado a partir do leitor de blocos. Isso inicializa o leitor de bloco com os metadados pré-preenchidos do leitor de bloco.
Outro método para copiar metadados é gravar o bloco de metadados referenciado pelo leitor de consultas usando o gravador de consultas do codificador. O código a seguir demonstra esse 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);
}
}
}
Aqui, um leitor de consulta é obtido do quadro decodificado e, em seguida, usado como o valor da propriedade do PROPVARIANT com um tipo de valor definido como VT_UNKNOWN. O escritor de consultas para o codificador é obtido e a expressão de consulta "/" é usada para configurar os metadados no caminho de navegação raiz. Você também pode usar esse método ao definir blocos de metadados aninhados, ajustando a expressão de consulta para o local desejado.
Da mesma forma, poderá criar um gravador de consulta com base no leitor de consulta do quadro decodificado usando o método CreateQueryWriterFromReader da fábrica de imagens. O gravador de consulta criado nesta operação será pré-preenchido com os metadados do leitor de consulta e poderá ser definido no quadro. O código seguinte demonstra a operação de cópia 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);
}
Esse método usa um gravador de consulta separado que é criado com base nos dados do leitor de consulta. Em seguida, esse novo escritor de consultas é então inserido no quadro.
Novamente, essas operações para copiar metadados só funcionam quando as imagens de origem e de destino têm o mesmo formato. Isso ocorre porque diferentes formatos de imagem armazenam os blocos de metadados em locais diferentes. Por exemplo, JPEG e TIFF suportam blocos de metadados XMP. Em imagens JPEG, o bloco XMP está no bloco de metadados raiz, conforme ilustrado no WIC Metadata Overview. No entanto, numa imagem TIFF, o bloco XMP está aninhado num bloco IFD raiz. O diagrama a seguir ilustra as diferenças entre uma imagem JPEG e uma imagem TIFF com os mesmos metadados de classificação.
Codificação rápida de metadados
Nem sempre é necessário recodificar uma imagem para gravar novos metadados nela. Os metadados também podem ser gravados usando um codificador de metadados rápido. Um codificador de metadados rápido pode gravar uma quantidade limitada de metadados em uma imagem sem recodificá-la. Isso é conseguido gravando novos metadados dentro do espaço vazio fornecido por alguns formatos de metadados. Os formatos de metadados nativos que suportam preenchimento de metadados são Exif, IFD, GPS e XMP.
Adicionando preenchimento a blocos de metadados
Antes de executar a codificação rápida de metadados, deve haver espaço dentro do bloco de metadados para gravar mais metadados. Se não houver espaço suficiente no preenchimento existente para gravar os novos metadados, a codificação rápida de metadados falhará. Para adicionar preenchimento de metadados a uma imagem, a imagem deve ser recodificada. Você pode adicionar preenchimento da mesma forma que adicionaria qualquer outro item de metadados, usando uma expressão de consulta, se o bloco de metadados que você está preenchendo oferecer suporte a ele. O exemplo a seguir demonstra como adicionar preenchimento a um bloco IFD incorporado em um bloco 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 adicionar preenchimento, crie um PROPVARIANT do tipo VT_UI4 e um valor correspondente ao número de bytes de preenchimento a serem adicionados. Um valor típico é 4096 bytes. As consultas de metadados para JPEG, TIFF e JPEG-XR estão nesta tabela.
Formato dos metadados | Consulta de metadados JPEG | TIFF, consulta de metadados JPEG-XR |
---|---|---|
IFD | /app1/ifd/PaddingSchema:Preenchimento | /ifd/PaddingSchema:preenchimento |
EXIF | /app1/ifd/exif/PaddingSchema:Preenchimento | /ifd/exif/PaddingSchema:Preenchimento |
XMP | /xmp/PaddingSchema:preenchimento | /ifd/xmp/PaddingSchema:Preenchimento |
GPS | /app1/ifd/gps/PaddingSchema:Padding | /ifd/gps/PaddingSchema:Preenchimento |
Obtendo um codificador de metadados rápido
Quando se tem uma imagem com preenchimento de metadados, pode-se obter um codificador de metadados rápido utilizando os métodos de fábrica de imagens CreateFastMetadataEncoderFromDecoder e CreateFastMetadataEncoderFromFrameDecode.
Como o nome indica, CreateFastMetadataEncoderFromDecoder cria um codificador de metadados rápido para metadados no nível do decodificador. Os formatos de imagem nativos fornecidos pelo WIC não suportam metadados de nível de decodificador, mas este método é fornecido no caso de tal formato de imagem ser desenvolvido no futuro.
O cenário mais comum é obter um codificador de metadados rápido de um quadro de imagem usando CreateFastMetadataEncoderFromFrameDecode. O código a seguir obtém o codificador de metadados rápidos de um quadro decodificado e altera o valor da classificação no bloco App1.
if (SUCCEEDED(hr))
{
IWICFastMetadataEncoder *pFME = NULL;
IWICMetadataQueryWriter *pFMEQW = NULL;
hr = pFactory->CreateFastMetadataEncoderFromFrameDecode(
pFrameDecode,
&pFME);
}
Usando o codificador de metadados rápidos
A partir do codificador rápido de metadados, pode-se obter um escritor de consultas. Isso permite que você escreva metadados usando uma expressão de consulta, conforme demonstrado anteriormente. Depois que os metadados tiverem sido definidos no gravador de consulta, confirme o codificador de metadados rápido para finalizar a atualização de metadados. O código a seguir demonstra a configuração e a confirmação das alterações de metadados
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();
}
}
Se o Commit falhar por qualquer razão, será necessário recodificar a imagem para garantir que os novos metadados sejam adicionados à imagem.
Tópicos relacionados
-
Conceptual
-
Visão geral dos metadados WIC