Implementando IWICMetadataBlockReader
IWICMetadataBlockReader
Vários blocos de metadados geralmente existem dentro de uma imagem, cada um expondo diferentes tipos de informações em diferentes formatos. No modelo WIC (Windows Imaging Component), os manipuladores de metadados são componentes distintos que, como os decodificadores, podem ser descobertos 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 ofereça suporte ao formato de metadados manipulado. Portanto, se o formato de imagem suportar EXIF, XMP, IPTC ou outro formato, você poderá aproveitar os manipuladores de metadados padrão para esses formatos fornecidos com o WIC e não precisará escrever o seu próprio. Claro, 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, assim como os padrão.
Observação
Se o formato da imagem for baseado em um contêiner TIFF (Tagged Image File Format) ou JPEG, você não precisará escrever nenhum manipulador de metadados (a menos que desenvolva um formato de metadados novo ou proprietário). Em contêineres TIFF e JPEG, blocos de metadados estão localizados dentro de 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 WIC. No entanto, se você tiver um formato de contêiner proprietário que tenha sua própria estrutura de metadados de nível superior exclusiva, deverá escrever um manipulador que possa navegar nessa estrutura de nível superior e delegar aos manipuladores de metadados apropriados, assim como os manipuladores IFD.)
Da mesma forma que o WIC fornece uma camada de abstração para aplicativos que lhes permite trabalhar com todos os formatos de imagem da mesma maneira através 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. Como 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. Também pode ser necessário implementá-lo em sua classe de decodificador no nível de contêiner se o formato da 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 Implementing 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 o 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 quando você cria pela primeira vez o IWICMetadataBlockReader objeto ou quando você cria o objeto de enumeração pela primeira vez, ou você pode criá-los preguiçosamente dentro da implementação do IEnumUnknown::Next método. Em muitos casos, é mais eficiente criá-los de forma preguiçosa, mas, no exemplo a seguir, os leitores de bloco são todos criados no construtor para otimizar o uso de 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 este método, passa o GUID do formato de contentor no parâmetro guidContainerFormat. Se tiveres uma preferência de fornecedor para um leitor de metadados, podes passar o GUID do teu fornecedor preferido no parâmetro pGuidVendor. Por exemplo, se sua empresa escreve manipuladores de metadados e você deseja usar o seu próprio se presente, você pode passar o GUID do fornecedor. Na maioria dos casos, você apenas passaria NULLe deixaria o sistema selecionar 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 objeto binário grande (BLOB) 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 apropriado WICPersistOptions e o apropriado WICMetadataCreationOptions . O WICPersistOptions descrever como seu contêiner é disposto. Little-endian é o padrão.
enum WICPersistOptions
{
WICPersistOptionDefault,
WICPersistOptionLittleEndian,
WICPersistOptionBigEndian,
WICPersistOptionStrictFormat,
WICPersistOptionNoCacheStream,
WICPersistOptionPreferUTF8
};
O WICMetadataCreationOptions especificar se você deseja recuperar o UnknownMetadataHandler se nenhum leitor de metadados for encontrado na máquina 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. Não consegue analisá-lo, mas escreve-o no fluxo como um BLOB e mantém-no intacto quando é escrito de volta no fluxo durante a codificação. Isso torna segura a criação de 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 os reconhece, 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 é descartar ou substituir metadados não reconhecidos. Esta é 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 o UnknownMetadataHandler preserve os 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á decodificando. Antes de passar no fluxo, você deve procurar o início do bloco de metadados para o qual você está solicitando um leitor. O leitor de metadados apropriado para o bloco de metadados na posição corrente no IStream será retornado através do parâmetro ppiReader.
GetReaderByIndex
GetReaderByIndex retorna o leitor de metadados no índice solicitado na coleção.
Tópicos relacionados
-
de referência
-
Conceptual
-
Visão geral do componente Windows Imaging