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.