跳到内容
CrossFly 是 100% 开源在 GitHub 关注我们
CrossFlyCrossFly
开始使用

本页面由葡萄牙语机器翻译,可能存在错误。葡萄牙语版本为准。

如何生成缩略图(thumbnail)

目的。 把一张大图缩减为持久化的缩略图(一张像素真正被缩小的新 Image), 而不仅仅是在绘制时缩放。当你显示大量缩略图时,这能节省纹理内存 和 GPU 带宽。

使用的 API

  • Image resize(int newWidth, int newHeight, ResizeMode mode, ResizeQuality quality) throws ImageException — 主入口。返回一张新 Image;原图不被修改。
  • Image resize(int newWidth, int newHeight, ResizeMode mode) — 使用 ResizeQuality.SMOOTH 的重载。
  • Image resize(int newWidth, int newHeight) — 使用 ResizeMode.STRETCH + ResizeQuality.SMOOTH 的重载。
  • Image resizeWidth(int newWidth[, ResizeQuality]) / Image resizeHeight(int newHeight[, ResizeQuality]) — 从目标宽度或高度出发、保持比例地调整尺寸(非常适合缩略图)。

枚举(已在 UIConstants 中验证)

ResizeMode { STRETCH, FIT, FILL }

  • STRETCH — 精确强制 w×h(可能变形)。
  • FIT — 保持比例并把整幅装入 w×h(letter-box;结果可能小于目标)。
  • FILL — 保持比例并填充 w×h,从中心裁掉多余部分。

ResizeQuality { FAST, SMOOTH, HARDWARE }

  • FAST — 快速采样(nearest);用于实时缓存。
  • SMOOTH — 高质量重采样;用于会保存/显示的缩略图。
  • HARDWARE — 保留源像素并在绘制时把缩放委托给 GPU(不减少 pixmap 内存)。

完整示例(复制、粘贴并运行)

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;

/** 可执行的主界面。将 launcher 指向此类(classname)并运行: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");

         // 128x128 缩略图,填充并裁掉多余部分,画质良好:
         Image thumb = original.resize(128, 128, ResizeMode.FILL, ResizeQuality.SMOOTH);

         // 另一种方式:从宽度出发保持比例(不裁剪):
         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) {
         // 文件未找到或 resize 失败(例如 "Out of memory")
      }
   }
}

下面的片段仅展示核心部分。要运行它,请把它放入上面的 MainWindow 骨架中。

最小片段

// 已在源码核实:Image.java resize(...) 870 行;枚举在 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");

// 128x128 缩略图,填充并裁掉多余部分,画质良好:
Image thumb = original.resize(128, 128, ResizeMode.FILL, ResizeQuality.SMOOTH);

// 另一种方式:从宽度出发保持比例(不裁剪):
Image thumbW = original.resizeWidth(128, ResizeQuality.SMOOTH);

实现说明(源码):使用 ResizeMode.FIT/FILL 时,resize 会先均匀缩放, 在 FILL 情况下再通过 getArea(...) 从中心裁切。使用 STRETCH 时直接调用 精确缩放。resize 会抛出 ImageException(例如超大图像上的 “Out of memory”), 并在 newWidth/newHeight ≤ 0 时抛出 IllegalArgumentException。

不要把 resize(...)(创建新像素)与 renderScaleX/renderScaleY 和 setRenderScale(...) 混淆,后者只是通过 GPU 在绘制时缩放而不改变 pixmap。

深入了解

  • 图像 — 破坏性 resize 与 render-scale 的区别。
  • 姊妹配方:salvar-imagem.md — 生成缩略图后把它保存到磁盘。
这个页面有帮助吗?