Compartilhar via


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 de WIC (Componente de Imagem do Windows) para ler e gravar metadados inseridos em arquivos de imagem.

Este tópico inclui as seções a seguir.

Pré-requisitos

Para entender este tópico, você deve estar familiarizado com o sistema de metadados WIC, conforme descrito na Visão Geral de Metadados do WIC. Você também deve estar familiarizado com a linguagem de consulta usada para ler e gravar metadados, conforme descrito na 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 inseridos 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 em 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.

A mais fácil delas é 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 de consulta (e gravador) utiliza um manipulador de metadados para acessar os 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 blocos (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.

ilustração da imagem jpeg com metadados de avaliação

Lendo Metadadata usando um leitor de consulta

A maneira mais fácil de ler metadados é usar a interface do leitor de consulta, IWICMetadataQueryReader. O leitor de consulta permite que você leia blocos de metadados e itens em blocos de metadados usando uma expressão de consulta.

Há três maneiras de obter um leitor de consulta: por meio de um decodificador de bitmap (IWICBitmapDecoder), por meio de seus quadros individuais (IWICBitmapFrameDecode) ou por meio de um gravador de consulta (IWICMetadataQueryWriter).

Obtendo um leitor de consulta

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 instalaçã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 arquivo test.jpg é obtido usando o método CreateDecoderFromFilename da fábrica de imagens. Nesse método, o quarto parâmetro é definido como o valor WICDecodeMetadataCacheOnDemand da enumeração WICDecodeOptions . Isso informa o decodificador que ele deve armazenar em cache os metadados quando forem necessários, seja obtendo um leitor de consulta ou o leitor de metadados subjacente. Usar essa opção permite manter o fluxo para os metadados necessários para codificação rápida de metadados e permite a decodificação sem perda da imagem JPEG. Como alternativa, você pode usar o outro valor WICDecodeOptions , WICDecodeMetadataCacheOnLoad, que armazena em cache os metadados da imagem inserida 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 consulta também pode ser obtido no nível do decodificador. Uma simples chamada ao método GetMetadataQueryReader do decodificador resulta no leitor de consultas do decodificador. O leitor de consulta de um decodificador, ao contrário do leitor de consulta de um quadro, lê metadados de uma imagem que está fora dos quadros individuais. No entanto, esse cenário não é comum e os formatos de imagem nativa não dão suporte a essa funcionalidade. Os CODECS de imagem nativa fornecidos pelo WIC leem e gravam metadados no nível do quadro, mesmo para formatos de quadro único, como JPEG.

Lendo metadados

Antes de passar para realmente ler metadados, examine o diagrama a seguir de um arquivo JPEG que inclui blocos de metadados inseridos e dados reais a serem recuperados. Este diagrama fornece anotações para blocos e itens específicos de metadados dentro da imagem, apresentando a expressão de consulta de metadados para cada bloco ou item.

ilustração da imagem jpeg com textos explicativos de metadados

Para consultar blocos de metadados inseridos ou itens específicos por nome, chame o método GetMetadataByName . Esse método usa 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 um leitor de consulta, 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 aninhados IFD, de modo que o PROPVARIANT é retornado com um tipo de VT_UNKNOWN variável (vt) e um ponteiro para uma interface IUnknown (punkVal). Em seguida, você consulta a interface IUnknown para obter um leitor de queries.

O código a seguir demonstra uma nova consulta com base no novo leitor de consulta em relação 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}" consulta o bloco IFD para a classificação MicrosoftPhoto incorporada sob o identificador 18249. O valor PROPVARIANT agora conterá um tipo de valor VT_UI2 e um valor de dado 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 primeiro consultar o IFD aninhado e depois a classificação MicrosoftPhoto, você pode 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 (sem incluir 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 uma interface IEnumString preenchida com os itens de metadados no bloco atual. Por exemplo, o código a seguir enumera a classificação XMP e a classificação MicrosoftPhoto para o bloco IFD aninhado obtido anteriormente.

IEnumString *metadataItems = NULL;

if (SUCCEEDED(hr))
{
    hr = pEmbedReader->GetEnumerator(&metadataItems);
}

Para obter mais informações sobre como identificar marcas apropriadas para vários formatos de imagem e formatos de metadados, consulte Consultas de metadados de formato de imagem nativa.

Métodos de leitor de consulta adicionais

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 inserido, você pode usar GetContainerFormat para determinar o tipo de bloco de metadados e chamar GetLocation para obter o caminho relativo ao bloco de metadados raiz. O código a seguir consulta o leitor de consulta inserido 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 de formato de metadados IFD. A chamada para GetLocation retorna um namespace de "/app1/ifd", fornecendo o caminho relativo a partir do qual as consultas subsequentes para o novo leitor de consultas serão executadas. É 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 gravador de consulta

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 codificar novamente uma imagem com metadados.

 

O componente principal para gravar metadados é o gravador de consulta (IWICMetadataQueryWriter). O redator de consultas permite definir e remover blocos de metadados e itens em um bloco de metadados.

Assim como o leitor de consulta, há três maneiras de obter um gravador de consulta: por meio de um codificador bitmap (IWICBitmapEncoder), por meio de seus quadros individuais (IWICBitmapFrameEncode) ou por meio de um codificador de metadados rápido (IWICFastMetadataEncoder).

Obtendo um gerador de consultas

O gerador de consulta mais comum é para um quadro individual de uma imagem bitmap. Este escritor de consulta configura e remove blocos e itens de metadados de um quadro de imagem. Para obter o gravador de consulta de um quadro de imagem, chame o método GetMetadataQueryWriter do quadro de imagem. O código a seguir demonstra a chamada de método simples para obter o gravador de consulta de um quadro.

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 encoder. Uma chamada simples para o método GetMetadataQueryWriter do codificador obtém o gravador de consulta do codificador. O escritor de consultas de um codificador, ao contrário do escritor de consultas de um quadro, escreve metadados para uma imagem fora de cada quadro individual. No entanto, esse cenário não é comum e os formatos de imagem nativa não dão suporte a essa funcionalidade. 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 gerador de consultas diretamente da fábrica de imagens (IWICImagingFactory). Há dois métodos de fábrica de imagens que retornam um gravador de consulta: CreateQueryWriter e CreateQueryWriterFromReader.

CreateQueryWriter cria um escritor de consulta com base no formato de metadados e fornecedor 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 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 GUID_MetadataFormatXMP amigável é usado como o parâmetro guidMetadataFormat . Ele representa o GUID de 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 estiver instalado junto com o manipulador XMP nativo, passar NULL para o fornecedor resultará no gravador de consulta com o GUID mais baixo sendo retornado.

CreateQueryWriterFromReader é semelhante ao método CreateQueryWriter, exceto pelo fato de preencher previamente o novo escritor de consulta com os dados fornecidos pelo leitor de consulta. Isso é útil para codificar novamente uma imagem, mantendo os metadados existentes ou para remover metadados indesejados. O código a seguir demonstra uma chamada 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, você pode usá-lo para adicionar blocos de metadados e itens. Para gravar metadados, use o método SetMetadataByName do gravador de consulta. 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 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);
}

Neste exemplo, o tipo de valor (vt) é definido como VT_LPWSTR, indicando que uma cadeia de caracteres será usada como o valor dos dados. Como o tipo de valor é uma cadeia de caracteres, pwszVal é usado para definir o título a ser usado. SetMetadataByName é chamado usando a expressão de consulta "/dc:title" e o PROPVARIANT recém-definido. A expressão de consulta utilizada indica que a propriedade título no esquema da câmera digital (dc) deve estar definida. Observe que a expressão não é "/xmp/dc:title". Isso porque o escritor de consulta já é específico do XMP e não contém um bloco XMP inserido, o que "/xmp/dc:title" sugere.

Até agora, você não adicionou metadados a um quadro de imagem. Você simplesmente preencheu um gerador de consultas com dados. Para adicionar a um quadro um bloco de metadados representado pelo gravador de consulta, você novamente chama SetMetadataByName usando o gravador de consulta como o valor do PROPVARIANT. Isso copia efetivamente 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 obtido 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_UNKOWN é usado, indicando um tipo de valor de interface COM. O gravador de consulta XMP (piXMPWriter) é então usado como o valor do PROPVARIANT, fazendo uma referência a ele através do método AddRef. Por fim, o gravador de consulta XMP é configurado chamando o método SetMetadataByName do frame e passando a expressão de consulta "/", que indica o bloco raiz, junto 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 metadados existentes substituídos.

 

Removendo metadados

Um gravador de consulta também permite que você remova metadados chamando o método RemoveMetadataByName . RemoveMetadataByName usa uma expressão de consulta e remove o bloco de metadados ou item, 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 codificação novamente

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. Você não pode copiar todos os metadados de uma imagem em uma única operação ao codificar para um formato de imagem diferente.

 

Para preservar metadados ao codificar novamente uma imagem no mesmo formato de imagem, há métodos disponíveis para copiar todos os metadados em uma única operação. Cada uma dessas 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 preferencial 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 bloco são obtidos do quadro de origem e do quadro de destino, respectivamente. O gravador de blocos é então inicializado a partir do leitor de blocos. Isso inicializa o leitor de blocos com os metadados pré-preenchidos do leitor de blocos.

Outro método para copiar metadados é gravar o bloco de metadados referenciado pelo leitor de consulta usando o gravador de consulta 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 valor de propriedade do PROPVARIANT, com o tipo de dado definido como VT_UNKNOWN. O escritor de consultas para o codificador é obtido e a expressão de consulta "/" é usada para definir 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 ao local desejado.

Da mesma forma, você pode criar um gravador de consultas com base no leitor de consultas do quadro que foi decodificado, usando o método CreateQueryWriterFromReader da fábrica de imagens. O escritor de consulta criado nesta operação será pré-preenchido com os metadados do leitor de consultas e, em seguida, poderá ser definido na estrutura. O código a seguir 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 criado com base nos dados do leitor de consulta. Em seguida, esse novo gravador de consulta foi 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 dão suporte a blocos de metadados XMP. Em imagens JPEG, o bloco XMP está no bloco de metadados raiz, conforme ilustrado na Visão Geral de Metadados do WIC. No entanto, em uma imagem TIFF, o bloco XMP é aninhado em um 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.

Comparação entre jpeg e tiff.

Codificação rápida de metadados

Nem sempre é necessário codificar novamente 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 codificar novamente a imagem. A realização disso se dá ao escrever os novos metadados dentro do espaço vazio disponibilizado por alguns formatos de metadados. Os formatos de metadados nativos que dão suporte ao 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 no 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 de metadados rápidos falhará. Para adicionar preenchimento de metadados a uma imagem, a imagem deve ser codificada novamente. Você pode adicionar preenchimento da mesma maneira que adicionaria qualquer outro item de metadados usando uma expressão de consulta, se o bloco de metadados que você está preenchendo der suporte a ele. O exemplo a seguir demonstra como adicionar preenchimento a um bloco IFD inserido em um bloco do 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 de metadados Consulta de metadados JPEG TIFF, JPEG-XR consulta de metadados
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

 

Obtendo um codificador de metadados rápidos

Quando você tem uma imagem com preenchimento de metadados, um codificador de metadados rápido pode ser obtido usando 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 dão suporte a metadados no nível do decodificador, mas esse método é fornecido caso esse formato de imagem seja 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 um codificador rápido de metadados de um quadro decodificado e altera o valor de avaliaçã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

No codificador rápido de metadados, você pode 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ápidos 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 a confirmação falhar por qualquer motivo, você precisará recodificar a imagem para garantir que os novos metadados sejam adicionados à imagem.

Conceitual

visão geral do componente de imagem do Windows

Visão geral dos metadados do WIC

Visão geral da linguagem de consulta de metadados

Visão geral da extensibilidade de metadados

instruções: codificar novamente uma imagem JPEG com metadados