Partilhar via


Implementando IWICBitmapDecoder

IWICBitmapDecoder

Quando um aplicativo solicita um decodificador, o primeiro ponto de interação com o codec é através da interface IWICBitmapDecoder. Esta é a interface de nível de contêiner que fornece acesso às propriedades de nível superior do contêiner e, mais importante, aos quadros que ele contém. Esta é a interface primária em sua classe de decodificador de nível de contêiner.

interface IWICBitmapDecoder : IUnknown
{
// Required methods
   HRESULT QueryCapability (IStream *pIStream, 
      DWORD *pdwCapabilities );
   HRESULT Initialize ( IStream *pIStream,
      WICDecodeOptions cacheOptions );
   HRESULT GetContainerFormat ( GUID *pguidContainerFormat );
   HRESULT GetDecoderInfo ( IWICBitmapDecoderInfo **pIDecoderInfo );
   HRESULT GetFrameCount ( UINT *pCount );
   HRESULT GetFrame ( UINT index, 
      IWICBitmapFrameDecode **ppIBitmapFrame );

// Optional methods
   HRESULT GetPreview ( IWICBitmapSource **ppIPreview );
   HRESULT GetThumbnail ( IWICBitmapSource **ppIThumbnail );
   HRESULT GetColorContexts ( UINT cCount, 
      IWICColorContext **ppIColorContexts, 
      UINT *pcActualCount );
   HRESULT GetMetadataQueryReader ( IWICMetadataQueryReader **ppIMetadataQueryReader);
   HRESULT CopyPalette ( IWICPalette *pIPalette );
}

Alguns formatos de imagem têm miniaturas globais, contextos de cores ou metadados, enquanto muitos formatos de imagem os fornecem apenas por quadro. Os métodos para acessar esses itens são opcionais em IWICBitmapDecoder , mas são necessários em IWICBitmapFrameDecode. Da mesma forma, alguns codecs não usam formatos de pixel indexados e, portanto, não precisam implementar os métodos CopyPalette em nenhuma das interfaces. Para saber mais sobre os métodos opcionais do IWICBitmapDecoder, consulte Implementing IWICBitmapFrameDecode, onde eles são mais comumente implementados.

QueryCapability

QueryCapability é o método usado para arbitragem de codec. (Consulte Descoberta e Arbitragem no tópico Como O Windows Imaging Component Funciona). Se dois codecs são capazes de decodificar o mesmo formato de imagem, ou se ocorre uma colisão de padrão em que dois codecs usam o mesmo padrão de identificação, esse método permite que você selecione o codec que pode lidar melhor com qualquer imagem específica.

Ao invocar este método, o Windows Imaging Component (WIC) passa-lhe o fluxo propriamente dito que contém a imagem. Você deve verificar se pode decodificar cada quadro dentro da imagem e enumerar através dos blocos de metadados, para declarar com precisão quais recursos esse decodificador tem em relação ao fluxo de arquivos específico passado para ele. Isto é importante para todos os descodificadores, mas particularmente importante para formatos de imagem baseados em contentores TIFF (Tagged Image File Format). O processo de descoberta funciona combinando padrões associados a decodificadores no registro para padrões no arquivo de imagem real. Declarar o seu padrão de identificação no registo garante que o seu descodificador será sempre detetado para imagens no seu formato de imagem. No entanto, o seu descodificador ainda pode ser detetado para imagens noutros formatos. Por exemplo, todos os contêineres TIFF incluem o padrão TIFF, que é um padrão de identificação válido para o formato de imagem TIFF. Isso significa que, durante a descoberta, pelo menos dois padrões de identificação serão encontrados em arquivos de imagem para qualquer formato de imagem baseado em um contêiner no estilo TIFF. Um será o padrão TIFF e o outro será o padrão de formato de imagem real. Embora menos provável, também pode haver colisões de padrões entre outros formatos de imagem não relacionados. É por isso que a descoberta e a arbitragem são um processo em duas etapas. Sempre verifique se o fluxo de imagem passado para QueryCapability é realmente uma instância válida do seu próprio formato de imagem. Além disso, se o codec decodificar um formato de imagem para o qual não possui a especificação, a implementação do QueryCapability deve verificar a presença de qualquer recurso que possa ser válido de acordo com a especificação de formato de imagem que o codec não implementa. Isso garantirá que os usuários não experimentem falhas de decodificação desnecessárias ou obtenham resultados inesperados com seu codec.

Antes de executar qualquer operação na imagem, você deve salvar a posição atual do fluxo, para que você possa restaurá-lo para sua posição original antes de retornar do método. A enumeraçãoWICBitmapDecoderCapabilities que especifica os recursos é definida da seguinte maneira:

enum WICBitmapDecoderCapabilities
{   
   WICBitmapDecoderCapabilitySameEncoder,
   WICBitmapDecoderCapabilityCanDecodeAllImages,
   WICBitmapDecoderCapabilityCanDecodeSomeImages,
   WICBitmapDecoderCapabilityCanEnumerateMetadata,
   WICBitmapDecoderCapabilityCanDecodeThumbnail
}

Você deve declarar WICBitmapDecoderCapabilitySameEncoder apenas se o seu codificador foi aquele que codificou a imagem. Depois de verificar se você pode decodificar cada quadro no contêiner, declare WICBitmapDecoderCapabilityCanDecodeSomeImages se você pode decodificar alguns, mas não todos os quadros, WICBitmapDecoderCapabilityCanDecodeAllImages se você pode decodificar todos os quadros, ou se você não pode decodificar nenhum deles. (Esses dois enums são mutuamente exclusivos; se você retornar WICBitmapDecoderCapabilityCanDecodeAllImages, WICBitmapDecoderCapabilityCanDecodeSomeImages serão ignorados.) Declare WICBitmapDecoderCapabilityCanEnumerateMetadata depois de verificar se você pode enumerar através dos blocos de metadados no contêiner de imagem. Você não precisa verificar se há uma miniatura em cada quadro. Se houver uma miniatura global e você puder decodificá-la, poderá declarar WICBitmapDecoderCapabilityCanDecodeThumbnail. Se não houver uma miniatura global, tente decodificar a miniatura do Quadro 0. Se não houver miniatura em nenhum desses locais, não declare esse recurso.

Depois de determinar as capacidades do descodificador em relação ao fluxo de imagem passado para este método, e tiver verificado que este descodificador pode executar uma operação OR com o WICBitmapDecoderCapabilities nesta imagem, devolva o resultado. Lembre-se de restaurar o fluxo à sua posição original antes de retornar.

Inicializar

Inicializar é invocado por um aplicativo depois que um decodificador foi selecionado para decodificar uma imagem específica. O fluxo de imagem é passado para o decodificador, e um chamador pode, opcionalmente, especificar a opção de cacheWICDecodeOptionspara lidar com os metadados no arquivo.

enum WICDecodeOptions
{
   WICDecodeMetadataCacheOnDemand,
   WICDecodeMetadataCacheOnLoad
}

Alguns aplicativos usam metadados mais do que outros. A maioria dos aplicativos não precisa acessar todos os metadados em um arquivo de imagem e solicitará metadados específicos conforme necessário. Outros aplicativos preferem armazenar em cache todos os metadados antecipadamente do que manter o fluxo de arquivos aberto e executar E/S de disco sempre que precisarem acessar metadados. Se o chamador não especificar uma opção de cache de metadados, o comportamento de cache padrão deverá ser cache sob demanda. Isso significa que nenhum metadados deve ser carregado na memória até que o aplicativo faça uma solicitação específica para esses metadados. Se o aplicativo especificar WICDecodeMetadataCacheOnLoad, os metadados devem ser carregados na memória imediatamente e armazenados em cache. Quando os metadados são armazenados em cache durante o carregamento, o fluxo de arquivos pode ser liberado após os metadados terem sido armazenados em cache.

GetContainerFormat

Para implementar GetContainerFormat, basta retornar o GUID do formato de imagem da imagem para a qual o decodificador é instanciado. Este método também é implementado em IWICMetadataBlockReader e IWICBitmapEncoder.

GetDecoderInfo

GetDecoderInfo retorna um objetoIWICBitmapDecoderInfo. Para obter o objeto IWICBitmapDecoderInfo, basta passar o GUID do seu decodificador para o método CreateComponentInfo em IWICImagingFactorye, em seguida, solicitar a interface IWICBitmapDecoderInfo nele, conforme mostrado no exemplo a seguir.

IWICComponentInfo* pComponentInfo = NULL;
HRESULT hr;
 
hr = m_pImagingFactory->CreateComponentInfo(CLSID_This, &pComponentInfo);

hr = pComponentInfo->QueryInterface(IID_IWICBitmapDecoderInfo, (void**)ppIDecoderInfo);

GetFrameCount

GetFrameCount apenas retorna o número de quadros no contêiner. Alguns formatos de contêiner suportam vários quadros e outros suportam apenas um quadro por contêiner.

GetFrame

GetFrame é um método importante na interfaceIWICBitmapDecoder porque o quadro contém os bits de imagem reais e o objeto decodificador de quadro retornado desse método é o objeto que faz a decodificação real da imagem solicitada. Esse é o outro objeto que você precisa implementar ao escrever um decodificador. Para obter mais informações sobre decodificadores de quadros, consulte Implementing IWICBitmapFrameDecode.

GetPreview

GetPreview retorna uma visualização da imagem. Para uma discussão detalhada das previsualizações, consulte o método Implementing IWICBitmapEncoder na interface Implementing IWICBitmapEncoder.

Se o formato da imagem contiver uma visualização JPEG incorporada, é altamente recomendável que, em vez de escrever um decodificador JPEG para decodificá-lo, você delegue ao decodificador JPEG fornecido com a plataforma WIC para decodificar visualizações e miniaturas. Para fazer isso, procure o início dos dados de imagem de visualização no fluxo e invoque o método CreateDecoderFromStream no IWICImagingFactory.

IWICBitmapDecoder* pPreviewDecoder = NULL;
IWICBitmapFrameDecode* pPreviewFrame = NULL;
IWICBitmapSource* pPreview = NULL;
HRESULT hr;

hr = m_pImagingFactory->CreateDecoderFromStream(
                               m_pStream, NULL, 
                               WICDecodeMetadataCacheOnDemand, &pPreviewDecoder);
hr = pPreviewDecoder->GetFrame(0, pPreviewFrame);
hr = pPreviewFrame->QueryInterface(IID_IWICBitmapSource, (void**)&pPreview);

Referência

IWICBitmapDecoder

IWICBitmapFrameDecode

Conceptual

Interfaces do Decodificador

Implementação do IWICBitmapCodecProgressNotification (Descodificador)

Como escrever um WIC-Enabled CODEC

Visão geral do componente Windows Imaging