Usando o ImageList com múltiplos dimensionamentos

O ImageList(TImageList) é um repositório de imagens. Podemos armazenar nele quantas imagens desejarmos e em qualquer formato suportado pela linguagem, mas geralmente vamos usar Bitmap(.bmp), Portable Network Graphics (.png) e JPEG (.jpg ou .jpeg).

Há uma grande diferença entre o ImageList do Delphi e do Lazarus, enquanto no Delphi todas as imagens num ImageList precisam ter a mesma definição de largura e altura, no Lazarus não é assim. Na realidade o Delphi possui o VirtualImageList que serve justamente para permitir múltiplos redimensionamentos de um mesmo grupo de imagens, contudo boa parte dos programadores continuam a usar o velho ImageList.

Se desejar, poderá ver na prática a explicação deste artigo em vídeo:

Como funciona o ImageList no Lazarus? Mais importante do que saber como funciona é primeiro saber onde ancorar um componente ImageList, boa parte dos programadores criaram o hábito de incluir um ImageList em cada formulário com as imagens de que precisará naquele formulário, essa lógica é muito boa, contudo, se há imagens que serão compartilhadas entre muitos formulários, por exemplo, para usar dentro de botões para indicar sair, imprimir, acrescentar, remover, editar, etc… então você deve ter um ImageList somente para elas, isso economizará trabalho na manutibilidade do programa.

Onde colocar o Imagelist? O formulário principal é onde está uma quantidade incrível de componentes e códigos de programação então acrescentar algo alí é uma complexidade a ser evitada então a melhor ideia é criar um datamodule, este tem footprint menor de recursos e complexidade, portanto é seguro usar ele ao invés do formulário principal.

Criando um datamodule

Se você tem um datamodule principal em seu programa então ignore essa parte, caso contrário, em um projeto novo vá em File|New… e escolha criar um datamodule:

Criando um datamodule para conter um ImageList

O próximo passo é arrastar um ImageList para dentro do datamodule e então configurar o tamanho máximo da altura(height) e da largura(width), se for informado 64×64, todas as imagens que eu depositar dentro do ImageList poderão ter tamanho 48×48, 32×32, 24×24, 16×16,…qualquer definição que você queira, mas não poderá ser maior que 64×64, por isso escolha com cuidado o tamanho máximo que desejará, afinal se precisar de um tamanho diferente você vai ter que apagar todo o conteúdo e começar do zero novamente:

Escolha com cuidado a primeira definição de largura e altura, não poderá trocar mais tarde sem apagar o conteúdo existente

Incluindo Imagens

Incluir imagens é muito simples, clique com o botão direito sobre o componente Imagelist e escolha a opção ImageList Editor:

E então inclua todas as suas imagens, mas atenção, todas as imagens deverão ter no mínimo o tamanho que você definiu antes, em nosso exemplo 64×64:

Todas as imagens adicionadas deverão ter a mesma definição informada anteriormente

Até esse ponto, provavelmente você não viu nada de mais, é igual ao que esta acostumado. Agora vamos novamente até a opção ImageList Editor e vamos acrescentar novas resoluções, clicando em New resolutions:

Agora podemos acrescentar novas resoluções

Se você informou inicialmente sua resolução como 64×64 então as novas resoluções que informará deverão ser proporcionais e menor que 64×64, então quando uma janela de dialogo lhe perguntar qual será a nova resolução basta informar a largura e ele calculará a altura. Por exemplo, para adicionar as resoluções: 48×48, 32×32, 24×24 e 16×16, basta informar na sequencia 48, 32, 24 e 16 e elas serão criadas na proporção:

Adicionando novas resoluções as imagens previamente adicionadas

Agora seu ImageList que antes tinha apenas imagens na resolução 64×64, agora terá também 48×48, 32×32, 24×24 e 16×16, mas como usufruir delas dentro do programa?

Usufruindo das imagens dentro do ImageList

Todos os componentes visuais que permitem sua associação com um componente ImageList possuem a propriedade Images, o que precisamos fazer é a associação desse componente com o ImageList que está no datamodule. Você precisará incluir a unidade do datamodule no uses de seu projeto (Use Alt+F11) antes de prosseguir:

Associando a propriedade Images de um componente ao ImageList que está no datamodule

Provavelmente tudo isso que eu disse você já sabia, agora você quer saber como mudar o tamanho daquela imagem no botão, não é mesmo? Note que todo componente que possui uma propriedade Images tem também a propriedade ImageWidth e ImageIndex:

Em ImageWidth você pode digitar 64, 48, 32, 24 e 16, todas aquelas resoluções que acrescentamos ao ImageList, depois disso basta selecionar em ImageIndex a imagem que precisa:

Definido a largura de que precisamos, agora é só escolher o ImageIndex adequado

Se precisarmos de imagens diferentes em diferentes proporções basta ajustar sempre a propriedade ImageWidth:

Demonstração do uso das propriedades ImageList, ImageIndex e ImageWidth

Qualquer componente que tenha a propriedade Images (que aceita um TImageList) pode usar a propriedade ImageWidth para informar a resolução que você deseja aplicar a imagem selecionada desde que tal resolução tenha sido acrescentada previamente ao ImageList selecionado.

Dessa forma, aprendemos que o ImageList no Lazarus é um pouco diferente do Delphi, possuindo recursos extras.

Importante: O ImageList pode aceitar qualquer tipo de imagem suportado pela IDE e pelo Pascal, no entanto, muitos programadores não usam ele apenas para colocar a arte nos botões, menus, DBGrids, etc… ele também pode servir para fazermos conversões de uma imagem para outra, habilitar transparência, uso de mascaras, ler/salvar imagens do disco e tantas outras coisas e evitar complexidades de programação usando esses formatos diretamente.

Você deve estar se perguntando qual é o melhor formato gráfico para usufruir dentro de seus programas? Isso depende, se for apenas para arte gráfica em botões, banners e estilos usados por seu programa não há duvidas que o melhor formato é o PNG porque ele mantêm a mesma qualidade em diferentes resoluções. Mas se você intenciona usar as imagens dentro de relatórios, PDFs e/ou interagir com outros componentes de terceiros talvez o melhor formato seja mesmo o Bitmap, todos os componentes de terceiros que lidam com imagens são compatíveis com Bitmap, mas nem todos lidam com PNG e geralmente requer que você converta-os para Bitmap para poder usufruir então é mais rápido não converter e usar Bitmap diretamente.

Caso queira estudar os exemplos, os mesmos podem ser obtidos aqui:

https://github.com/gladiston/lazdemos_gsl