anikolab / laravel-images
Responsive images for Laravel: presets, master copies, AVIF/WebP/JPEG variants on GD and one <x-picture> component for static photos and medialibrary uploads.
Requires
- php: ^8.3
- ext-exif: *
- ext-gd: *
- illuminate/console: ^13.0
- illuminate/support: ^13.0
- illuminate/view: ^13.0
Requires (Dev)
- laravel/pint: ^1.24
- orchestra/testbench: ^11.0
- phpunit/phpunit: ^12.5
- spatie/laravel-medialibrary: ^11.23
Suggests
- spatie/laravel-medialibrary: Photos uploaded in the admin panel: <x-picture :media>, queued processing, images:media
Provides
None
Conflicts
None
Replaces
None
README
Responsive images for Laravel on plain GD: presets, master copies, AVIF / WebP / JPEG variants and one <x-picture> component — for static site photos and for photos uploaded in the admin panel via spatie/laravel-medialibrary.
- Presets — aspect ratio, fixed
srcsetwidths, JPEG fallback width, defaultsizes, optional separate mobile frame (<source media>). - Master copy — rotated by EXIF Orientation, longest side capped (3200 px by default), metadata stripped. PNG sources keep transparency: AVIF and WebP keep the alpha channel, the JPEG fallback is flattened onto a background colour.
- Variants — every width is resized once and saved in every format; images are never upscaled; file names contain the actual width and a hash of the master copy and all parameters, so variants can be cached as
immutable. - Missing photo — the component renders a grey placeholder with the preset proportions and logs a warning; the page never fails.
Requirements: PHP 8.3+, Laravel 13, ext-gd (with AVIF support for AVIF output) and ext-exif.
Installation
composer require anikolab/laravel-images php artisan vendor:publish --tag=images-config
Fill config/images.php: presets for every place with a photo in your layout, the list of static photos (photos) and, if needed, admin collections (media).
Static photos
Sources stay out of git (images.sources_path). The flow:
php artisan images:master # sources from images.photos → master copies (images.masters_path) php artisan images:build # master copies → variants + manifest.json (images.output_path)
images:build rebuilds only what changed and is safe to run on every deploy. Master copies are copied to the server (e.g. rsync); missing ones produce warnings, not errors.
<x-picture photo="hero" preset="hero" alt="…" priority /> <x-picture photo="about" preset="portrait" alt="…" sizes="50vw" class="about__photo" />
priority — first screen: loading="eager" and fetchpriority="high"; otherwise lazy + decoding="async". Extra attributes go to <img>.
Admin uploads (medialibrary)
// config/images.php 'media' => [ App\Models\Work::class => ['gallery' => ['card', 'lightbox']], ],
A new media item of a listed collection is processed in the queue (run a worker): the original is replaced with a master copy, variants are stored next to it in variants/ and listed in the media custom_properties. Deleting the media removes the variants. medialibrary conversions are not used — uploads get the same quality, crop and formats as static photos.
<x-picture :media="$work->getFirstMedia('gallery')" preset="card" alt="…" />
php artisan images:media # queue media without variants (run on deploy) php artisan images:media --force # queue all, after changing presets or quality
Upload fields must use the same public disk as the collection.
Customising the markup
php artisan vendor:publish --tag=images-views
Testing
composer test
License
MIT
Кратко по-русски
Пакет обработки фото для сайтов Anikolab: пресеты, мастер-копии, варианты AVIF/WebP/JPEG на GD и один компонент <x-picture> для статичных фото и фото из админки (medialibrary). Статичные фото — images:master и images:build, фото из админки — очередь и images:media. Настройка — config/images.php.