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

Imagine Extra Bundle Laravel Package

zenstruck/imagine-extra-bundle

A Symfony bundle that adds extra filters and utilities to the Imagine image manipulation library, making it easy to apply additional image transformations through configuration and services.

View on GitHub
Deep Wiki
Context7

Getting Started

Before anything else: this bundle is archived, last released in December 2014, and targets Symfony2 / PHP 5.x. Its purpose was to wire the standalone imagine-filters library (filter definitions + a filesystem cache) into a Symfony2 application, giving you a service and a Twig helper that turn a source image path into a cached, transformed derivative. Treat this write-up as "how it was used" and "what to do instead," not as a recommendation to install it on a current project.

If you are maintaining a legacy Symfony2 app where it is already installed, the minimal path is:

  1. Install Imagine itself (imagine/imagine with either the GD or Imagick driver) and ensure the driver's PHP extension is present. The bundle does not ship an image backend.
  2. Register Zenstruck\ImagineExtraBundle\ZenstruckImagineExtraBundle in app/AppKernel.php and the routing/DI config if the README asks for it.
  3. Configure the two things the bundle actually needs: a web root / cache path (where derivatives are written and served from) and a set of named filters (the transformations to apply). Both live under the bundle's config key in config.yml.
  4. First use case — the canonical one — is an upload: persist the original image somewhere under web/, then in a controller or template ask the bundle for the derivative of a given filter name (thumbnail, preview, etc.) and render the returned web-relative path in an <img> tag.

Where to look first in the repo:

  • README.md — the only real documentation; read the config example before reading code.
  • DependencyInjection/ZenstruckImagineExtraExtension.php — the authoritative list of config keys, defaults, and service IDs. This is where you learn what is actually configurable versus what the README promises.
  • Resources/config/*.xml — the service wiring, which tells you which classes you can inject and override.
  • The Twig extension class — the public template API, and the thing you will actually call all day.
  • The cache/loader class — how a source path maps to a derivative path, and therefore how cache invalidation works (or doesn't).

Implementation Patterns

Configuration-defined filter sets. The core workflow is declarative: define each filter once in YAML (a name plus an ordered list of transformations — resize, thumbnail, crop, quality, format), then reference it by name from application code. Keep filter names semantic (product_thumb, hero_wide) rather than technical (resize_200x200), because the name is the cache key and the call site should not change when the dimensions do.

Controller/service usage. Inject the bundle's filter/manager service into a controller or a dedicated image service rather than resolving it from the container. The typical pattern is: accept the upload, save the original, then lazily request the derivative only when it is needed for display. Generating derivatives on upload (eager) is faster to render but multiplies storage and slows the upload request; generating on first render (lazy) is the default and usually correct.

Twig helper for templates. The bundle's Twig function is where most day-to-day usage lives — pass the source path and the filter name, get back a URL. Wrap it in a project-local Twig macro so that every <img> in the app goes through one place; when you eventually migrate away from this bundle, you change one macro instead of grepping templates.

Compose with upload/storage bundles. In practice this bundle was almost always paired with VichUploaderBundle or a Gaufrette/filesystem abstraction. The pattern: the upload bundle owns the original file and its path; the imagine-extra bundle owns only the derivative and its cache path. Keep those two path namespaces strictly separate and never let the derivative path be written back into the entity — derivatives are disposable and must be regenerable.

Runtime filters vs. configured filters. If the library supports passing transformations at call time, resist using that in application code. Ad-hoc transformations bypass the named-filter cache key discipline and lead to an unbounded number of cached derivatives. If you genuinely need dynamic sizing (responsive images), enumerate the allowed sizes in config and map request parameters onto those names.

Testing. Because the filtering itself is delegated to imagine-filters and Imagine, unit-test your code against a stubbed filter/manager service that returns a known path string. Don't assert on actual pixel output in your app's test suite; that belongs in a thin integration test with a fixture image, and it will be slow and driver-dependent.

Gotchas and Tips

  • Abandonware is the headline risk. No releases since 2014, no security policy, Symfony2 is EOL, and the underlying Imagine versions it was written against are years behind. Do not install this in a new project. There is no upgrade path within the bundle; the migration is to LiipImagineBundle (the maintained, widely used equivalent with the same conceptual model: named filter sets, a cache resolver, a Twig function) or to imagine-filters used directly behind a small service of your own.
  • Composer will fight you. Dependency constraints pinned to Symfony2 and PHP 5 will not resolve on a modern stack, and --ignore-platform-reqs hacks will surface as fatal errors at runtime. If you need this code, vendor it or fork it.
  • Cache invalidation is manual. Changing a filter's definition in config does not invalidate previously generated derivatives, because the derivative path is usually derived from the source path plus the filter name — not from the filter's parameters. After changing dimensions or quality, you must clear the image cache directory by hand. A robust fork hashes the resolved filter options into the cache key; the stock bundle likely does not.
  • cache:clear does not clear images. Symfony's cache clear is unrelated to the image cache. Add an explicit console command or deploy step for the image cache directory, and give that directory its own deploy-time permissions story — a read-only or missing directory produces silent 404s, not exceptions.
  • Path handling is the classic bug source. Anything that takes a user-supplied path and turns it into a filesystem read is a traversal risk. Sanitize/normalize the source path, and reject anything that escapes the configured source root before handing it to Imagine.
  • Memory and driver quirks. Imagick is far more memory-hungry than GD on large source images and will hit memory_limit mid-request; GD silently degrades quality on some formats and mishandles palette PNGs. Set an explicit memory_limit consideration and test with your largest real-world images, not a 200×200 fixture.
  • Debugging checklist, in order: does the source file exist at the resolved absolute path → does the cache directory exist and is it writable by the web user → is the driver extension actually loaded → does the derivative exist on disk → is the returned URL correct relative to web/. Nine out of ten issues are one of the first two.
  • Extension points. If you fork it, the natural seams are: a custom filter implementing the imagine-filters filter interface (registered in DI), a custom cache/resolver class, and overriding the Twig extension service. Those are the three places worth patching rather than editing the bundle in place.
  • Budget a migration, not a fix. Given three stars, zero dependents, and a decade of dormancy, the realistic advice for a maintainer who finds this in a composer.json is to schedule replacement with LiipImagineBundle and keep the named-filter vocabulary intact so templates and config translate almost one-to-one.
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.
skyraptor/chatter
edlugz/sasapay
abbasudo/artisan-route
mirvan/ippanel
ignibyte/aic-framework
glavweb/data-schema-bundle
glavweb/datagrid-bundle
tacticmedia/scim-server
uni-method/frame
neika-ai/sdk
adachsoft/php-code-style
pharaonic/laravel-notification-dependencies
beautinow/translug
dev-brainiac/bot-cloaked
octoberrain/html
octoberrain/extension
octoberrain/exception
octoberrain/contracts
adachsoft/api-version-bundle
cgv/localized-resource