No artigo anterior, criamos uma animação procedural, onde com um algoritmo simples, um padrão de cores foi gerado. Neste artigo vamos criar um efeito sobre uma imagem já existente utilizando um conceito simples de transparência.
Opacidade
Segundo o Wikipedia:A opacidade é uma propriedade óptica da matéria. Um material é considerado opaco quando não permite a passagem da luz em quantidades apreciáveis. Geralmente, diz-se que um material é opaco quando bloqueia a passagem da luz visível. (http://pt.wikipedia.org/wiki/Opacidade)
Para nossos estudos, vamos definir opacidade como sendo o nível de transparência de uma imagem cujo valor será representado por um byte, o que nos dá uma faixa de
256
valores possíveis (0..255
) onde 0
define uma imagem completamente transparente e 255
uma imagem completamente opaca.Vamos criar um descendente de TBitmap onde adicionaremos esta propriedade.
TSprite = class(TBitmap)
private
fOpacity: byte;
procedure SetOpacity(const Value: byte);
published
property Opacity: byte read FOpacity write SetOpacity;
end;
Agora vamos instanciar nosso sprite na inicialização do programa (lembrando que estamos modificando o código do template cirado nos artigos anteriores)
procedure TForm1.FormCreate(Sender: TObject);
begin
ReportMemoryLeaksOnShutdown := True;
ClientWidth := 800;
ClientHeight := 600;
fOffScreen := TBitmap.Create;
fOffScreen.PixelFormat := pf24bit;
fOffScreen.Width := ClientWidth;
fOffScreen.Height := ClientHeight;
fOffScreen.Canvas.Font.Color := clGray;
fOffScreen.Canvas.Font.Size := 9;
sprite := TSprite.Create;
sprite.LoadFromFile('img01.bmp');
sprite.Opacity := MAXBYTE div 2;
Application.OnIdle := OnIdle;
end;
Windows.AlphaBlend
50%
de opacidade sobre um background preto (note que já configuramos opacidade como MAXBYTE div 2
).A primeira coisa que precisamos para usar o Windows.AlphaBlend é configurar um registro do tipo TBlendFunction (Veja a descrição oficial deste struct no MSDN).
procedure TForm1.DrawToBuffer;
var
Canvas : TCanvas;
Blendf : TBlendFunction;
begin
Canvas := fOffScreen.Canvas;
Canvas.Brush.Color := clBlack;
Canvas.FillRect(fOffScreen.Canvas.ClipRect);
Blendf.BlendOp := AC_SRC_OVER;
Blendf.BlendFlags := 0;
Blendf.SourceConstantAlpha := sprite.Opacity;
Blendf.AlphaFormat := AC_SRC_OVER;
end;
O parâmetro
BlendOp
representa a opração de mesclagem a executar. Como queremos copiar nosso sprite “por cima” da imagem de fundo, setamos BlendOP
com a constante AC_SRC_OVER
.O parâmatro
BlendFlags
deve ser sempre zero.SourceConstantAlpha
define um valor de transparência a ser aplicado na imagem de origem. Aqui, simplesmente passamos o valor da opacidade de nosso sprite.Por fim,
AlphaFormat
deve ser AC_SRC_OVER
para que o Windows não tente buscar informações de transparência nos pixels da imagem de origem, aplicando em vez disto, o valor de SourceConstantAlpha
.Pronto. Com nosso
TBlendFunction
configurado, podemos desenhar o sprite semi-transparente. Complemente o método DrawToBuffer
conforme a listagem abaixo e execute o programa para ver o resultado.
procedure TForm1.DrawToBuffer;Se tudo estiver certo, você vai ver uma imagem no canto esquerdo da tela de seu programa. A imagem parece muito escura porque metade a luminosidade foi misturada com o fundo negro. Altere o valor de opacidade do sprite para chegar a resultados diferentes.
var
Canvas : TCanvas;
Blendf : TBlendFunction;
begin
Canvas := fOffScreen.Canvas;
Canvas.Brush.Color := clBlack;
Canvas.FillRect(fOffScreen.Canvas.ClipRect);
Blendf.BlendOp := AC_SRC_OVER;
Blendf.BlendFlags := 0;
Blendf.SourceConstantAlpha := sprite.Opacity;
Blendf.AlphaFormat := AC_SRC_OVER;
Windows.AlphaBlend(
Canvas.Handle, {manipulador da imagem de destino}
fOffScreen.Width - sprite.Width, {coordenada X}
0, {coordenada Y}
sprite.Width, {largura da área de desenho}
sprite.Height, {altura da área de desenho}
sprite.Canvas.Handle, {manipulador da imagem de origem}
0, {coordenada X}
0, {coordenada Y}
sprite.Width, {largura da imagem de origem}
sprite.Height, {altura da imagem de origem}
Blendf {parâmetros de executação(TBlendFunction)}
);
Canvas.TextOut(10, 10, Format('Opacidade : %d', [sprite.Opacity]));
end;
Fade In e Fade Out
Uma aplicação muito comum da opacidade em imagens é a criação dos efeitos Fade In e Fade Out. Em um (fade in) uma imagem vai surgindo aos poucos até ficar completamente visível, no outro (fade out) a imagem vai se apagando até sumir completamente. Com o que já temos até aqui, é realmente muito fácil implementar estes efeitos: basta ir alterando o valor da propriedadeOpacity
ao longo do tempo. Vejamos como ficará o método UpdateAnimation.
procedure TForm1.UpdateAnimation;
begin
if OpIncreasing then
sprite.Opacity := sprite.Opacity + 1
else
sprite.Opacity := sprite.Opacity - 1;
case sprite.Opacity of
0 : OpIncreasing := true;
255 : OpIncreasing := false;
end;
end;
Execute o programa e veja os efeitos em funcionamento. Para conseguir novos efeitos, altere os valores dos incrementos e decrementos em cada iteração.
Até o próximo post.
Downloads
- FadeIn e FadeOut: Código fonte | executável
Links
Links para as postagens que fazem parte do mini curso "Animações em Tempo real com a VCL"- Parte I
- Parte II
- Parte III
- Parte IV
This post first appeared on Computação Gráfica E Jogos Em Pascal, please read the originial post: here