163 lines
5.3 KiB
Markdown
163 lines
5.3 KiB
Markdown
# Image Optimization
|
||
|
||
The package provides on-the-fly image resizing with caching, WebP conversion, and configurable quality. Requires `spatie/image`.
|
||
|
||
## Requirements
|
||
|
||
```bash
|
||
composer require spatie/image "^3.8"
|
||
```
|
||
|
||
If `spatie/image` is not installed, all resizing calls gracefully return the original file path.
|
||
|
||
---
|
||
|
||
## Resizing via URL
|
||
|
||
When serving images through the [Warehouse](serving-files.md), append query parameters:
|
||
|
||
```
|
||
/warehouse/{id}?size=300x200
|
||
/warehouse/{id}?size=400&quality=90
|
||
/warehouse/{id}?size=800x600&webp=false&position=contain
|
||
```
|
||
|
||
### Query Parameters
|
||
|
||
| Param | Type | Default | Description |
|
||
|------------|----------|---------|---------------------------------------------------------------------------------------------|
|
||
| `size` | `string` | — | Dimensions as `WIDTHxHEIGHT` (e.g. `300x200`). Use a single number for square (e.g. `300`). |
|
||
| `quality` | `int` | `85` | JPEG/WebP quality (1–100) |
|
||
| `webp` | `bool` | `true` | Convert output to WebP |
|
||
| `position` | `string` | `cover` | Fit mode: `cover`, `contain`, `fill`, `max`, `stretch` |
|
||
| `cached` | `bool` | `true` | Use cached resize if available |
|
||
| `rounding` | `bool` | `true` | Round dimensions to nearest step |
|
||
|
||
---
|
||
|
||
## Resizing Programmatically
|
||
|
||
Use the `resizedPath()` method to generate a resized variant:
|
||
|
||
```php
|
||
$path = $file->resizedPath(
|
||
width: 300,
|
||
height: 200,
|
||
toWebp: true,
|
||
quality: 85,
|
||
position: 'cover',
|
||
);
|
||
```
|
||
|
||
### Parameters
|
||
|
||
| Parameter | Type | Default | Description |
|
||
|-------------|---------------------|-----------|-----------------------------------------------|
|
||
| `$width` | `string\|int\|null` | — | Target width. Use `'auto'` for proportional. |
|
||
| `$height` | `string\|int\|null` | — | Target height. Use `'auto'` for proportional. |
|
||
| `$rounding` | `bool` | `true` | Round to nearest step (default: 50px) |
|
||
| `$toWebp` | `bool` | `true` | Convert to WebP format |
|
||
| `$cached` | `bool` | `true` | Return cached version if available |
|
||
| `$quality` | `?int` | `null` | Quality (1–100). `null` uses config default. |
|
||
| `$position` | `string` | `'cover'` | Fit mode |
|
||
|
||
The method returns an absolute file path to the resized image.
|
||
|
||
---
|
||
|
||
## Fit Modes
|
||
|
||
| Mode | Behavior |
|
||
|-----------|------------------------------------------------|
|
||
| `cover` | Crop to fill exact dimensions (default) |
|
||
| `contain` | Fit within dimensions, preserving aspect ratio |
|
||
| `fill` | Fill dimensions, padding if necessary |
|
||
| `max` | Resize within dimensions, no upscaling |
|
||
| `stretch` | Stretch to exact dimensions |
|
||
|
||
---
|
||
|
||
## Caching
|
||
|
||
Resized images are cached on disk in a `resized/` subdirectory next to the original:
|
||
|
||
```
|
||
files/2024/06/15/abc-123 ← original
|
||
files/2024/06/15/resized/
|
||
abc-123.300x200.jpg.webp ← resized variant
|
||
abc-123.800x600.contain.q90.jpg ← another variant
|
||
```
|
||
|
||
Cache key components: `{width}x{height}`, `.{position}` (if not cover), `.q{quality}` (if not default). Requesting the same size again serves from cache instantly.
|
||
|
||
When a file is deleted, all resized variants are cleaned up automatically.
|
||
|
||
---
|
||
|
||
## Dimension Rounding
|
||
|
||
To reduce cache fragmentation, dimensions are rounded **up** to the nearest step (default: 50px):
|
||
|
||
| Requested | Rounded to |
|
||
|-----------|------------|
|
||
| `280x180` | `300x200` |
|
||
| `310x310` | `350x350` |
|
||
| `50x50` | `50x50` |
|
||
|
||
Configure the step size:
|
||
|
||
```php
|
||
// config/files.php
|
||
'optimization' => [
|
||
'round_to' => 100, // round to nearest 100px
|
||
],
|
||
```
|
||
|
||
Disable rounding per request with `?rounding=false` or `rounding: false`.
|
||
|
||
---
|
||
|
||
## Skipped Formats
|
||
|
||
Some formats cannot be processed by image libraries and are served as-is:
|
||
|
||
```php
|
||
'optimization' => [
|
||
'skip_formats' => ['gif', 'svg', 'svg+xml'],
|
||
],
|
||
```
|
||
|
||
---
|
||
|
||
## Preferred Extensions (Asset Auto-Resolution)
|
||
|
||
When the warehouse receives a path without an extension (e.g. `/warehouse/images/logo`), it tries these extensions in order:
|
||
|
||
```php
|
||
'optimization' => [
|
||
'preferred_extensions' => ['svg', 'webp', 'png', 'jpg', 'jpeg'],
|
||
],
|
||
```
|
||
|
||
---
|
||
|
||
## Configuration Reference
|
||
|
||
All optimization settings in `config/files.php`:
|
||
|
||
```php
|
||
'optimization' => [
|
||
'enabled' => true,
|
||
'default_quality' => 85, // default JPEG/WebP quality
|
||
'webp_conversion' => true, // convert to WebP by default
|
||
'round_dimensions' => true, // round sizes to reduce cache variants
|
||
'round_to' => 50, // rounding step in pixels
|
||
'skip_formats' => ['gif', 'svg', 'svg+xml'],
|
||
'preferred_extensions' => ['svg', 'webp', 'png', 'jpg', 'jpeg'],
|
||
],
|
||
```
|
||
|
||
---
|
||
|
||
Next: [Configuration](configuration.md)
|