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.

Sprite utilizado na composição do movimento

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.