Transparência por máscara
Como lidar com máscaras de impressão para transparências

Umas das mais incríveis funções da API do Windows é aquela que trata da transferência de blocos de imagens (BitBlt) entre dispositivos. Com ela, podemos fazer literalmente "mágicas".

E, talvez, a maior mágica seja justamente manipular figuras com áreas transparentes, ou seja, que deixam transparecer o conteúdo original da posição onde são impressas.

Note como a sobreposição simples de duas imagens distintas provoca a perda de elementos gráficos. Não vemos, no exemplo acima, o tronco e as folhas da árvore dentro da área de impressão do motoqueiro.

Nosso propósito é criar uma função para que, ao imprimir uma figura como a do motoqueiro, possamos "ver" o que existia antes nas áreas transparentes.

Começamos nosso trabalho pela figura da moto. Antes de mais nada, teremos que criar a partir dela uma máscara de impressão, ou seja, uma figura em preto e branco que demarque os limites da área a ser mostrada na tela.

O resultado deverá ser mais ou menos como está aí ao lado. A área em branco será transparente durante a impressão e a área preta será "apagada" antes da moto ser impressa.

Chamaremos essa figura de MOTO-1.BMP e a salvamos junto com a figura "completa" da moto (MOTO-0.BMP) e a árvore (ARV-0.BMP). A grande vantagem das funções de transferência de blocos da API é que não precisamos nos preocupar com padrões gráficos de cores.

As imagens, mesmo fazendo parte de um conjunto, podem ter o formato mais adequado à sua estrutura. Valem arquivos desde o padrão monocromático (1 bit) usado na máscara de impressão, até os padrões True Color, com 24 bits para cores.

O truque desse sistema de máscara está em criá-la um pouco maior que a imagem original. Com isso, a figura adquire um contorno preto que lhe confere muito mais profundidade visual.

O passo seguinte é juntar tudo num único bloco de programação Delphi. Definido o formulário e um botão, para ativar a impressão das imagens, o corpo principal da função será o responsável por carregar as figuras (shapes) e preparar a impressão das mesmas:

  //Cria os shapes e carrega-os
  Shape1:= TBitmap.Create;
  Shape2:= TBitmap.Create;
  Shape3:= TBitmap.Create;
  Shape1.LoadFromFile('MOTO-0.BMP');
  Shape2.LoadFromFile('MOTO-1.BMP');
  Shape3.LoadFromFile('ARV-0.BMP');

Agora que as figuras foram carregadas para a memória do programa, definimos os respectivos Handles de manipulação e imprimimos as árvores:

  //Cria os Handles
  Hvid:= Form1.Canvas.Handle;
  Hshp:= Shape3.Canvas.Handle;
          
  //Imprime as árvores na posição 0,0 do formulário}
  BitBlt(Hvid,0,0,190,91,Hshp,0,0,SRCCOPY);
  Hshp:= Shape2.Canvas.Handle;

Note o parâmetro SRCCOPY, no final da instrução BitBlt. Ele define uma cópia sobreposta normal. A seguir definimos o Handle da máscara. Veja, ao lado, como ficará a imagem após a impressão da máscara.

  //Usa a máscara para "limpar" a área de impressão}
  BitBlt(Hvid,10,45,175,45,Hshp,0,0,SRCAND);

O destaque aqui fica por conta do parâmetro SRCAND. Ele indica para a função BitBlt que a cópia da figura deve ser feita usando a instrução lógica AND.

Numa operação AND, entre dois bits, basta que um deles seja zero para que o resultado seja também zero. O padrão de bits gerado pela cor preta corresponde, em binário, a 000000000000000000000000b e o branco a 111111111111111111111111b. Logo, tudo o que for preto, na máscara, será apagado na transferência e tudo que for branco será mantido intacto.

O passo seguinte é usar a figura do motoqueiro, preparada com um fundo preto. Aqui, o parâmetro de impressão da função BitBlt será SRCPAINT, que informa à API o uso da função OR entre bits.

Numa operação OR, entre dois bits, basta que um deles seja 1 para que o resultado também seja 1. Ao contrário da máscara, aqui tudo o que for preto será "visto" como cor transparente.

  //Agora coloca a figura no seu lugar}
  Hshp:= Shape1.Canvas.Handle;
  BitBlt(Hvid,10,45,175,45,Hshp,0,0,SRCPAINT);

Esses recursos mostram apenas o potencial das funções da API do Windows. Ainda estamos longe de uma animação complexa, ou de efeitos especiais, recursos gráficos, etc, mas já é um começo.

Fonte completo, em Delphi, da rotina para usar figuras com cores transparentes.

  procedure MostraMoto;
  var
    Shape1,Shape2: TBitmap;  //Figura e máscara
    Shape3: TBitmap;         //Árvore
    Hshp: HBitmap;           //Handle da figura
    Hvid: HDC;               //Handle da tela
  begin
    //Cria os shapes e carrega-os
    Shape1:= TBitmap.Create;
    Shape2:= TBitmap.Create;
    Shape3:= TBitmap.Create;
    Shape1.LoadFromFile('MOTO-0.BMP');
    Shape2.LoadFromFile('MOTO-1.BMP');
    Shape3.LoadFromFile('ARV-0.BMP');
    //Cria os Handles
    Hvid:= Form1.Canvas.Handle;
    Hshp:= Shape3.Canvas.Handle;
    //Imprime as árvores na posição 0,0
    BitBlt(Hvid,0,0,190,91,Hshp,0,0,SRCCOPY);
    Hshp:= Shape2.Canvas.Handle;
    //Usa a máscara para "limpar" a área de impressão
    BitBlt(Hvid,10,45,175,45,Hshp,0,0,SRCAND);
    //Agora coloca a figura no seu lugar
    Hshp:= Shape1.Canvas.Handle;
    BitBlt(Hvid,10,45,175,45,Hshp,0,0,SRCPAINT);
    //Reseta todo mundo
    Shape1.Free; Shape2.Free; Shape3.Free;
    DeleteDC(Hvid);
  end;

Gostou? Clique no link abaixo para baixar o fonte completo desta matéria.


Download...
Clique no link para fazer o download dos arquivos. Se sua assinatura do club TILT está para vencer, clique aqui e saiba como renová-la.

Fontes completos do exemplo da matéria
 
online