Implementando IWICBitmapEncoder

IWICBitmapEncoder

Essa interface é a equivalente à interface IWICBitmapDecoder e é o ponto de partida para codificar um arquivo de imagem. Assim como IWICBitmapDecoder é usado para recuperar propriedades de nível de contêiner e quadros individuais do contêiner de imagem, IWICBitmapEncoder é usado para definir propriedades no nível do contêiner e serializar quadros de imagem individuais no contêiner. Você implementa essa interface em sua classe de codificador no nível do contêiner.

interface IWICBitmapEncoder : public IUnknown
{
   // Required methods
   HRESULT Initialize ( IStream *pIStream,
              WICBitmapEncoderCacheOption cacheOption );
   HRESULT GetContainerFormat ( GUID *pguidContainerFormat );
   HRESULT GetEncoderInfo ( IWICBitmapEncoderInfo **pIEncoderInfo );
   HRESULT CreateNewFrame ( IWICBitmapFrameEncode **ppIFrameEncode,
              IPropertyBag2 **ppIEncoderOptions );
   HRESULT Commit ( void );

   // Optional methods
   HRESULT SetPreview ( IWICBitmapSource *pIPreview );
   HRESULT SetThumbnail ( IWICBitmapSource *pIThumbnail );
   HRESULT SetColorContexts ( UINT cCount,
              IWICColorContext **ppIColorContext );
   HRESULT GetMetadataQueryWriter ( IWICMetadataQueryWriter 
              **ppIMetadataQueryWriter );
   HRESULT SetPalette ( IWICPalette *pIPalette);
};

Conforme discutido em Implementação de IWICBitmapDecoder, alguns formatos de imagem têm miniaturas globais, contextos de cores ou metadados, enquanto muitos formatos de imagem os fornecem apenas por quadro. Portanto, os métodos para defini-los são opcionais em IWICBitmapEncoder, mas são necessários em IWICBitmapFrameEncode. Discutiremos os métodos opcionais no IWICBitmapEncoder na seção em IWICBitmapFrameEncode, em que eles são mais comumente implementados.

Se você não der suporte a miniaturas globais, retorne WINCODEC_ERR_CODECNOTHUMBNAIL do método SetThumbnail em IWICBitmapEncoder. Se você não der suporte a uma paleta no nível do contêiner ou se a imagem que você está codificando não tiver um formato indexado, retorne WINCODEC_ERR_PALETTEUNAVAILABLE do método SetPalette. Para quaisquer outros métodos sem suporte, retorne WINCODEC_ERR_UNSUPPORTEDOPERATION.

Initialize

Initialize é o primeiro método invocado em um IWICBitmapEncoder depois de ter sido instanciado. Um fluxo de imagem é passado para o codificador e um chamador pode, opcionalmente, especificar uma opção de cache. No caso do decodificador, o fluxo é somente leitura, mas o fluxo passado para um codificador é um fluxo gravável, no qual o codificador serializará todos os dados e metadados da imagem. As opções de cache no codificador também são diferentes.

enum WICBitmapEncoderCacheOption
{
   WICBitmapEncoderCacheInMemory,
   WICBitmapEncoderCacheTempFile,
   WICBitmapEncoderNoCache
}

O aplicativo tem a opção de solicitar ao codificador para armazenar em cache os dados da imagem na memória, armazená-los em cache em um arquivo temporário ou gravá-los diretamente no arquivo de disco sem cache. Quando solicitado a armazenar os dados em cache em um arquivo temporário, o codificador deve criar um arquivo temporário no disco e gravar diretamente nesse arquivo sem armazenar em cache na memória. Quando o chamador seleciona a opção sem cache, cada quadro deve ser confirmado em ordem antes que o próximo quadro possa ser criado.

Getcontainerformat

GetContainerFormat é implementado da mesma maneira que o método GetContainerFormat em Implementando IWICBitmapDecoder.

GetEncoderInfo

GetEncoderInfo retorna um objeto IWICBitmapEncoderInfo . Para obter o objeto IWICBitmapEncoderInfo , basta passar o GUID do codificador para o método CreateComponentInfo em IWICImagingFactory e solicitar a interface IWICBitmapEncoderInfo nele.

Consulte o exemplo em Implementando IWICBitmapDecoder em GetDecoderInfo.

Createnewframe

CreateNewFrame é o equivalente do codificador de GetFrame no IWICBitmapDecoder. Esse método retorna um objeto IWICBitmapFrameEncode , que é o objeto que realmente serializa os dados da imagem para um quadro específico dentro do contêiner.

Um dos benefícios do WIC (Componente de Imagem do Windows) é que ele fornece uma camada de abstração para aplicativos que permitem que eles trabalhem com todos os formatos de imagem da mesma maneira. No entanto, nem todos os formatos de imagem são exatamente iguais. Alguns formatos de imagem têm recursos que outros não têm. Para que os aplicativos possam aproveitar esses recursos exclusivos, é necessário fornecer uma maneira de o codec expô-los. Essa é a finalidade das opções do codificador. Se o codec der suporte a qualquer opção de codificador, você deverá criar um objeto IPropertyBag2 que expõe as opções de codificador compatíveis e devolvê-lo no parâmetro ppIEncoderOptions desse método. Em seguida, o chamador pode usar esse objeto IPropertyBag2 para determinar quais opções de codificador o codec dá suporte. Se o chamador quiser especificar valores para qualquer uma das opções de codificador com suporte, ele atribuirá o valor à propriedade relevante no objeto IPropertyBag2 e o passará para o objeto IWICBitmapFrameEncode recém-criado em seu método Initialize.

Para instanciar um objeto IPropertyBag2 , primeiro você precisa criar um struct PROPBAG2 para especificar cada opção de codificador compatível com o codificador e seu tipo de dados para cada propriedade. Em seguida, você deve implementar um objeto IPropertyBag2 que impõe os intervalos de valor para cada propriedade na gravação e reconcilia quaisquer valores conflitantes ou sobrepostos. Para conjuntos simples de opções de codificador não conflitantes, você pode invocar o método CreateEncoderPropertyBag , que criará um objeto IPropertyBag2 simples usando as propriedades especificadas em seu struct PROPBAG2. Você ainda deve impor os intervalos de valores. Para opções de codificador mais avançadas ou se precisar reconciliar valores conflitantes, você deverá escrever sua própria implementação IPropertyBag2.

UINT cuiPropertyCount = 0;
IPropertyBag2* pPropertyBag = NULL;
PROPBAG2* pPropBagOptions;
HRESULT hr;

// Insert code here to initialize piPropertyBag with the 
// supported options for your encoder, and to initialize 
// cuiPropertyCount to the number of encoder option properties
// you are exposing.
...

hr = pComponentFactory->CreateEncoderPropertyBag( 
   pPropBagOptions, cuiPropertyCount, &pPropertyBag);

O WIC fornece um pequeno conjunto de opções de codificador canônico que são usadas por alguns dos formatos de imagem comuns. Todas as opções de codificador canônico são opcionais e codecs não são necessários para dar suporte a nenhuma delas. O motivo pelo qual eles são fornecidos como opções canônicas é porque muitos aplicativos expõem a interface do usuário para que os usuários especifiquem essas opções ao salvar um arquivo de imagem em um formato que dê suporte a eles. Fornecer uma maneira canônica de especificar essas opções torna mais fácil para os aplicativos comunicá-las aos codificadores de maneira consistente. As opções de codificador canônico são listadas na tabela a seguir.

Opção de codificador VARTYPE Intervalo de valores
Lossless VT_BOOL Verdadeiro/Falso
ImageQuality VT_R4 0.0-1.0
CompressionQuality VT_R4 0.0-1.0
BitmapTransform VT_UI1 WICBitmapTransformOptions

 

Se o codec der suporte à codificação sem perda, você deverá expor a opção Codificador sem perda como uma maneira de os aplicativos solicitarem que uma imagem seja codificada sem perdas. Se um chamador definir essa propriedade como True, você deverá ignorar a opção ImageQuality e codificar a imagem sem perda.

A opção ImageQuality permite que um aplicativo especifique o grau de fidelidade com o qual codificar a imagem. Essa opção permite que um usuário faça uma compensação entre a qualidade da imagem versus a velocidade e/ou o tamanho do arquivo. JPEG é um exemplo de um formato de imagem que dá suporte a essa compensação. Um valor de 0,0 indica que a fidelidade é de baixa importância e o codificador deve usar seu algoritmo mais perdido. Um valor 1.0 indica que a fidelidade é a mais importante e o codificador deve preservar a maior fidelidade possível. (Dependendo do codec, isso pode ser sinônimo da opção Sem perda. No entanto, se o codec der suporte à codificação sem perda e se a opção Sem Perdas estiver definida como True, a opção ImageQuality deverá ser ignorada.)

A opção CompressionQuality permite que um aplicativo especifique a eficiência da compactação a ser usada ao codificar a imagem. Um algoritmo muito eficiente pode produzir um arquivo de imagem menor com a mesma qualidade que um algoritmo de compactação menos eficiente, mas pode levar mais tempo para codificar. Essa opção permite que um usuário especifique uma compensação entre o tamanho do arquivo versus a velocidade da codificação, preservando o mesmo nível de qualidade. TIFF é um exemplo de um formato de imagem que dá suporte a essa compensação. (Observe que um formato como JPEG dá suporte a diferentes níveis de compactação, mas uma taxa mais alta de compactação resulta em menor qualidade de imagem. Portanto, um formato de imagem JPEG exporia a opção ImageQuality em vez da opção CompressionQuality.) Um valor de 0,0 para essa opção indica que você deve compactar a imagem o mais rápido possível, sem reduzir a fidelidade, em detrimento de um tamanho de arquivo maior. Um valor 1.0 indica que você deve criar o menor tamanho de arquivo possível (no mesmo nível de qualidade), independentemente de quanto tempo possa levar para codificá-lo. Um codec pode dar suporte à opção ImageQuality e à opção CompressionQuality, em que a opção ImageQuality especifica o grau aceitável de perda e a opção CompressionQuality oferece uma compensação de tamanho/velocidade no nível de qualidade especificado.

A opção BitmapTransform fornece uma maneira de o chamador especificar um ângulo de rotação ou orientação de inversão vertical ou horizontal durante a codificação. A enumeração WICBitmapTransformOptions usada para especificar a transformação solicitada é a mesma enumeração usada ao solicitar uma transformação durante a decodificação por meio da interface IWICBitmapSourceTransform.

Observe que os codificadores não estão limitados às opções de codificador canônico. A finalidade das opções do codificador é permitir que os codificadores exponham seus recursos e não há limite para os tipos de recursos que você pode expor. Verifique se as opções do codificador estão bem documentadas. Embora um aplicativo possa usar o recipiente de propriedades que você retorna desse método para descobrir os nomes, tipos e intervalos de valores para as opções compatíveis, a única maneira de descobrir seus significados ou como expô-los na interface do usuário é na documentação.

Commit

Commit é o método que você chama depois que todos os dados e metadados da imagem são serializados no fluxo. Você deve usar esse método para serializar os dados da imagem de visualização no fluxo e quaisquer miniaturas globais, metadados, paleta ou outros itens, se aplicável. Esse método não deve fechar o fluxo de arquivos, pois o aplicativo que abriu o fluxo deve fechá-lo.

A seção sobre o método IWICBitmapFrameEncode:Commit tem detalhes sobre como o IWICBitmapEncoderCacheOptions afeta o comportamento desse método.

SetPreview

SetPreview é usado para criar uma visualização da imagem. Embora não seja estritamente necessário que cada imagem tenha uma versão prévia, é altamente recomendável. Câmeras digitais modernas e scanners geram imagens de alta resolução, que tendem a ser muito grandes e, consequentemente, levam um tempo significativo de processamento para decodificar. As imagens da próxima geração de câmeras serão ainda maiores. É uma boa ideia fornecer uma versão de resolução menor e menor de uma imagem, normalmente no formato JPEG, que pode ser rapidamente decodificada e exibida "instantaneamente" quando um usuário a solicita. Um aplicativo pode solicitar uma visualização antes de solicitar que a imagem real seja decodificada para fornecer uma experiência melhor para os usuários e mostrar a eles uma representação em tamanho de tela da imagem enquanto eles estão aguardando para decodificar a imagem real. Embora os codecs devam fornecer visualizações, codecs que não dão suporte a IWICBitmapSourceTransform definitivamente devem fazer isso.

Se você fornecer uma versão prévia do JPEG, não precisará escrever um codificador JPEG para codificá-lo. Você deve delegar ao codificador JPEG que acompanha a plataforma WIC para codificar visualizações e miniaturas.

Referência

IWICBitmapEncoder

Iwicbitmapframeencode

Conceitual

Interfaces do codificador

Implementando IWICBitmapCodecProgressNotification (Codificador)

Como escrever um CODEC WIC-Enabled

Visão geral do componente de imagem do Windows