# Transform images

Image operations change pixels or geometry. Metadata policies are documented
separately under [Safety](https://altophp.com/image/safety.md).

## Choose a resizing operation

The same 768 by 432 source produces these outputs for a 320 by 240 box:

| Operation | Result | Use when |
| --- | --- | --- |
| [Cover](transform/cover.md) | 320 x 240, cropped | The frame must be filled |
| [Contain](transform/contain.md) | 320 x 240, padded | The entire source and fixed frame matter |
| [Fit](transform/fit.md) | 320 x 180 | Keep the whole source with no padding |
| [Resize outside](transform/resize.md) | 427 x 240 | Preserve ratio while covering the minimum dimensions |

| Cover | Contain | Fit |
| --- | --- | --- |
| ![Cropped cover](assets/examples/cover.png) | ![Padded contain](assets/examples/contain.png) | ![Ratio-preserving fit](assets/examples/fit.png) |

Geometry and encoding are separate: selecting WebP or JPEG does not select a
resize policy. The linked guides show the shared source, exact options, and
actual outputs. Smaller inputs are not enlarged by default.

## Resize

- [Cover](https://altophp.com/image/transform/cover.md)
- [Contain](https://altophp.com/image/transform/contain.md)
- [Fit](https://altophp.com/image/transform/fit.md)
- [Scale](https://altophp.com/image/transform/scale.md)
- [Stretch](https://altophp.com/image/transform/stretch.md)
- [Resize](https://altophp.com/image/transform/resize.md)

## Geometry

- [Crop](https://altophp.com/image/transform/crop.md)
- [Extend](https://altophp.com/image/transform/extend.md)
- [Trim](https://altophp.com/image/transform/trim.md)
- [Rotate](https://altophp.com/image/transform/rotate.md)
- [Flip](https://altophp.com/image/transform/flip.md)
- [Orient](https://altophp.com/image/transform/orient.md)

## Composition

- [Flatten](https://altophp.com/image/transform/flatten.md)
- [Overlay](https://altophp.com/image/transform/overlay.md)

## Effects

- [Blur](https://altophp.com/image/transform/blur.md)
- [Sharpen](https://altophp.com/image/transform/sharpen.md)
- [Adjust](https://altophp.com/image/transform/adjust.md)
- [Grayscale](https://altophp.com/image/transform/grayscale.md)
- [Invert](https://altophp.com/image/transform/invert.md)
- [Pixelate](https://altophp.com/image/transform/pixelate.md)
- [Tint](https://altophp.com/image/transform/tint.md)

## Colour

- [Convert a colour profile](https://altophp.com/image/transform/colour-profile.md)

Every method returns a new `Image` or `ImageSet`. The source is unchanged.
Drivers can report an approximate result through `Result::$degradations`.

## Inspect a request

An `Image` is one immutable source and one requested output. Before rendering,
use `sourceSize()` and `sourceMetadata()` for the original or `size()` and
`metadata()` for the projected result. `transform()` returns the ordered
operations; `signature()` returns the stable derivative identity.

Terminal methods perform the work: `render()` returns a `Result`, `save()`
writes one caller-selected path, and `store()` uses a derivative store.
`bytes()` and `dataUri()` are in-memory conveniences. Pixel decoding remains
deferred until a terminal method or analyzer needs it.

## Custom operations

An executable operation implements `OperationInterface`. A portable operation
also implements `PortableOperationInterface` so it can project geometry, parse
arguments, and serialize to a stable transform string. Geometry operations may
implement `Solvable` and return a resolved `Placement`.

Apply a custom operation with `apply()`. Use `escape()` only for trusted,
driver-specific code, and provide a stable identity whenever its output affects
cache keys. Parse untrusted transform strings with an explicit allowlist:

```php
use Alto\Image\Transform;

$transform = Transform::parse($value, only: ['cover', 'crop', 'sharpen']);
```

Exclude `overlay` unless referenced paths are constrained independently.
