Automatic resizing and cropping of images using Symfony
The Liip Imagine Bundle
Google and its users have been focusing more and more on website performance and speed, the main reason why sites are slow these days is because of poor image optimization.
This tutorial will teach you on about image resizing and optimization with Symfony.
The main component we will be using for this is the Liip Imagine bundle, this bundle can be used in Symfony as an image resize/cropper tool and much more.
To resize and crop an image the following happens:
- You as a developer needs to set up Liip Imagine filters, more about this later
- The developer needs to add a filter to the image, for example:
{{ 'https://www.placehold.it/350x350'|imagine_filter('square_image') }}
- The bundle will use this filter to generate a custom route for this image
- As soon as you visit that page the Liip Imagine controller for that route will generate and return an image with the specifications of that filter
square_image
. - Don’t worry, the Liip Imagine filter doesn’t do this every time, once the image is created it’s stored in the cache and just returns that image next time.
Installation of the bundle
For a more detailed installation/configuration you can always visit the developer’s documentation on Github
To download the package in your project use composer. The package is called liip/imagine-bundle
so the composer command is:
composer require liip/imagine-bundle
If you’re using Symfony 4 or above, your installation and partial configuration are basically done, if you’re using Symfony 3 or below you should add the bundle to your AppKernel.php:
class AppKernel extends Kernel
{
public function registerBundles()
{
$bundles = array(
// ...
new Liip\ImagineBundle\LiipImagineBundle(),
);
// ...
}
// ...
}
and also add your routes:
_liip_imagine:
resource: "@LiipImagineBundle/Resources/config/routing.xml"
Make sure the above route is above anything else, as otherwise this might be ignored and your setup will not work.
Use filters to resize and crop your images
Liip Imagine filters are quite interesting, you can give them names and options/actions to adjust your images the way you want them.
A Liip imagine filter can:
- Change the quality of your image
- Scale the image
- Crop the image
- Add a border to an image
- Rotate, flip the image
- Add a watermark
If you’re still here, it’s time to show you how to set up some filters.
Open config/packages/liip_imagine.yml and have a look at it first, usually there’s already an example filter.
Notice there’s a driver option in that configuration file, the current possible options are gd, imagick, gmagick, choose what’s available on your production server and if all are supported imagick is the one with the most functionality and gd is the slimmest version of the three. I prefer Imagick overall.
Let’s create our first filter, I will add comments to what each option does to clarify the use case.
liip_imagine:
# As mentioned above, gd, imagick or gmagick are possible
driver: "imagick"
# This is where all the filters sets are located
filter_sets:
square: # The name of the filter, can be later used in the twig template
quality: 75 # Compression quality, this image will be 75% the quality
filters: # These are the filters of the filter set, many filters can be applied
# Scale and shrink the image to the given size, with a possible crop of the image
thumbnail:
size: [200, 200]
mode: outbound
# Shrink the image to 350px wide, the image will keep aspect ratio and adapt the height accordingly
small:
quality 80
filters:
relative_resize:
widen: 350
# Shrink/upscale the image to 800px of height, with full quality
big:
filters:
relative_resize:
heighten: 800
# Will allow smaller images to take 800px of height,
# width will change accordingly since aspect ration is still valid.
allow_upscale: true
How to use these filter sets now?
Pretty simple, you can use these filters in both PHP and in twig (most preferred method).
Use in twig:
<div class="product">
{{ product.title }}
{% if product.image %}
<img src="{{ product.image.webPath|imagine_filter('big') }}"/> {# You can replace big with square/small #}
{% endif %}
</div>
Use in PHP
/** @var CacheManager */
$imagineCacheManager = $this->get('liip_imagine.cache.manager');
/** @var string */
$resolvedPath = $imagineCacheManager->getBrowserPath($product->getImage()->getWebPath(), 'big'); // You can replace big with square/small
Changing filter options
Here comes the tricky part which many people had questions about:
I changed my filter, but my images are still all the same as before?!
Well easy, as I said before these images are cached, they don’t get recreated on the fly because of performance issues. This is why you specifically need to clear the Liip Imagine cache using the following command:
bin/console liip:imagine:cache:remove
Quick tip, you can resolve some images using the command:
bin/console liip:imagine:cache:resolve <PATH-OF-IMAGES>
This will already create the caches of the images stored in that path.
Conclusion
Rather than manually resize/cropping images I’m using Liip Imagine for a few months now and I must say it has streamlined my development workflow and makes sure the images the client uploads are always the correct size for that position.
To learn more about Symfony, you might be interested in a symfony beginners tutorial.