# ImageView

> Displays an Image with configurable scale mode (ImageSize) and alignment.

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

# ImageView

`ImageView` renders an [`Image`](/docs/ui/images-and-graphics) within the component's bounds, with the scale mode controlled by the [`ImageSize`](/docs/reference) enum and horizontal/vertical alignment via `Position`. It is the declarative way to show a fixed image (photo, cover, logo) in a layout.

Internally it keeps a **cached scaled** copy (`ResizeMode.STRETCH`, `ResizeQuality.FAST`) so it does not resize every frame; the cache is invalidated when the image, the scale mode or the size changes.

> 🟢 · **Package:** `dev.crossfly.ui` · **Extends:** `Component` · **Style:** `ComponentStyle` (uses `ingap` for internal margin)

## When to use
- Display a fixed image in a layout: photo, cover, logo, avatar.
- Adjust how the image fills the space (aspect ratio, cover, stretch).

## When NOT to use
- Per-frame animation, continuously varying scale or composite drawing → make your own `Component` with `onPaint` calling `paint.image(...)` directly (see [`images-and-graphics/`](/docs/ui/images-and-graphics)).
- **Background** image of another component → use the `Component`'s own `BackgroundImage` (Ch. 18).

## Appearance
The image is centered by default within the internal area (after `ingap`) and scaled according to `ImageSize`:

| `ImageSize` | Behavior |
|---|---|
| `ORIGINAL` | natural size, no scaling |
| `RATIO` | uniform scale to **fit** within the bounds (letter-box) — **default** |
| `FIT` | uniform scale to **cover** the bounds (may crop) |
| `STRETCH` | stretches to fill exactly (ignores aspect ratio) |
| `FIT_WIDTH` / `FIT_HEIGHT` | fits to the width / height, keeping proportion |
| `FIT_HALF_WIDTH` / `FIT_HALF_HEIGHT` | fits to half the width / height |

``

## Complete example (copy, paste and run)
```java
package com.exemplo;

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

/** Runnable main screen. Point the launcher (classname) and run: gradlew :lwjgl3:run */
public class MainWindow extends Window
{
   @Override
   public void onShow() throws Exception
   {
      super.onShow();
      setLayout(new VerticalLayout());

      // Loading an Image can throw ImageException/IOException — handle it so the screen doesn't break.
      ImageView iv = new ImageView();          // empty (placeholder: nothing is drawn)
      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);
   }
}
```

> The snippets below show **only the core** (what goes inside `onShow()`). To run them, place them in the `MainWindow` skeleton above.

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

## Constructors
| Constructor | Description |
|---|---|
| `ImageView()` | empty (`image = null`, `ImageSize.RATIO`) |
| `ImageView(Image image)` | image with `RATIO` mode |
| `ImageView(Image image, ImageSize imageSize)` | image + scale mode |

## Properties and customization
| Property / method | Type | Default | What it does |
|---|---|---|---|
| `image(Image)` | `ImageView` (fluent) | `null` | swaps the image (invalidates cache/layout) |
| `imageSize(ImageSize)` | `ImageView` (fluent) | `RATIO` | sets the scale mode |
| `alignX(Position)` | `ImageView` (fluent) | `CENTER` | horizontal alignment (`START`/`CENTER`/`END`) |
| `alignY(Position)` | `ImageView` (fluent) | `CENTER` | vertical alignment |
| `getImage()` | `Image` | — | current image (or `null`) |
| `getImageSize()` | `ImageSize` | — | current mode |
| `getAutoWidth()` / `getAutoHeight()` | `int` | — | image size + `ingap` (0 if no image) |

## Callbacks and events
None. `ImageView` is non-interactive.

## States
No interaction states. If `image == null`, nothing is drawn.

### Cover (crop) with top alignment
```java
Image foto = new Image(caminhoFoto);
ImageView avatar = new ImageView(foto, ImageSize.FIT)
   .alignY(Position.START);      // keeps the top visible when cropping
container.add(0.4f, avatar);
```

### Swap the image at runtime (fluent)
```java
ImageView iv = new ImageView();          // empty
container.add(LAY_FILL, iv);
// later, on load:
iv.image(new Image(novoCaminho))
  .imageSize(ImageSize.STRETCH);
```

## Best practices
- Give the `ImageView` a defined layout space (`LAY_FILL` or a fraction) — the scale mode only makes sense with known bounds.
- Release the `Image` with `dispose()` when it is no longer used (native resource — see Ch. 18).
- On the Web, prefer `ResizeQuality.FAST`; the `ImageView`'s internal scaling already uses that path.

## Common mistakes
- **Confusing `FIT` with `RATIO`:** `RATIO` does letter-box (fits entirely); `FIT` covers and may crop. `STRETCH` distorts.
- **Expecting automatic sizing from an `ImageView` without an image:** `getAutoWidth/Height()` return `0` when `image == null`.

## See also
- Area guide: [`ui/`](/docs/ui) · Recipes: [`cookbook/`](/docs/cookbook)
- Concept (images, `Paint.image`): [`concepts/`](/docs/concepts)
- Related components: [`Label`](/docs/ui/widgets/label) · [`Button`](/docs/ui/widgets/button)
