Web hints Navbar toggle

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.

Have any questions about this article?