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

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

如何从文件或网络加载图像

目的。 从本地路径加载图像文件(PNG、JPEG 或 GIF),或从网络下载的字节 加载,并用 ImageView 在屏幕上显示它。这是显示照片、图标和插图最常见的 方式。

使用的 API

  • new Image(String path) throws ImageException, IOException — 从文件路径加载图像。如果找不到文件(读取后 width == 0),则抛出 ImageException。
  • new Image(byte[] bytes) throws ImageException — 从已在内存中的字节数组解码图像(PNG/JPEG/GIF)。对从网络下载的数据使用此构造函数。
  • new ImageView(Image image, ImageSize imageSize) — 创建绘制图像的控件。使用 ImageSize.RATIO 时,图像会在保持比例的情况下均匀缩放(letter-boxing),不裁切。
  • ImageView.imageSize(ImageSize) / .alignX(Position) / .alignY(Position) — 用于调整尺寸模式和对齐方式(默认 Position.CENTER)的流式 setter。

Javadoc 与代码的偏差:new Image(String) 的 Javadoc 写的是 “@throws ImageException When the file was not found”,但实际签名还声明了 IOException。两者都要处理。

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

package com.exemplo;

import java.io.IOException;

import dev.crossfly.Main;                    // runOnPaintThreadAndWait
import dev.crossfly.ui.*;                     // Window, Component, ImageView, UIConstants.ImageSize
import dev.crossfly.ui.layout.*;             // VerticalLayout, LAY_FILL
import dev.crossfly.ui.image.*;              // Image, ImageException

/** 可执行的主界面。将 launcher 指向此类(classname)并运行:gradlew :lwjgl3:run */
public class MainWindow extends Window
{
   private ImageView imageView;

   @Override
   public void onShow() throws Exception
   {
      super.onShow();
      setLayout(new VerticalLayout());

      // 1) 从本地文件加载
      try {
         Image img = new Image("/sdcard/foto.jpg");   // 可能抛出 ImageException / IOException
         ImageView iv = new ImageView(img, UIConstants.ImageSize.RATIO);
         add(LAY_FILL, iv);
      } catch (ImageException | IOException e) {
         // 文件未找到或已损坏
      }

      // 2) 从网络:在 paint thread 之外下载并解码,然后更新 widget
      imageView = new ImageView(null, UIConstants.ImageSize.RATIO);
      add(LAY_FILL, imageView);

      new Thread(() -> {
         try {
            byte[] data = baixarBytes("https://exemplo.com/foto.png"); // 你的 HTTP client
            Image img = new Image(data);              // 在 paint thread 之外解码
            Main.runOnPaintThreadAndWait(() -> imageView.image(img));
         } catch (Exception e) {
            // 处理网络/解码错误
         }
      }).start();
   }

   /** Stub:替换为你自己的 HTTP 客户端。 */
   private byte[] baixarBytes(String url) throws IOException
   {
      return new byte[0];
   }
}

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

最小片段

// 已在源码核实:Image.java(403、432 行)和 ImageView.java(72 行)
import dev.crossfly.ui.image.*;   // Image, ImageException
import dev.crossfly.ui.*;         // ImageView, UIConstants.ImageSize

// 1) 从本地文件加载
try {
   Image img = new Image("/sdcard/foto.jpg");   // 可能抛出 ImageException / IOException
   ImageView iv = new ImageView(img, UIConstants.ImageSize.RATIO);
   add(iv, /* 你的容器的位置/布局 */);
} catch (ImageException | java.io.IOException e) {
   // 文件未找到或已损坏
}

从网络(在 paint thread 之外下载字节)

new Image(...) 会解码像素,是一项繁重的操作。绝不要在 paint thread 上下载或解码。在工作线程中下载字节、在那里创建 Image,然后再更新控件。

// 已在源码核实:new Image(byte[]) — Image.java 432 行
new Thread(() -> {
   try {
      byte[] data = baixarBytes("https://exemplo.com/foto.png"); // 你的 HTTP client
      Image img = new Image(data);              // 在 paint thread 之外解码
      // 现在在 paint thread 上安排 UI 更新
      Main.runOnPaintThreadAndWait(() -> imageView.image(img));
   } catch (Exception e) {
      // 处理网络/解码错误
   }
}).start();

深入了解

这个页面有帮助吗?