reliqarts/laravel-guided-image
Laravel package for guided, responsive image handling: generate and serve optimized image variants with an intuitive API. Handles resizing, caching, and responsive delivery so your Laravel app stays fast without extra config.
v5.0.0 requirements first: Laravel 11+ (which means PHP 8.2+) and Intervention Image v3. If you're on Laravel 10 or PHP 8.1, stay on the 4.x line. Confirm with:
composer require reliqarts/laravel-guided-image:^5.0
php artisan vendor:publish --tag=guided-image-config # check the tag in the package README
Where to look first:
config/guided-image.php — this is the package's real API. Guides (named presets) are declared here as arrays of dimensions + manipulation method. Everything else is a thin call site on top of that config.src/ directory (or README) for the current entry point — v5 changed the underlying engine, so re-check the facade/helper name and the guide-invocation signature rather than copying v4 snippets.Intervention\Image\ImageManager docs for v3 — the package now delegates to it, so driver behaviour (gd vs imagick) is effectively your responsibility.First use case: define one guide for a thumbnail and one for a hero image, then generate a derivative from a stored upload:
// config/guided-image.php
'guides' => [
'thumb' => ['width' => 200, 'height' => 200, 'method' => 'crop'],
'hero' => ['width' => 1600, 'height' => 900, 'method' => 'fit'],
],
Then invoke the guide by name against the source path and persist the result wherever you normally store uploads. Keep the guide name in your database (a logo_guide column, or a media row), never the pixel dimensions — that's the whole point of the package.
Config-as-schema. Treat guided-image.php as versioned application schema: one guide per real UI slot (avatar-sm, og-image, product-card), named after the slot rather than the size. Reviewers can then grep a template for product-card and know exactly which crop is in play.
Model/upload integration. The common workflow is a Photo/Media-style model with a storeUpload() action that (a) saves the original to a disk, (b) loops over the guides the entity needs, (c) writes each derivative next to the original with a deterministic filename ({basename}-{guide}.{ext}), (d) records guide + path rows. Avoid generating derivatives in an accessor — that turns a read into a write and will bite you under load.
Queue it. For anything above ~1–2 MP, dispatch a job per guide. This gives you retries, isolates max_execution_time, and keeps upload requests fast. In tests use Bus::fake() / Queue::fake().
Two-tier guides. Define small guides synchronously at upload (avatar, admin thumb) and let large/OG/social guides run on the queue. This is the single biggest perceived-performance win.
Re-generation command. Add php artisan images:regenerate {--guide=} that re-runs a guide over all existing originals. You will change a guide's dimensions eventually, and without this you're stuck with mixed aspect ratios in production.
Testing. Storage::fake('public') plus a small fixture PNG; assert file existence and dimensions with getimagesize(). Do not assert byte-for-byte output — Intervention v3 encoders differ by driver and version.
Blade/Inertia surface. Wrap derivative lookup in one helper (image_url($model, 'thumb')) so a missing derivative falls back to the original rather than 404-ing.
Image::make(), ->fit(), ->resize($w, null, callback) with the v2 constraint-callback style) must be rewritten to the v3 API (resize(), scale(), cover(), contain(), explicit ImageManager instance). The package's config-driven guides survive; your custom manipulation code does not.gd or imagick). Verify ext-gd (with WebP/AVIF support if you need it) or ext-imagick is installed in every environment, including CI and the queue worker container. A missing driver fails at runtime, not install time.php artisan config:cache in deploy means guide changes need a cache clear. Add it to your deploy script, not your memory.memory_limit. Set a sane max_upload_dimension guard before processing and reject oversized images at validation.?v={updated_at}.How can I help you explore Laravel packages today?