Veja neste artigo uma forma de dividir uma imagem, adicionando as partes a um ImageList.
Quando isso é útil? Suponha que queremos fazer um protótipo de um tipo de jogo 2D, no estilo plataforma, em Delphi (não é muito o foco da ferramenta, mas é possível sim, por que não?). Esse tipo de jogo simples geralmente é baseado em sprites, imagens contendo sequências de posições dos personagens que, quando exibidas dentro de um intervalo de tempo pequeno, dão a ideia de movimento.
Neste artigo, explicarei uma das formas de ser fazer esse procedimento, copiando a imagem “pixel a pixel”. De fato não é a forma mais eficiente de fazer, mas certamente funciona.
Bem, mãos à obra. Nesse exemplo, utilizarei a seguinte imagem, composta por uma sequência de 16 posições.
Figura 1 - Sprite utilizado na composição do movimento
Inicialmente, adicionemos os seguintes componentes ao form principal de uma aplicação Windows e configuremos conforme explicado abaixo.TImage
- Name = imgSrc;
- AutoSize = True;
- Transparent = True;
- Picture = Figura 1, disponível no link código-fonte no topo do artigo;
Timage
- Name = imgDest;
- AutoSize = True;
- Transparent = True;
TButton
TImageList
- Name = imlList;
- Width = 100;
- Height = 150;
No ImageList, usamos as dimensões 100x150 pois são as mesmas de cada subimagem que utilizaremos.
Para facilitar o entendimento do código, vamos definir duas constantes que serão a largura e altura padrão de cada imagem que copiaremos.
Listagem 1: definição de constantes
const
imgWidth = 100;
imgHeight = 150;
No evento onClick do botão, codificaremos da seguinte forma:
Listagem 2: copiando as várias partes da imagem para o ImageList.
var
i, j, k, start, posx:Integer;
begin
imlList.Clear();
start := 0;
for j := 100 to imgSrc.Width do
begin
if j mod imgWidth = 0 then
begin
posx := 0;
for k := start to j do
begin
for I := 0 to imgHeight do
begin
imgDest.Picture.Bitmap.Canvas.Pixels[posx,i]:=
imgSrc.Picture.Bitmap.Canvas.Pixels[k,i];
end;
Inc(posx);
end;
ImageList1.AddMasked(imgDest.Picture.Bitmap, clWhite);
start := j;
Self.Refresh;
end;
end;
end;
O que fazemos é simples: varremos a imagem horizontalmente e a cada 100 pixels (imgWidth) fazemos uma nova varredura, copiando a imagem correspondente à parte do loop em que estamos. Por exemplo, nos primeiros 150px, copiamos os pixels de 0 a 100 horizontais da imgSrc para os pixels de 0 a 100 da imgDest e de 0 a 150 (imgHeight) verticais do imgSrc para os pixels de 0 a 150 verticais do imgDest.
Bem, o procedimento é simples. Ficamos por aqui e espero que gostem. Comentários são bem vindos.
Caso alguém tenha alguma dúvida, estou à disposição para tentar ajudar.
Até o próximo artigo.