---
title: "Processors"
manual: "Imaginator"
version: "main"
permalink: "https://docs.typo3.org/permalink/schliesser/imaginator:configuration-processors@main"
source: "Configuration/Processors.rst"
rendered: "2026-10-13T11:21:46+00:00"
---

# Processors {#configuration-processors}

The [processor](https://docs.typo3.org/permalink/schliesser/imaginator:confval-conf-processor@main) setting selects who turns the source
file into the derivatives that land in `srcset`. Both local modes drive
TYPO3's `ImageService` exclusively (the binary is whatever your `GFX` config
selects — GraphicsMagick or ImageMagick); there are no direct
GraphicsMagick/ImageMagick/GD calls.

-   **`local:async` (default)**

    Processing is deferred to the first request per variant: a cold `srcset`
    candidate points at the signed `/_imaginator/` endpoint and the middleware
    materializes the derivative, then 302-redirects to the processed file. Once a
    derivative exists, `srcset` points at the static `_processed_/…` file
    directly, so warm images skip the middleware entirely.

-   **`local:sync`**

    Files are processed synchronously at first render time and the static
    `_processed_/…` file URL is written straight into `srcset`. Just like
    the TYPO3 core processes files on first page load if `<f:image>` is used.
    The middleware is never involved and requests are plain static-file serves.

-   **`imgproxy`**

    Offloaded; `srcset` points straight at the provider (see
    [Offloaded processing with imgproxy](https://docs.typo3.org/permalink/schliesser/imaginator:configuration-imgproxy@main)). imgproxy has no result cache — a fronting
    CDN / reverse-proxy cache is **mandatory** in production.

-   **`imagor`**

    Offloaded; `srcset` points straight at the provider (see
    [Offloaded processing with imagor](https://docs.typo3.org/permalink/schliesser/imaginator:configuration-imagor@main)). Enable imagor's result storage (or put a
    fronting cache in front) so derivatives are rendered once, not per hit.

> [!TIP]
> Integrators can register a **custom processor** by putting
> `#[AsImaginatorProcessor('my-key')]` on their class (a plain URL
> builder is enough for a new CDN provider) and selecting it here — no YAML.
> See [Custom Processor](https://docs.typo3.org/permalink/schliesser/imaginator:extend-custom-processor@main).

## The image endpoint & signing {#image-endpoint}

In `local:async` mode each candidate URL has one of these forms:

**Signed candidate URLs**

```text
reference: /_imaginator/{16-hex-signature}/r{referenceUid}/{cropVariant}/{width}x{height}.{ext}
file:      /_imaginator/{16-hex-signature}/f{fileUid}/{cropVariant}/{width}x{height}.{ext}
```

The uid is site-unique, so no storage segment is needed. A PSR-15 middleware
verifies the signature, re-checks the width against the
[ladder](https://docs.typo3.org/permalink/schliesser/imaginator:confval-conf-ladder@main), processes the image and **302-redirects to the
processed file** with `Cache-Control: public, max-age=31536000,
immutable`.

> [!NOTE]
> A forged or tampered URL returns **403**, and only ladder-quantized widths
> are ever processed — so the endpoint cannot be abused to exhaust the server
> with arbitrary sizes.

The signing secret is derived automatically from the global
`encryptionKey`; no configuration is needed. See [Signing](https://docs.typo3.org/permalink/schliesser/imaginator:configuration-signing@main),
and [Crop & Focus Area](https://docs.typo3.org/permalink/schliesser/imaginator:image-endpoint-crop@main) for how the editor's crop is
honoured server-side.

## Offloaded processing with imgproxy {#configuration-imgproxy}

With [processor](https://docs.typo3.org/permalink/schliesser/imaginator:confval-conf-processor@main) set to `imgproxy`, `srcset` URLs
point straight at an [imgproxy](https://imgproxy.net/) service, the webserver
never touches pixels, and the signed `/_imaginator/` endpoint is unused. Each
candidate is built as:

```php
{processorBaseUrl}/{signature}/rs:fill:{w}:{h}/g:sm/q:{quality}/plain/{source}@{ext}

```

For a **reference with a stored crop or focus area** the editor's crop variant
is replayed externally: the same ratio-fitted, focus-positioned rect local
processing uses goes into imgproxy's crop op (`c:{cw}:{ch}:nowe:{x}:{y}`,
replacing `g:sm`), so external output matches local output. Plain files and
references without editor crop use smart gravity.

Offloading also sidesteps local encoder limits: e.g. AVIF at large dimensions
that a thin GraphicsMagick build fails to encode.

> [!TIP]
> For local development, the [ddev-imgproxy](https://github.com/barbieswimcrew/ddev-imgproxy) add-on runs imgproxy
> next to the web container:
>
> ```bash
> ddev add-on get barbieswimcrew/ddev-imgproxy
> ddev restart
> ```
>
> It sets `IMGPROXY_BASE_URL` to the web container and runs keyless, so
> [processorBaseUrl](https://docs.typo3.org/permalink/schliesser/imaginator:confval-conf-processorbaseurl@main) is the add-on URL
> (`https://<project>.ddev.site:8081`) and the sign key/salt stay empty.

## Offloaded processing with imagor {#configuration-imagor}

With [processor](https://docs.typo3.org/permalink/schliesser/imaginator:confval-conf-processor@main) set to `imagor`, `srcset` URLs
point straight at an [imagor](https://imagor.net/) service (thumbor-compatible
URL grammar). Each candidate is built as:

```php
{processorBaseUrl}/{signature}/{w}x{h}/smart/filters:quality({q}):format({ext})/{source}

```

The signature is a URL-safe base64 HMAC of the path, keyed with
[processorSignKey](https://docs.typo3.org/permalink/schliesser/imaginator:confval-conf-processorsignkey@main) — imagor's plain-string
`IMAGOR_SECRET` (run imagor with `IMAGOR_SIGNER_TYPE=sha256`).
[processorSalt](https://docs.typo3.org/permalink/schliesser/imaginator:confval-conf-processorsalt@main) is unused; imagor's scheme has no
salt. An empty key emits `unsafe` URLs, which imagor only accepts with
`IMAGOR_UNSAFE=1` (dev only). As with imgproxy, a reference's stored editor
crop is replayed externally, the crop rect becomes imagor's manual crop segment
(`{x1}x{y1}:{x2}x{y2}`, replacing `smart`); plain files and references
without editor crop fall back to `smart` detection.

Unlike the edge-cached SaaS providers, imagor caches derivatives **only when
result storage is enabled** (`FILE_RESULT_STORAGE_BASE_DIR` or the S3
equivalent). Enable it or front imagor with a CDN / reverse-proxy cache,
otherwise every browser hit reprocesses the image.

> [!TIP]
> For local development this repository ships
> `.ddev/docker-compose.imagor.yaml`: imagor listens on
> `https://<project>.ddev.site:8083` with the secret
> `imaginator-dev-secret` and result storage on a volume — so
> [processorBaseUrl](https://docs.typo3.org/permalink/schliesser/imaginator:confval-conf-processorbaseurl@main) is that URL and
> [processorSignKey](https://docs.typo3.org/permalink/schliesser/imaginator:confval-conf-processorsignkey@main) the dev secret.
