Compartilhar via


Implementando IWICMetadataBlockReader

Iwicmetadatablockreader

Vários blocos de metadados geralmente existem em uma imagem, cada um expondo diferentes tipos de informações em formatos diferentes. No modelo WIC (Componente de Imagem do Windows), os manipuladores de metadados são componentes distintos que, como decodificadores, são detectáveis em tempo de execução. Cada formato de metadados tem um manipulador separado e cada um desses manipuladores de metadados pode ser usado com qualquer formato de imagem que dê suporte ao formato de metadados que ele manipula. Portanto, se o formato de imagem der suporte a EXIF, XMP, IPTC ou outro formato, você poderá aproveitar os manipuladores de metadados padrão para esses formatos fornecidos com WIC e você não precisará escrever os seus próprios. É claro que, se você criar um novo formato de metadados, deverá escrever um manipulador de metadados para ele, que será descoberto e invocado em tempo de execução da mesma forma que os padrões.

Observação

Se o formato da imagem for baseado em um contêiner TIFF (Formato de Arquivo de Imagem Marcada) ou JPEG, você não precisará gravar nenhum manipulador de metadados (a menos que você desenvolva um formato de metadados novo ou proprietário). Em contêineres TIFF e JPEG, os blocos de metadados estão localizados em IFDs e cada contêiner tem uma estrutura IFD diferente. O WIC fornece manipuladores IFD para ambos os formatos de contêiner que navegam na estrutura IFD e delegam aos manipuladores de metadados padrão para acessar os metadados dentro deles. Portanto, se o formato da imagem for baseado em qualquer um desses contêineres, você poderá aproveitar automaticamente os manipuladores IFD do WIC. No entanto, se você tiver um formato de contêiner proprietário que tenha sua própria estrutura exclusiva de metadados de nível superior, deverá escrever um manipulador que possa navegar por essa estrutura de nível superior e delegar para os manipuladores de metadados apropriados, assim como os manipuladores IFD fazem.)

 

Da mesma forma que o WIC fornece uma camada de abstração para aplicativos que lhes permitem trabalhar com todos os formatos de imagem da mesma forma por meio de um conjunto consistente de interfaces, o WIC fornece uma camada de abstração para autores de codec em relação aos formatos de metadados. Conforme observado anteriormente, os autores de codec geralmente não precisam trabalhar diretamente com os vários formatos de metadados que podem estar presentes em uma imagem. No entanto, cada autor de codec é responsável por fornecer uma maneira de enumerar os blocos de metadados para que um manipulador de metadados apropriado possa ser descoberto e instanciado para cada bloco.

Você deve implementar essa interface em sua classe de decodificação no nível do quadro. Talvez você também precise implementá-lo em sua classe de decodificador no nível do contêiner se o formato de imagem expor metadados globais fora de qualquer quadro de imagem individual.

interface IWICMetadataBlockReader : IUnknown
{
   // All methods required
   HRESULT GetContainerFormat ( GUID *pguidContainerFormat );
   HRESULT GetCount ( UINT *pcCount );
   HRESULT GetEnumerator ( IEnumUnknown **ppIEnumMetadata );
   HRESULT GetReaderByIndex ( UINT nIndex, IWICMetadataReader **ppIMetadataReader );
}

Getcontainerformat

GetContainerFormat é o mesmo que o método GetContainerFormat em Implementando IWICBitmapDecoder.

GetCount

GetCount retorna o número de blocos de metadados de nível superior associados ao quadro.

GetEnumerator

GetEnumerator retorna um enumerador que o chamador pode usar para enumerar sobre os blocos de metadados no quadro e ler seus metadados. Para implementar esse método, você precisa criar um leitor de metadados para cada bloco de metadados e implementar um objeto de enumeração que enumera sobre a coleção de leitores de metadados. O objeto de enumeração deve implementar IEnumUnknown para que você possa convertê-lo em IEnumUnknown ao retorná-lo no parâmetro ppIEnumMetadata .

Ao implementar o objeto de enumeração, você pode criar todos os leitores de metadados ao criar pela primeira vez o objeto IWICMetadataBlockReader ou ao criar pela primeira vez o objeto de enumeração ou criá-los lentamente dentro da implementação do método IEnumUnknown::Next . Em muitos casos, é mais eficiente criá-los lentamente, mas, no exemplo a seguir, todos os leitores de bloco são criados no construtor para economizar espaço.

public class MetadataReaderEnumerator : public IEnumUnknown
{
   UINT m_current;
   UINT m_blockCount;
   IWICMetadataReader** m_ppMetadataReader;
   IStream* m_pStream;

   MetadataReaderEnumerator() 
   {
       // Set m_blockCount to the number of metadata blocks in the frame. 
      ...
      m_ppMetadataReader = IWICMetadataReader*[m_blockCount];
       m_current = 0;

      for (UINT x=0; x < m_blockCount; x++) 
      {
         // Find the position in the file where the xth
         // block of metadata lives and seek m_piStream 
         // to that position.
         ...

         m_pComponentFactory->CreateMetadataReaderFromContainer(
            GUID_ContainerFormatTiff,
                        NULL,
                        WICPersistOptions.WICPersistOptionsDefault | 
            WICMetadataCreationOptions.WICMetadataCreationDefault, 
                        m_pStream, &m_ppMetadataReader[x]);
        }
    }

    // Implementation of IEnumUnknown and IUnknown interfaces
    ...
}

Para criar os leitores de metadados, use o método CreateMetadataReaderFromContainer . Ao invocar esse método, você passa o GUID do formato de contêiner no parâmetro guidContainerFormat . Se você tiver uma preferência de fornecedor para um leitor de metadados, poderá passar o GUID do fornecedor preferido no parâmetro pGuidVendor . Por exemplo, se sua empresa gravar manipuladores de metadados e você quiser usar seus próprios se estiver presente, poderá passar o GUID do fornecedor. Na maioria dos casos, bastaria passar NULL e permitir que o sistema selecionasse o leitor de metadados apropriado. Se você solicitar um fornecedor específico e esse fornecedor tiver um leitor de metadados instalado no computador, o WIC retornará o leitor desse fornecedor. No entanto, se o fornecedor solicitado não tiver um leitor de metadados instalado no computador e se houver um leitor de metadados apropriado disponível, esse leitor será retornado mesmo que não seja do fornecedor preferencial. Se não houver nenhum leitor de metadados no computador para o tipo de metadados no bloco, a fábrica de componentes retornará o Manipulador de Metadados Desconhecido, que tratará o bloco de metadados como um BLOB (objeto binário grande) e desserializará o bloco de metadados do arquivo sem qualquer tentativa de analisá-lo.

Para o parâmetro dwOptions , execute uma operação OR entre o WICPersistOptions apropriado com o WICMetadataCreationOptions apropriado. O WICPersistOptions descreve como o contêiner é disposto. Little-endian é o padrão.

enum WICPersistOptions
{   
   WICPersistOptionDefault,
   WICPersistOptionLittleEndian,
   WICPersistOptionBigEndian,
   WICPersistOptionStrictFormat,
   WICPersistOptionNoCacheStream,
   WICPersistOptionPreferUTF8
};

O WICMetadataCreationOptions especifica se você deseja obter de volta o UnknownMetadataHandler se nenhum leitor de metadados for encontrado no computador que possa ler o formato de metadados de um bloco específico. WICMetadataCreationAllowUnknown é o padrão e você sempre deve permitir a criação do UnknownMetadtataHandler. O UnknownMetadataHandler trata metadados não reconhecidos como um BLOB. Ele não pode analisá-lo, mas o grava no fluxo como um BLOB e o mantém intacto quando é gravado de volta no fluxo durante a codificação. Isso torna seguro criar manipuladores de metadados para metadados proprietários ou formatos de metadados que não são fornecidos com o sistema. Como os metadados são preservados intactos, mesmo que nenhum manipulador esteja presente no computador que o reconheça, quando um manipulador de metadados apropriado for instalado posteriormente, os metadados ainda estarão lá e poderão ser lidos. Se você não permitir a criação do UnknownMetadataHandler, a alternativa será descartar ou substituir metadados não reconhecidos. Essa é uma forma de perda de dados.

Observação

Se você escrever seu próprio manipulador de metadados para metadados proprietários, nunca deverá incluir referências a nada fora do próprio bloco de metadados. Embora UnknownMetadataHandler preserve metadados intactos, os metadados são movidos quando os arquivos são editados e quaisquer referências a qualquer coisa fora de seu próprio bloco não serão mais válidas quando isso acontecer.

 

enum WICMetadataCreationOptions
{
   WICMetadataCreationDefault = 0x00000000,
   WICMetadataCreationAllowUnknown = WICMetadataCreationDefault,
   WICMetadataCreationFailUnknown = 0x00010000,
   WICMetadataCreationMask = 0xFFFF0000
};

O parâmetro pIStream é o fluxo real que você está decodificação. Antes de passar o fluxo, você deve buscar o início do bloco de metadados para o qual está solicitando um leitor. O leitor de metadados apropriado para o bloco de metadados na posição atual no IStream será retornado no parâmetro ppiReader .

GetReaderByIndex

GetReaderByIndex retorna o leitor de metadados no índice solicitado na coleção.

Referência

Iwicmetadatablockreader

Conceitual

Implementando IWICBitmapFrameDecode

Implementando IWICBitmapSourceTransform

Como escrever um CODEC WIC-Enabled

Visão geral do componente de imagem do Windows