# 如何捕获屏幕截图

> 使用 Main.getScreenShot 把当前后台缓冲区捕获为 Image 并保存。

Source: https://crossfly.dev/zh/docs/cookbook/images/screenshot — CrossFly documentation. Full docs as one file: https://crossfly.dev/llms-full.txt

# 如何捕获屏幕截图

**目的。** 获取一个包含当前屏幕内容（OpenGL 后台缓冲区）的 `Image`，无需重绘
任何内容，并可选地保存它。适用于诊断、可视化测试和分享。

## 使用的 API
- `static Image Main.getScreenShot(boolean... opaque)` — 捕获**当前帧**。`opaque=true` 会移除 alpha 通道（使一切不透明）。这是最常用的静态便捷方法。内部通过 `runOnPaintThreadAndWait` 在 paint thread 上调用实例版本。
- `Image Main.getScreenShot(boolean opaque)`（实例）— 相同的捕获；把读取调度到 paint thread 并阻塞直到完成。
- `Image Main.getNextScreenShot(boolean opaque)`（实例）— 强制重绘并捕获**下一**帧。当你刚刚更改了 UI 并希望确保该更改出现在截图中时使用；如果在 paint thread 之外调用，它会循环重绘/更新直到获取到该帧。
- `String Image.toPng(String... prefix)` / `String Image.toJpg(int... quality)` — 用于保存结果（见 [salvar-imagem.md](/docs/cookbook/images/salvar-imagem)）。

## 完整示例（复制、粘贴并运行）

```java
package com.exemplo;

import dev.crossfly.*;                        // Main
import dev.crossfly.ui.*;                     // Window, Button
import dev.crossfly.ui.layout.*;             // VerticalLayout, LAY_AUTO
import dev.crossfly.ui.image.*;              // Image
import dev.crossfly.util.*;                  // Debug

/** 可执行的主界面。将 launcher 指向此类（classname）并运行：gradlew :lwjgl3:run */
public class MainWindow extends Window
{
   @Override
   public void onShow() throws Exception
   {
      super.onShow();
      setLayout(new VerticalLayout());

      Button b = new Button("Capturar tela");
      b.onAction(origin ->
      {
         // 捕获当前帧，不透明（无 alpha），并保存为 PNG：
         Image shot = Main.getScreenShot(true);   // true = 移除 alpha
         String path = shot.toPng("screen_");     // 例如：.../screen_20260706153000.png
         Debug.log("Screenshot salvo em: " + path);

         // 如果你刚改了 UI，想要下一帧渲染后的画面：
         Image next = Main.instance.getNextScreenShot(false);  // 保留 alpha
      });
      add(LAY_AUTO, b);
   }
}
```

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

## 最小片段

```java
// 已在源码核实：Main.java getScreenShot（533、667）和 getNextScreenShot（541）
import dev.crossfly.Main;
import dev.crossfly.ui.image.Image;

// 捕获当前帧，不透明（无 alpha），并保存为 PNG：
Image shot = Main.getScreenShot(true);   // true = 移除 alpha
String path = shot.toPng("screen_");     // 例如：.../screen_20260706153000.png

// 如果你刚改了 UI，想要下一帧渲染后的画面：
Image next = Main.instance.getNextScreenShot(false);  // 保留 alpha
```

> 实现说明（源码）：
> - 捕获得到的图像的 `alreadyScreenScaled = true` 并会经过 `flipY()`（OpenGL 后台缓冲区在
>   垂直方向上是翻转的）。
> - 在 **WebGL** 平台上，`opaque=true` **不会**应用 `setOpaque()`（代码中有显式的保护判断）；
>   即便请求不透明，alpha 也会被保留。
> - `getScreenShot` 与 `Component.toImage()` 不同：这里**不**进行绘制/渲染——捕获的是
>   当前帧的后台缓冲区。
> - 对于跨平台比较（例如测试），请用
>   `Styles.setDefaultFont(Font.getFont(false, 20))` 固定字体，因为字体渲染因设备而异。

## 深入了解
- 姊妹配方：[salvar-imagem.md](/docs/cookbook/images/salvar-imagem) — 把截图保存为 PNG/JPEG。
- [自定义绘制](/docs/ui/images-and-graphics/custom-drawing) — paint thread 与 `runOnPaintThreadAndWait`。
