Pular para o conteúdo
CrossFly é 100% open sourceSiga no GitHub
CrossFlyCrossFly
Começar

Como gerar um thumbnail (miniatura)

Propósito. Reduzir uma imagem grande a uma miniatura persistente (uma nova Image com pixels realmente reduzidos), em vez de apenas escalar no desenho. Isso economiza memória de textura e banda de GPU quando você exibe muitas miniaturas.

APIs usadas

  • Image resize(int newWidth, int newHeight, ResizeMode mode, ResizeQuality quality) throws ImageException — ponto de entrada principal. Retorna uma nova Image; a original não é modificada.
  • Image resize(int newWidth, int newHeight, ResizeMode mode) — overload que usa ResizeQuality.SMOOTH.
  • Image resize(int newWidth, int newHeight) — overload que usa ResizeMode.STRETCH + ResizeQuality.SMOOTH.
  • Image resizeWidth(int newWidth[, ResizeQuality]) / Image resizeHeight(int newHeight[, ResizeQuality]) — redimensionam preservando a proporção a partir de uma largura ou altura alvo (ideal para thumbnails).

Enums (verificados em UIConstants)

ResizeMode { STRETCH, FIT, FILL }

  • STRETCH — força exatamente w×h (pode distorcer).
  • FIT — mantém a proporção e cabe inteira dentro de w×h (letter-box; resultado pode ser menor que o alvo).
  • FILL — mantém a proporção e preenche w×h, cortando o excesso pelo centro.

ResizeQuality { FAST, SMOOTH, HARDWARE }

  • FAST — amostragem rápida (nearest); use para caches em tempo real.
  • SMOOTH — reamostragem de alta qualidade; use para thumbnails que ficam salvos/exibidos.
  • HARDWARE — mantém os pixels de origem e delega a escala à GPU no desenho (não reduz memória de pixmap).

Exemplo completo (copiar, colar e rodar)

package com.exemplo;

import java.io.IOException;

import dev.crossfly.ui.*;                     // Window, ImageView, UIConstants.ImageSize
import dev.crossfly.ui.layout.*;             // VerticalLayout, LAY_AUTO
import dev.crossfly.ui.image.*;              // Image, ImageException
import dev.crossfly.ui.UIConstants.ResizeMode;
import dev.crossfly.ui.UIConstants.ResizeQuality;

/** Tela principal executável. Aponte o launcher (classname) e rode: gradlew :lwjgl3:run */
public class MainWindow extends Window
{
   @Override
   public void onShow() throws Exception
   {
      super.onShow();
      setLayout(new VerticalLayout());

      try {
         Image original = new Image("/sdcard/foto.jpg");

         // Miniatura 128x128 preenchendo e cortando o excesso, com boa qualidade:
         Image thumb = original.resize(128, 128, ResizeMode.FILL, ResizeQuality.SMOOTH);

         // Alternativa preservando proporção a partir da largura (sem cortar):
         Image thumbW = original.resizeWidth(128, ResizeQuality.SMOOTH);

         add(new ImageView(thumb, UIConstants.ImageSize.ORIGINAL), LAY_AUTO);
         add(new ImageView(thumbW, UIConstants.ImageSize.ORIGINAL), LAY_AUTO);
      } catch (ImageException | IOException e) {
         // arquivo não encontrado ou falha no resize (ex.: "Out of memory")
      }
   }
}

O trecho abaixo mostra só o miolo. Para rodar, coloque-o no esqueleto MainWindow acima.

Trecho mínimo

// verificado na fonte: Image.java resize(...) linha 870; enums em UIConstants (795, 806)
import dev.crossfly.ui.image.*;   // Image, ImageException
import dev.crossfly.ui.UIConstants.ResizeMode;
import dev.crossfly.ui.UIConstants.ResizeQuality;

Image original = new Image("/sdcard/foto.jpg");

// Miniatura 128x128 preenchendo e cortando o excesso, com boa qualidade:
Image thumb = original.resize(128, 128, ResizeMode.FILL, ResizeQuality.SMOOTH);

// Alternativa preservando proporção a partir da largura (sem cortar):
Image thumbW = original.resizeWidth(128, ResizeQuality.SMOOTH);

Nota de implementação (fonte): com ResizeMode.FIT/FILL, o resize primeiro escala uniformemente e, no caso FILL, recorta pelo centro via getArea(...). Com STRETCH chama diretamente o escalonamento exato. resize lança ImageException (ex.: “Out of memory” em imagens muito grandes) e IllegalArgumentException se newWidth/newHeight ≤ 0.

Não confunda resize(...) (cria pixels novos) com renderScaleX/renderScaleY e setRenderScale(...), que apenas escalam no desenho via GPU sem alterar o pixmap.

Aprofunde-se

  • Imagens — diferença entre resize destrutivo e render-scale.
  • Receita irmã: salvar-imagem.md — grave o thumbnail em disco depois de gerá-lo.
Esta página foi útil?