# Como salvar uma imagem em PNG ou JPEG

> Gravar uma Image em disco (arquivo com timestamp) ou em um OutputStream, em PNG ou JPEG.

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

# Como salvar uma imagem em PNG ou JPEG

**Propósito.** Persistir uma `Image` em disco. O CrossFly oferece dois níveis: *conveniência*
(salva um arquivo com nome por timestamp e retorna o caminho) e *controle total* (você fornece o
`OutputStream`).

### Conveniência (salva arquivo automaticamente)
- `String toPng(String... prefix)` — salva um PNG com nome `<prefix><timestamp>.png`. No desktop grava em `Device.homeFolder`; em mobile grava em `/sdcard/`. Retorna o caminho salvo, ou `null` em caso de erro (o erro é tratado internamente via `Debug.handle`). O `prefix` é **opcional**.
- `String toJpg(int... quality)` — salva um JPEG com nome por timestamp. `quality` é **opcional** (default `90`); `100` = sem compressão, `85` = boa compressão, `60` = grande compressão mas com ruído. Retorna o caminho, ou `null` em erro.

### Controle total (você fornece o stream)
- `void toPng(OutputStream s) throws ImageException, IOException` — grava o PNG no stream. O PNG é 24 BPP, ou 32 BPP se a imagem tiver canal alpha.
- `void toJpg(OutputStream s, int quality) throws ImageException, IOException` — grava o JPEG no stream com a qualidade dada (0–100). **O stream é fechado** pela chamada.

> Atenção às sobrecargas: `toPng(String...)`/`toJpg(int...)` **salvam um arquivo** e engolem exceções
> (retornam `null`). Já `toPng(OutputStream)`/`toJpg(OutputStream,int)` **propagam**
> `ImageException`/`IOException`. Escolha conforme quer ou não tratar o erro.

## Exemplo completo (copiar, colar e rodar)

```java
package com.exemplo;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;

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

/** 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 img = new Image("/sdcard/foto.jpg");   // sua imagem já carregada ou gerada

         // 1) Conveniência: arquivo com timestamp; retorna o caminho
         String pngPath = img.toPng("thumb_");   // ex.: .../thumb_20260706153000.png
         String jpgPath = img.toJpg(85);         // qualidade 85
         Debug.log("PNG: " + pngPath + " | JPG: " + jpgPath);

         // 2) Controle total: você decide o destino e trata erros
         try (OutputStream out = new FileOutputStream("/sdcard/saida.png")) {
            img.toPng(out);                      // stream é fechado pela chamada; propaga exceções
         } catch (ImageException | IOException e) {
            // trate falha de escrita/codificação
         }
      } catch (ImageException | IOException e) {
         // falha ao carregar a imagem de origem
      }
   }
}
```

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

## Trecho mínimo

```java
// verificado na fonte: Image.java toPng/toJpg — linhas 800, 811, 1454, 1479
import dev.crossfly.ui.image.*;   // Image, ImageException

Image img = /* sua imagem já carregada ou gerada */;

// 1) Conveniência: arquivo com timestamp; retorna o caminho
String pngPath = img.toPng("thumb_");   // ex.: .../thumb_20260706153000.png
String jpgPath = img.toJpg(85);         // qualidade 85

// 2) Controle total: você decide o destino e trata erros
try (java.io.OutputStream out = new java.io.FileOutputStream("/sdcard/saida.png")) {
   img.toPng(out);                      // stream é fechado pela chamada; propaga exceções
} catch (ImageException | java.io.IOException e) {
   // trate falha de escrita/codificação
}
```

## Aprofunde-se
- Receita irmã: [thumbnail.md](/docs/cookbook/images/thumbnail) — gere o thumbnail e depois salve com esta receita.
- Receita irmã: [screenshot.md](/docs/cookbook/images/screenshot) — capture a tela e salve com `toPng()`.
