Image Transformations
Anvil ships an in-process image pipeline so common transforms (resize, format conversion, quality re-encode) don't need an external service. The pipeline runs on cache miss and writes the result to a content-addressed cache so repeated requests are zero copies.
Two endpoints
| Route | Auth |
|---|---|
| /storage/v1/render/image/public/{bucket}/{path} | None (bucket must be public) |
| /storage/v1/render/image/authenticated/{bucket}/{path} | Session-bound, honours RLS |
| /storage/v1/render/image/sign/{bucket}/{path} | Mint a signed render URL (transform baked into token) |
Parameters
| Param | Type | Notes |
|---|---|---|
| width | u32 | Target width in pixels |
| height | u32 | Target height in pixels |
| resize | cover | contain | fill | Fit policy |
| format | webp | jpeg | png | avif | Output encoder |
| quality | u32 1..100 | Encoder quality |
Examples
# 200x200 webp thumbnail
http://host/storage/v1/render/image/public/avatars/alice.png?width=200&height=200&resize=cover&format=webp
# Signed render URL with transform sealed into the token.
curl -X POST -H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"expires_in": 3600,
"transform": {"width": 200, "height": 200, "format": "webp"}
}' \
http://localhost:7474/storage/v1/render/image/sign/avatars/alice.pngCache
Variants are cached on disk under {cache_dir}/{source_hash}/{params_hash}. Configure cache size and limits in [file_storage.image_transforms]:
[file_storage.image_transforms] cache_dir = "./data/image_cache" max_cache_size = "2GiB" image_max_dimension = 4096 allowed_formats = ["webp", "jpeg", "png", "avif"]
Limits
Requests for dimensions over image_max_dimension return 400 - protects the renderer from accidental memory blow-ups. Disallowed output formats also 400.