Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Image Bundle Laravel Package

kaliop/image-bundle

Kaliop ImageBundle is a Symfony bundle for managing and serving images, integrating with LiipImagineBundle to generate filtered variations and thumbnails. It provides image storage, upload handling, Twig helpers, and a simple API for cached image URLs and variations.

View on GitHub
Deep Wiki
Context7

Getting Started

This is a Symfony bundle (kaliop/image-bundle), not a native Laravel package, so treat it as "Symfony component glue inside Laravel" rather than a php artisan vendor:publish-style install. Budget for a thin integration layer.

  1. composer require kaliop/image-bundle — it pulls in the usual Symfony pieces (http-foundation, dependency-injection, config) plus an image driver (GD/Imagick) or an HTTP client for the Fastly provider.
  2. Read the bundle's README.md and its DependencyInjection/Configuration.php first — that file is the real documentation for what variations, providers, and cache resolvers are configurable.
  3. In Laravel, register the bundle's extension/services via a small service provider (or use a Symfony-kernel bridge) and bind the generated config array from config/images.php into it. Keep this in one ImageServiceProvider so the rest of the app never touches Symfony internals.
  4. First use case: define one ImageVariation (e.g. thumb_small = thumbnail 200x200, fit), resolve it for a stored file, and emit the resulting URL in a Blade view. That single loop — config → variation → URL → response — is 90% of day-to-day usage.

Where to look when something is off: the variation registry (which named variations exist), the provider (who actually transforms bytes), and the cache resolver (who decides the output path/key). Almost every bug is one of those three being misconfigured.

Implementation Patterns

Config-driven variations, not code-driven. Define all variations in config (fit, thumbnail, scale, plus quality and format filters) and reference them by name in controllers. This keeps filter tuning out of application code and makes cache keys stable.

Dedicated image controller/route. A single route like GET /img/{variation}/{path} that resolves the variation, streams the image (or 302s to the CDN), and sets long-lived Cache-Control/ETag headers. Blade then only needs a URL helper:

<img src="{{ image_url('thumb_small', $post->cover) }}" alt="">

Fastly/CDN offload with real dimensions. When using the Fastly provider, you generally don't transform locally at all — you emit a signed/parametrised CDN URL. As of v2.0.3, ImageVariation objects from the Fastly provider now carry populated width/height, so you can render intrinsic dimensions directly in markup (avoiding layout shift) without an extra getimagesize() round-trip:

$variation = $this->variations->get('hero');
<img src="..." width="{{ $variation->getWidth() }}" height="{{ $variation->getHeight() }}">

Pre-warm / async generation. For non-CDN providers, dispatch a queued job that requests each needed variation after upload so the first visitor isn't the one paying the transform cost. The URL helper should be idempotent so warm-up and render agree.

Testing. Bind a fake/stub provider in tests that returns a deterministic URL or a 1x1 image; assert on the URL contract (variation name, path, cache-busting segment) rather than on bytes.

Gotchas and Tips

  • It's a Symfony bundle. Expect to fight autowiring: service IDs are bundle-prefixed, and tagged services (filters, providers) won't be discovered unless the extension is loaded. If a variation "doesn't exist", the extension almost certainly didn't boot.
  • Cache keys must include the filter set. If you change a filter (quality, crop anchor) and the key doesn't change, you'll serve stale images from disk/CDN forever. Either hash the filter config into the path or version the variation name (hero_v2).
  • Fastly width/height are not always known. v2.0.3 populates them, but only where the dimensions are derivable (fixed-size variations, or source dimensions already known). For relative "fit"-style variations the values can be null until the source is inspected — always null-check before emitting attributes rather than assuming the getters are non-null.
  • Filter order is semantic, not cosmetic. crop then thumbnail ≠ thumbnail then crop. Put the intent-revealing filter first and document it next to the variation.
  • Driver drift. GD and Imagick differ in colour handling, EXIF auto-rotation, and WebP quality defaults. Pin the driver in config per environment, or you'll get "works on staging" image diffs.
  • Filesystem permissions and paths. Local cache resolvers fail silently-ish (500 on first request, 200 after warm) when the cache dir isn't writable by the web user but is by your queue worker.
  • Debugging recipe: log the resolved variation name, the resolved cache path, and the provider class at the point of URL generation. Nine times out of ten the answer is in that triple.
  • Extension points worth knowing: custom filter (implements the bundle's filter interface, registered as a tagged service), custom provider (for S3/CloudFront/your own CDN), and a custom cache resolver (when you need S3-backed output rather than local disk). These are the sanctioned seams — prefer them over subclassing the variation factory.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
cgv/localized-resource
noith/settings