# Como tirar uma foto e obter o caminho do arquivo

> Capturar uma foto com a câmera do dispositivo e receber o caminho do JPEG salvo.

Source: https://crossfly.dev/pt/docs/cookbook/device/tirar-foto — CrossFly documentation. Full docs as one file: https://crossfly.dev/llms-full.txt

# Como tirar uma foto e obter o caminho do arquivo

**Propósito.** Abrir a câmera, tirar uma foto e receber o **caminho do arquivo JPEG** gravado.
A forma recomendada é usar `Camera` com `cameraType = CameraType.PICKER`, que por baixo abre o
`PhotoPicker` (a UI de captura do próprio framework) e retorna o caminho — ou `null` se cancelado.

## APIs usadas
- `Camera` — construtor sem argumentos; campos públicos `cameraType` (`CameraType`), `captureMode` (`Preview`, default `PHOTO`), `videoQuality` (`AVQuality`), `videoTimeLimit`.
- `Camera.shot()` → `String` — tira a foto/vídeo conforme os campos e retorna o **caminho do arquivo** ou `null` (cancelado, erro, ou macOS ARM). **Não existe** método `click()`.
- `CameraType` (enum) — `DEFAULT` (câmera nativa do SO), `PICKER` (UI do CrossFly via `PhotoPicker`), `GALLERY` (escolher da galeria).
- `PhotoPicker(Preview type)` — usado internamente por `shot()` quando `cameraType == PICKER`; expõe `getAnswer()` (caminho ou string de erro) e `isError()`. `Camera.shot()` já converte erro em `null` para você.

> **Divergência/nota de honestidade.** `PhotoPicker` **não** é abstrato e **não** usa callback
> `onAnswer`: ele grava o resultado em `getAnswer()` e sinaliza falha em `isError()`. `Camera.shot()`
> encapsula esse fluxo (`show()` → lê `getAnswer()` → `isError() ? null : ret`), então prefira `shot()`.
> No iOS, quando `captureMode != PHOTO`, `shot()` delega direto para a câmera nativa do SO.

## Exemplo completo (copiar, colar e rodar)

```java
package com.exemplo;

import dev.crossfly.ui.*;                   // Window, Component, Button, Label, UIConstants
import dev.crossfly.ui.layout.*;            // VerticalLayout
import dev.crossfly.device.*;               // Camera

/** 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());

      Label resultado = new Label("");
      add(LAY_AUTO, resultado);

      Button acao = new Button("Tirar foto");
      acao.onAction(c ->
      {
         // shot() é bloqueante enquanto o picker está aberto; rode fora da paint thread.
         new Thread(() ->
         {
            Camera cam = new Camera();
            cam.cameraType  = UIConstants.CameraType.PICKER;   // UI de captura do CrossFly
            cam.captureMode = UIConstants.Preview.PHOTO;       // foto (default)

            String path = cam.shot();                          // caminho do JPEG, ou null se cancelado/erro

            // O retorno chega FORA da paint thread → volte à UI com onUI(...)
            Component.onUI(() ->
               resultado.setText(path != null ? "Foto: " + path : "Cancelado ou erro"));
         }).start();
      });
      add(LAY_AUTO, acao);
   }
}
```

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

## Trecho mínimo

```java
// verificado na fonte: Camera.java shot() (linhas 75-91); PhotoPicker.java (constructor + getAnswer/isError)
import dev.crossfly.device.*;              // Camera
import dev.crossfly.ui.*;                  // Component (onUI), UIConstants.CameraType/Preview

// shot() é bloqueante enquanto o picker está aberto; rode fora da paint thread.
new Thread(() -> {
   Camera cam = new Camera();
   cam.cameraType  = UIConstants.CameraType.PICKER;   // UI de captura do CrossFly
   cam.captureMode = UIConstants.Preview.PHOTO;       // foto (default)

   String path = cam.shot();                          // caminho do JPEG, ou null se cancelado/erro

   // O retorno chega FORA da paint thread → volte à UI com onUI(...)
   Component.onUI(() -> {
      if (path != null)
         mostrarFoto(path);   // ex.: carregar a Image e exibir num ImageView
      // else: usuário cancelou ou houve erro de câmera
   });
}).start();
```

## Aprofunde-se
- Guia da câmera: [Câmera do dispositivo](/docs/data-and-services/device-camera) · Widget: [PhotoPicker](/docs/ui/widgets/photopicker)
- Receita irmã: [gravar-video.md](/docs/cookbook/device/gravar-video) · [ler-codigo-de-barras.md](/docs/cookbook/device/ler-codigo-de-barras)
