Installation:
composer require liip/imagine-bundle
Add to config/bundles.php:
return [
// ...
Liip\ImagineBundle\LiipImagineBundle::class => ['all' => true],
];
Basic Configuration:
Create config/packages/liip_imagine.yaml:
liip_imagine:
driver: 'gd' # or 'gmagick'/'imagick'
filter_sets:
my_thumbnail:
filters:
thumbnail: { size: [100, 100], mode: outbound }
First Use Case: Generate a thumbnail in a controller:
use Liip\ImagineBundle\Imagine\Filter\FilterConfiguration;
use Liip\ImagineBundle\Service\FilterService;
public function show(Image $image, FilterService $filterService)
{
$path = $filterService->getPath($image->getPath(), 'my_thumbnail');
return new Response(file_get_contents($path));
}
config/packages/liip_imagine.yaml (default config)src/Controller/ImageController.php (example usage)templates/imagine/filters.html.twig (Twig integration)Define reusable filter sets in YAML:
liip_imagine:
filter_sets:
social_share:
filters:
thumbnail: { size: [600, 300], mode: outbound }
background: { color: '#ffffff' }
watermark: { image: '%kernel.project_dir%/public/images/watermark.png', opacity: 0.2 }
Apply in controller:
$path = $filterService->getPath($originalPath, 'social_share');
Chain filters dynamically:
$filterManager = $this->get('liip_imagine.filter.manager');
$filterConfig = new FilterConfiguration();
$filterConfig->add($filterManager->findFilter('thumbnail'), ['size' => [200, 200]]);
$filterConfig->add($filterManager->findFilter('watermark'), ['image' => $watermarkPath]);
$path = $filterService->getPath($originalPath, null, $filterConfig);
Use in templates:
<img src="{{ asset(liip_imagine_filter(image.path, 'my_thumbnail')) }}">
Clear cache for a filter set:
php bin/console liip:imagine:cache:remove my_thumbnail
Or programmatically:
$this->get('liip_imagine.cache.manager')->remove($filterSetName);
Trigger actions post-filtering:
// config/services.yaml
App\EventListener\ImageFilterListener:
tags:
- { name: kernel.event_listener, event: liip_imagine.filter.post, method: onPostFilter }
Use with EntityType for file uploads:
$builder->add('image', EntityType::class, [
'class' => Image::class,
'mapped' => false,
'label' => 'Upload Image',
]);
Return filtered images as StreamedResponse:
public function getFilteredImage(Image $image, FilterService $filterService)
{
$path = $filterService->getPath($image->getPath(), 'my_thumbnail');
return new StreamedResponse(function () use ($path) {
echo file_get_contents($path);
}, 200, ['Content-Type' => 'image/jpeg']);
}
Store filtered paths in DB:
/**
* @ORM\Column(type="string", nullable=true)
*/
private $thumbnailPath;
liip_imagine.yaml:
driver: gd
fallback_driver: imagick
php bin/console cache:clear
php bin/console liip:imagine:cache:remove my_thumbnail
liip_imagine.cache.invalidator service to hook into events (e.g., file uploads).var/cache/liip_imagine is writable:
chmod -R 775 var/cache/liip_imagine
memory_limit. Adjust in php.ini or use smaller filter sets.imagick for better memory handling.filters:
resize: { width: 800 } # Runs first
thumbnail: { size: [200, 200] } # Runs second (overrides resize)
Enable debug mode and check var/log/dev.log for filter execution logs.
Use the liip:imagine:filter:list command to verify configured filter sets:
php bin/console liip:imagine:filter:list
imagickSimulate production environments:
# config/packages/dev/liip_imagine.yaml
driver: imagick
Ensure source and cache paths are correct in liip_imagine.yaml:
source: '%kernel.project_dir%/public/uploads'
cache: '%kernel.project_dir%/var/cache/liip_imagine'
Create a custom filter (e.g., RoundCornersFilter):
namespace App\Imagine\Filter;
use Liip\ImagineBundle\Imagine\Filter\FilterInterface;
class RoundCornersFilter implements FilterInterface
{
public function applyFilter($image)
{
// Use Imagine library to add rounded corners
return $image->effects()->gaussianBlur(0.5);
}
}
Register in config/services.yaml:
App\Imagine\Filter\RoundCornersFilter:
tags:
- { name: liip_imagine.filter, alias: round_corners }
Fetch filter sets from a database:
$filterConfig = new FilterConfiguration();
$dbFilterSet = $this->getFilterSetFromDB($filterSetName);
foreach ($dbFilterSet['filters'] as $filter => $options) {
$filterConfig->add($filterManager->findFilter($filter), $options);
}
Listen for liip_imagine.filter.pre and liip_imagine.filter.post events:
public function onPreFilter(GetResponseForFilterEvent $event)
{
if (!$event->isValid()) {
$event->setValid(false);
// Custom logic (e.g., skip if image is already optimized)
}
}
Use liip_imagine.cache.manager to store filtered images in S3:
$cacheManager = $this->get('liip_imagine.cache.manager');
$cacheManager->setCacheDir('s3://my-bucket/cache/');
Add a filter set for WebP:
liip_imagine:
filter_sets:
webp_conversion:
filters:
convert: { format: webp, quality: 80 }
How can I help you explore Laravel packages today?