Implementando IWICBitmapFrameEncode

Iwicbitmapframeencode

IWICBitmapFrameEncode é o equivalente do codificador à interface IWICBitmapFrameDecode . Você pode implementar essa interface na classe de codificação no nível do quadro, que é a classe que faz a codificação real dos bits de imagem para cada quadro.

interface IWICBitmapFrameEncode : public IUnknown
{
   // Required methods
   HRESULT Initialize ( IPropertyBag2 *pIEncoderOptions );
   HRESULT SetSize ( UINT width,
               UINT height );
   HRESULT SetResolution ( double dpiX,
               double dpiY );
   HRESULT SetPixelFormat (WICPixelFormatGUID *pPixelFormat);
   HRESULT SetColorContexts ( UINT cCount,
               IWICColorContext **ppIColorContext );
   HRESULT GetMetadataQueryWriter ( IWICMetadataQueryWriter 
               **ppIMetadataQueryWriter );
   HRESULT SetThumbnail ( IWICBitmapSource *pIThumbnail );
   HRESULT WritePixels ( UINT lineCount,
               UINT cbStride,
               UINT cbBufferSize,
               BYTE *pbPixels );
   HRESULT WriteSource ( IWICBitmapSource *pIWICBitmapSource,
               WICRect *prc );
   HRESULT Commit ( void );

// Optional method
   HRESULT SetPalette ( IWICPalette *pIPalette );
};

Initialize

Initialize é o primeiro método invocado em um objeto IWICBitmapFrameEncode depois de ter sido instanciado. Esse método tem um parâmetro, que pode ser definido como NULL. Esse parâmetro representa as opções do codificador e é a mesma instância IPropertyBag2 que você criou no método CreateNewFrame no decodificador no nível do contêiner e passada de volta para o chamador no parâmetro pIEncoderOptions desse método. Nesse momento, você preencheu o struct IPropertyBag2 com propriedades que representam as opções de codificação compatíveis com o codificador no nível do quadro. O chamador agora forneceu valores para essas propriedades para indicar determinados parâmetros de opção de codificação e está passando o mesmo objeto de volta para você para inicializar o objeto IWICBitmapFrameEncode . Você deve aplicar as opções especificadas ao codificar os bits de imagem.

SetSize e SetResolution

SetSize e SetResolution são autoexplicativos. O chamador usa esses métodos para especificar o tamanho e a resolução da imagem codificada.

SetPixelFormat

SetPixelFormat é usado para solicitar um formato de pixel no qual codificar a imagem. Se não houver suporte para o formato de pixel solicitado, você deverá retornar o GUID do formato de pixel mais próximo com suporte no pPixelFormat, que é um parâmetro de entrada/saída.

SetColorContexts

SetColorContexts é usado para especificar um ou mais contextos de cores válidos (também conhecidos como perfis de cor) para essa imagem. É importante especificar os contextos de cor, portanto, um aplicativo que decodifica a imagem posteriormente pode converter do perfil de cor de origem para o perfil de destino do dispositivo que está sendo usado para exibir ou imprimir a imagem. Sem um perfil de cor, não é possível obter cores consistentes em diferentes dispositivos. Isso pode ser frustrante para os usuários finais quando suas fotos parecem diferentes em monitores diferentes, e eles não podem obter as impressões para corresponder ao que eles vêem na tela.

GetMetadataQueryWriter

GetMetadataQueryWriter retorna um IWICMetadataQueryWriter que um aplicativo pode usar para inserir ou editar propriedades de metadados específicas em um bloco de metadados no quadro de imagem.

Você pode instanciar um IWICMetadataQueryWriter do IWICComponentFactory de várias maneiras. Você pode criá-lo a partir de seu IWICMetadataBlockWriter, da mesma forma que IWICMetadataQueryReader foi criado a partir de um IWICMetadataBlockReader no método GetMetadataQueryReader na interface IWICBitmapFrameDecode .

IWICMetadataQueryWriter* piMetadataQueryWriter = NULL;
HRESULT hr;

hr = m_piComponentFactory->CreateQueryWriterFromBlockWriter( 
      static_cast<IWICMetadataBlockWriter*>(this), 
      &piMetadataQueryWriter);

Você também pode criá-lo de um IWICMetadataQueryReader existente, como o obtido usando o método anterior.

hr = m_piComponentFactory->CreateQueryWriterFromReader( 
      piMetadataQueryReader, pguidVendor, &piMetadataQueryWriter);

O parâmetro pguidVendor permite que você especifique um fornecedor específico para o gravador de consulta usar ao instanciar um gravador de metadados. Por exemplo, se você fornecer seus próprios gravadores de metadados, convém especificar seu próprio GUID de fornecedor. Você pode passar NULL para esse parâmetro se não tiver uma preferência.

SetThumbnail

SetThumbnail é usado para fornecer uma miniatura. Todas as imagens devem fornecer uma miniatura globalmente, em cada quadro ou em ambos. Os métodos GetThumbnail e SetThumbnail são opcionais no nível do contêiner, mas, se um codec retornar WINCODEC_ERR_CODECNOTHUMBNAIL do método GetThumbnail , o WIC (Componente de Imagem do Windows) invocará o método GetThumbnail para o Quadro 0. Se nenhuma miniatura for encontrada em nenhum dos lugares, o WIC deverá decodificar a imagem completa e dimensioná-la para o tamanho da miniatura, o que pode incorrer em uma grande penalidade de desempenho para imagens maiores.

A miniatura deve ser de um tamanho e resolução que o torna rápido para decodificar e exibir. Por esse motivo, miniaturas são mais comumente imagens JPEG. Observe que, se você usar JPEG para suas miniaturas, não precisará escrever um codificador JPEG para codificá-los ou um decodificador JPEG para decodificá-los. Você sempre deve delegar ao codec JPEG fornecido com a plataforma WIC para codificação e decodificação de miniaturas.

Writepixels

WritePixels é o método usado para passar linhas de verificação de um bitmap na memória para codificação. O método será chamado repetidamente até que todas as linhas de verificação sejam passadas. O parâmetro lineCount indica quantas linhas de verificação devem ser gravadas nesta chamada. O parâmetro cbStride indica o número de bytes por linha de verificação. cbBufferSize indica o tamanho do buffer passado no parâmetro pbPixels, que contém os bits de imagem reais a serem codificados. Se a altura combinada das linhas de verificação de chamadas cumulativas for maior que a altura especificada no método SetSize , retorne WINCODEC_ERR_TOOMANYSCANLINES.

Quando o WICBitmapEncoderCacheOption for WICBitmapEncoderCacheInMemory, as linhas de verificação deverão ser armazenadas em cache na memória até que todas as linhas de verificação sejam passadas. Se a opção de cache do codificador for WICBitmapEncoderCacheTempFile, as linhas de verificação deverão ser armazenadas em cache em um arquivo temporário, criado ao inicializar o objeto. Em qualquer um desses casos, a imagem não deve ser codificada até que o chamador chame Commit. No caso em que a opção de cache é WICBitmapEncoderNoCache, o codificador deve codificar as linhas de verificação conforme elas são recebidas, se possível. (Em alguns formatos, isso não é possível e as linhas de verificação devem ser armazenadas em cache até que Commit seja chamado.)

A maioria dos codecs brutos não implementará WritePixels, pois eles não dão suporte à alteração dos bits de imagem no arquivo bruto. Os codecs brutos ainda devem implementar WritePixels, no entanto, porque quando os metadados são adicionados, ele pode aumentar o tamanho do arquivo, exigindo que o arquivo seja reescrito no disco. Nesse caso, é necessário poder copiar os bits de imagem existentes, que é o que o método WritePixels faz.

WriteSource

WriteSource é usado para codificar um objeto IWICBitmapSource . O primeiro parâmetro é um ponteiro para um objeto IWICBitmapSource . O segundo parâmetro é um WICRect que especifica a região de interesse a ser codificada. Esse método pode ser chamado várias vezes consecutivas, desde que a largura de cada retângulo seja a mesma largura da imagem final a ser codificada. Se a largura do retângulo passado no parâmetro prc for diferente da largura especificada no método SetSize, retorne WINCODEC_ERR_SOURCERECTDOESNOTMATCHDIMENSIONS. Se a altura combinada das linhas de verificação de chamadas cumulativas for maior que a altura especificada no método SetSize, retorne WINCODEC_ERR_TOOMANYSCANLINES.

As opções de cache funcionam da mesma maneira com esse método que com o método WritePixels descrito anteriormente.

Commit

Commit é o método que serializa os bits de imagem codificados para o fluxo de arquivos e itera todos os gravadores de metadados para o quadro solicitando que eles serializem seus metadados para o fluxo. No caso em que a opção de cache do codificador é WICBitmapEncoderCacheInMemory ou WICBitmapEncoderCacheTempFile, esse método também é responsável pela codificação da imagem e, quando a opção de cache é WICBitmapEncoderCacheTempFile, o método Commit também deve excluir o arquivo temporário usado para armazenar os dados da imagem em cache antes da codificação.

Esse método sempre é invocado depois que todas as linhas de verificação ou retângulos que compõem a imagem foram passadas usando o método Commit ou WriteSource . O tamanho do retângulo final composto por meio das chamadas acumuladas para WritePixels ou WriteSource deve ter o mesmo tamanho que foi especificado no método SetSize. Se o tamanho não corresponder ao tamanho esperado, esse método deverá retornar WINCODECERROR_UNEXPECTEDSIZE.

Para iterar pelos gravadores de metadados e dizer a cada gravador de metadados para serializar seus metadados, invoque GetWriterByIndex para iterar pelos gravadores de cada bloco e invoque IWICPersistStream.Save em cada gravador de metadados.

IWICMetadataWriter* piMetadataWRiter = NULL;
IWICPersistStream* piPersistStream = NULL;
HRESULT hr;

for (UINT x=0; x < m_blockCount; x++) 
{
    hr = GetWriterByIndex(x, & piMetadataWriter);
hr = piMetadataWriter->QueryInterface(
IID_IWICPersistStream,(void**)&piPersistStream);

hr = piPersistStream->Save(m_piStream, 
WICPersistOptions.WicPersistOptionDefault, 
true);
...
}

Setpalette

Somente os codecs que têm formatos indexados precisam implementar o método SetPalette . Se uma imagem usar um formato indexado, use esse método para especificar a paleta de cores usada na imagem. Se o codec não tiver um formato indexado, retorne WINCODEC_ERR_PALETTEUNAVAILABLE desse método.

Conceitual

Implementando IWICBitmapCodecProgressNotification (Codificador)

Implementando IWICMetadataBlockWriter

Como escrever uma WIC-Enabled CODEC

Visão geral do componente de imagem do Windows