# ImageView

> Muestra una Image con modo de escala (ImageSize) y alineación configurables.

Source: https://crossfly.dev/es/docs/ui/widgets/imageview — CrossFly documentation. Full docs as one file: https://crossfly.dev/llms-full.txt

# ImageView

`ImageView` renderiza una [`Image`](/docs/ui/images-and-graphics) dentro de los límites del componente, con el modo de escala controlado por el enum [`ImageSize`](/docs/reference) y la alineación horizontal/vertical vía `Position`. Es la forma declarativa de mostrar una imagen fija (foto, portada, logo) en un layout.

Internamente mantiene una copia **escalada en caché** (`ResizeMode.STRETCH`, `ResizeQuality.FAST`) para no redimensionar en cada frame; la caché se invalida al cambiar la imagen, el modo de escala o el tamaño.

> 🟢 · **Paquete:** `dev.crossfly.ui` · **Extiende:** `Component` · **Estilo:** `ComponentStyle` (usa `ingap` para el margen interno)

## Cuándo usar
- Mostrar una imagen fija en un layout: foto, portada, logo, avatar.
- Ajustar cómo la imagen rellena el espacio (aspect ratio, cover, stretch).

## Cuándo NO usar
- Animación por frame, escala continua variable o dibujo compuesto → haz un `Component` propio con `onPaint` llamando a `paint.image(...)` directamente (ver [`images-and-graphics/`](/docs/ui/images-and-graphics)).
- Imagen de **fondo** de otro componente → usa el `BackgroundImage` del propio `Component` (Cap. 18).

## Apariencia
La imagen se centra por defecto dentro del área interna (tras `ingap`) y se escala según el `ImageSize`:

| `ImageSize` | Comportamiento |
|---|---|
| `ORIGINAL` | tamaño natural, sin escala |
| `RATIO` | escala uniforme para **caber** dentro de los límites (letter-box) — **por defecto** |
| `FIT` | escala uniforme para **cubrir** los límites (puede recortar) |
| `STRETCH` | estira para rellenar exactamente (ignora aspect ratio) |
| `FIT_WIDTH` / `FIT_HEIGHT` | ajusta al ancho / al alto, manteniendo la proporción |
| `FIT_HALF_WIDTH` / `FIT_HALF_HEIGHT` | ajusta a la mitad del ancho / alto |

``

## Ejemplo completo (copiar, pegar y ejecutar)
```java
package com.exemplo;

import dev.crossfly.ui.*;
import dev.crossfly.ui.layout.*;
import dev.crossfly.ui.image.*;   // Image, ImageException

/** Pantalla principal ejecutable. Apunta el launcher (classname) y corre: gradlew :lwjgl3:run */
public class MainWindow extends Window
{
   @Override
   public void onShow() throws Exception
   {
      super.onShow();
      setLayout(new VerticalLayout());

      // Cargar una Image puede lanzar ImageException/IOException — manéjelo para no romper la pantalla.
      ImageView iv = new ImageView();          // vacío (placeholder: no se dibuja nada)
      try {
         Image capa = new Image("cf/samples/api/ui/books/book1.png");
         iv.image(capa).imageSize(ImageSize.RATIO);
      } catch (ImageException e) {
         System.out.println("Imagem não encontrada, usando placeholder vazio: " + e.getMessage());
      }

      add(LAY_FILL, iv);
   }
}
```

> Los fragmentos siguientes muestran **solo el núcleo** (lo que va dentro de `onShow()`). Para ejecutar, colócalos en el esqueleto `MainWindow` de arriba.

## Uso básico
```java
Image capa = new Image("cf/samples/api/ui/books/book1.png");
ImageView iv = new ImageView(capa, ImageSize.RATIO);
container.add(LAY_FILL, iv);
```

## Constructores
| Constructor | Descripción |
|---|---|
| `ImageView()` | vacío (`image = null`, `ImageSize.RATIO`) |
| `ImageView(Image image)` | imagen con modo `RATIO` |
| `ImageView(Image image, ImageSize imageSize)` | imagen + modo de escala |

## Propiedades y personalización
| Propiedad / método | Tipo | Por defecto | Qué hace |
|---|---|---|---|
| `image(Image)` | `ImageView` (fluido) | `null` | cambia la imagen (invalida caché/layout) |
| `imageSize(ImageSize)` | `ImageView` (fluido) | `RATIO` | define el modo de escala |
| `alignX(Position)` | `ImageView` (fluido) | `CENTER` | alineación horizontal (`START`/`CENTER`/`END`) |
| `alignY(Position)` | `ImageView` (fluido) | `CENTER` | alineación vertical |
| `getImage()` | `Image` | — | imagen actual (o `null`) |
| `getImageSize()` | `ImageSize` | — | modo actual |
| `getAutoWidth()` / `getAutoHeight()` | `int` | — | tamaño de la imagen + `ingap` (0 si no hay imagen) |

## Callbacks y eventos
Ninguno. `ImageView` no es interactivo.

## Estados
Sin estados de interacción. Si `image == null`, no se dibuja nada.

### Cover (recorte) con alineación arriba
```java
Image foto = new Image(caminhoFoto);
ImageView avatar = new ImageView(foto, ImageSize.FIT)
   .alignY(Position.START);      // mantiene el tope visible al recortar
container.add(0.4f, avatar);
```

### Cambiar la imagen en runtime (fluido)
```java
ImageView iv = new ImageView();          // vacío
container.add(LAY_FILL, iv);
// luego, al cargar:
iv.image(new Image(novoCaminho))
  .imageSize(ImageSize.STRETCH);
```

## Buenas prácticas
- Dale al `ImageView` un espacio de layout definido (`LAY_FILL` o fracción) — el modo de escala solo tiene sentido con límites conocidos.
- Libera la `Image` con `dispose()` cuando ya no se use (recurso nativo — ver Cap. 18).
- En Web, prefiere `ResizeQuality.FAST`; la escala interna del `ImageView` ya usa ese camino.

## Errores comunes
- **Confundir `FIT` con `RATIO`:** `RATIO` hace letter-box (cabe entera); `FIT` cubre y puede recortar. `STRETCH` distorsiona.
- **Esperar tamaño automático de un `ImageView` sin imagen:** `getAutoWidth/Height()` devuelven `0` cuando `image == null`.

## Ver también
- Guía del área: [`ui/`](/docs/ui) · Recetas: [`cookbook/`](/docs/cookbook)
- Concepto (imágenes, `Paint.image`): [`concepts/`](/docs/concepts)
- Componentes relacionados: [`Label`](/docs/ui/widgets/label) · [`Button`](/docs/ui/widgets/button)
