Como funciona o Windows Imaging Component
Descoberta e arbitragem
Antes que uma imagem possa ser decodificada, um codec apropriado deve ser encontrado que possa decodificar esse formato de imagem. Na maioria dos sistemas, como os formatos de imagem suportados são codificados, nenhum processo de descoberta é necessário. Como a plataforma Windows Imaging Component (WIC) é extensível, é necessário ser capaz de identificar o formato de uma imagem e combiná-la com um codec apropriado.
Para oferecer suporte à descoberta em tempo de execução, cada formato de imagem deve ter um padrão de identificação que possa ser usado para identificar o decodificador apropriado para esse formato. (É altamente recomendável que, para novos formatos de arquivo, você use um GUID para o padrão de identificação, porque é garantido que ele seja exclusivo.) O padrão de identificação deve ser incorporado em cada arquivo de imagem que esteja em conformidade com esse formato de imagem. Cada descodificador tem uma entrada de registo que especifica o padrão ou padrões de identificação dos formatos de imagem que pode descodificar. Quando um aplicativo precisa abrir uma imagem, ele solicita um decodificador do WIC. O WIC procura os descodificadores disponíveis no registo e verifica cada entrada de registo à procura de um padrão de identificação que corresponda ao padrão incorporado no ficheiro de imagem. Para obter mais informações sobre entradas de registro do decodificador, consulte Encoder-Specific Registry Entries
Quando o WIC encontra um único decodificador que corresponde ao padrão de identificação na imagem, ele cria uma instância do decodificador e passa o arquivo de imagem para ele. Se o WIC encontrar mais de uma correspondência, ele invocará um método chamado QueryCapability em cada decodificador correspondente para arbitrar entre eles e encontrar a melhor correspondência. Para obter mais informações, consulte a seção QueryCapabilities no Implementing IWICBitmapDecoder.
Descodificação
Depois de selecionado e instanciado o descodificador adequado, a aplicação fala diretamente com o descodificador. O descodificador tem várias responsabilidades, que implementa através de várias interfaces. Estes serviços podem ser classificados como:
- Serviços no nível do contêiner
- Serviços ao nível da estrutura
- Serviços de enumeração de metadados
- Transformações nativas do decodificador
- Notificações de progresso e suporte de cancelamento
- Serviços de processamento de matérias-primas
Os serviços de nível de contêiner incluem a recuperação da miniatura de nível superior (se suportada), visualização, contextos de cores, paleta (se aplicável) e formato de contêiner, bem como fornecer acesso aos quadros de imagem individuais dentro do contêiner. (Alguns contêineres contêm apenas um único quadro, enquanto outros, como o TIFF (Tagged Image File Format), podem conter vários quadros.) Este conjunto de serviços também inclui o fornecimento de informações sobre o próprio descodificador e as suas capacidades em relação a um ficheiro de imagem específico.
Quadros individuais têm suas próprias miniaturas e também podem ter seus próprios contextos de cores, paletas e outras propriedades, que são expostas no nível do quadro. A operação mais importante realizada no nível do quadro, no entanto, é a decodificação real dos bits de imagem para esse quadro.
O WIC fornece leitores de metadados para os formatos de metadados mais comuns (IFD, EXIF, IPTC, XMP, APP0, APP1 e outros formatos) e também suporta extensibilidade para formatos de metadados de terceiros. Isso libera o codec da responsabilidade pela análise de metadados. No entanto, o codec é responsável por enumerar os blocos de metadados e solicitar um leitor de metadados para cada bloco. O WIC realiza a descoberta para manipuladores de metadados da mesma forma que faz para codecs, baseando-se num padrão no cabeçalho do bloco correspondente a um padrão na entrada do registo do manipulador de metadados. Para obter mais informações, consulte as entradas no registo Encoder-Specific
Os decodificadores não são necessários para suportar nativamente operações de transformação, mas isso permite otimizações de desempenho significativas que fornecem uma melhor experiência ao usuário final. Por exemplo, um aplicativo pode criar um pipeline de várias transformações (dimensionamento, corte, rotação e conversão de formato de pixel) para executar em uma imagem antes que a imagem seja renderizada. Para obter mais informações sobre pipelines de transformação, consulte IWICBitmapSource. Depois de criar um pipeline de transformação, o aplicativo solicita a transformação final no pipeline para produzir o bitmap resultante da aplicação de todas as transformações à fonte da imagem. Nesse ponto, se o próprio decodificador for capaz de executar operações de transformação, o WIC perguntará qual das transformações solicitadas ele pode executar. Todas as transformações solicitadas que o decodificador não pode executar serão executadas pelo WIC na imagem decodificada antes de devolvê-la ao chamador. Esse pipeline de transformação otimizado oferece melhor desempenho do que executar cada transformação sequencialmente na memória, particularmente quando algumas ou todas as transformações podem ser realizadas durante o processo de decodificação.
As notificações de progresso e o suporte a cancelamentos permitem que um aplicativo solicite notificações de progresso para operações longas e também permitem que o aplicativo dê ao usuário a oportunidade de cancelar uma operação que está demorando muito. Isso é importante porque se um usuário não pode cancelar uma operação, ele ou ela pode sentir que o processo travou, e tentar cancelá-lo fechando o aplicativo.
Essas interfaces são descritas em detalhes na seção sobre implementando um decodificador habilitado para WIC.
Os serviços de processamento bruto incluem ajustar as configurações da câmera, como exposição, contraste e nitidez, ou alterar o espaço de cores antes de processar os bits brutos.
Codificação
Tal como os descodificadores, os codificadores têm responsabilidades que implementam através de interfaces. Os serviços que os codificadores fornecem são complementares aos serviços fornecidos pelos descodificadores, exceto que escrevem dados de imagem em vez de os lerem. Os codificadores também prestam serviços nas seguintes categorias:
- Serviços no nível do contêiner
- Serviços ao nível do quadro
- Serviços de enumeração e atualização de metadados
- Notificação de progresso e suporte de cancelamento
Os serviços a nível de contêiner para um codificador incluem a definição da miniatura principal (se suportada), pré-visualização, e paleta (se aplicável), bem como a iteração pelos quadros de imagem individuais para que possam ser serializados no contêiner.
Os serviços ao nível do frame para um codificador refletem os do descodificador, exceto que gravam os dados da imagem, a imagem em miniatura e qualquer paleta associada ou outro componente, em vez de os lerem.
Além disso, os serviços de enumeração de metadados para um codificador incluem a iteração através dos blocos de metadados a serem gravados e a invocação dos gravadores de metadados apropriados para serializar os metadados no disco.
Essas interfaces são descritas em detalhes na seção sobre Implementando um codificador habilitado para WIC.
O tempo de vida de um codec
Um codec WIC é instanciado para lidar com uma única imagem e geralmente tem um tempo de vida curto. Ele é criado quando uma imagem é carregada e é liberado quando a imagem é fechada. Um aplicativo pode usar um grande número de codecs simultaneamente com tempos de vida sobrepostos (pense em rolar por um diretório contendo centenas de imagens), e vários aplicativos podem estar fazendo isso ao mesmo tempo.
Embora alguns codecs tenham um tempo de vida que é definido para o tempo de vida do processo em que vivem, este não é o caso com codecs WIC. A Galeria de Fotos do Windows Vista, o Windows Explorer e o Visualizador de Fotos, bem como vários outros aplicativos, são criados no WIC e usarão seu codec para exibir imagens e miniaturas. Se o tempo de vida do codec fosse definido para o tempo de vida do processo, toda vez que uma imagem ou miniatura fosse exibida no Windows Vista Explorer, o codec instanciado para decodificar essa imagem permaneceria na memória até a próxima vez que o usuário reiniciasse seu computador. Se o seu codec nunca é descarregado, seus recursos são, na verdade, "vazados" porque eles não podem ser usados por qualquer outro componente no sistema.
Como habilitar um codec para WIC
- Implemente uma classe de decodificador no nível do contêiner e uma classe de decodificador no nível do quadro que exponha as interfaces WIC necessárias para decodificar imagens e iterar através de blocos de metadados. Isso permite que todos os aplicativos baseados em WIC interajam com seu codec da mesma forma que interagem com formatos de imagem padrão.
- Implemente uma classe de codificador de nível de contêiner e uma classe de codificador de nível de quadro que exponha as interfaces WIC necessárias para codificar imagens e serializar blocos de metadados em um arquivo de imagem.
- Se o formato do contêiner não for baseado em um contêiner TIFF ou JPEG, talvez seja necessário escrever manipuladores de metadados para os formatos de metadados comuns (EXIF, XMP). No entanto, se você usar um formato de contêiner baseado em TIFF ou JPEG, isso não será necessário porque você pode delegar aos manipuladores de metadados fornecidos pelo sistema.
- Incorpore um padrão de identificação exclusivo (recomendamos um GUID) em todos os seus arquivos de imagem. Isso permite que o formato da imagem seja comparado com o codec durante o processo de descoberta. Se você estiver escrevendo um wrapper WIC para um formato de imagem existente, deverá encontrar um padrão de bits que o codificador sempre grava em seus arquivos de imagem que seja exclusivo para esse formato de imagem e usá-lo como o padrão de identificação.)
- Registe o seu codec no momento da instalação. Isso permite que seu codec seja descoberto em tempo de execução, combinando o padrão de identificação no registro com o padrão incorporado no arquivo de imagem.
- A partir do Windows 7, o WIC requer que os codecs sejam do tipo de apartamento COM 'Both'. Isso significa que deve fazer o bloqueio apropriado para lidar com chamadores entre diferentes apartamentos e em cenários multithread. Para obter mais informações, consulte a próxima seção sobre suporte ao modelo de apartamento com múltiplas threads.
- Suporte para plataformas de 64 bits: Para o Windows 7, o WIC exigirá que codecs WIC de terceiros sejam fornecidos como binários nativos de 32 bits e 64 bits. Além disso, o formulário de 32 bits deve ser instalado e executado em sistemas de 64 bits, e o instalador de codec do Windows 7 de terceiros deve instalar os binários de 32 bits e 64 bits em sistemas de 64 bits.
Suporte para apartamentos com múltiplas threads em WIC
Os objetos dentro de um apartamento com múltiplas threads (MTA) podem ser chamados simultaneamente por qualquer número de threads dentro do MTA. Isso permite um melhor desempenho em sistemas multi-core e determinados cenários de servidor. Além disso, os codecs WIC num MTA podem invocar outros objetos no MTA sem o custo de empacotamento associado à chamada entre threads em diferentes apartamentos STA. No Windows 7, todos os codecs WIC in-box foram atualizados para suportar MTAs, incluindo JPEG, TIFF, PNG, GIF, ICO e BMP. É altamente recomendável que codecs de terceiros sejam escritos para suportar MTAs. Codecs de terceiros que não suportam MTAs causam custos de desempenho significativos em aplicativos multi-threaded devido ao marshaling. Habilitar o suporte MTA requer que a sincronização adequada seja implementada no codec de terceiros. A implementação exata dessas técnicas de sincronização está além do escopo deste artigo. Para obter mais informações sobre a sincronização de objetos COM, consulte Compreendendo e usando modelos de encadeamento COM.