diff --git a/README.md b/README.md index 01e464b50..c3954f3de 100644 --- a/README.md +++ b/README.md @@ -1,100 +1,227 @@ -LiipImagineBundle -================= +# LiipImagineBundle + +| Travis-CI | Style-CI | Downloads | Release | +|:----------------------:|:-----------------------:|:-----------------------:|:-----------------------:| +| [![Travis](https://src.run/shield/liip/LiipImagineBundle/travis.svg)](http://travis-ci.org/liip/LiipImagineBundle) | [![Style CI](https://src.run/shield/liip/LiipImagineBundle:2515323/styleci.svg)](https://styleci.io/repos/2515323) |[![Downloads](https://src.run/shield/liip/LiipImagineBundle/packagist_dt.svg)](https://packagist.org/packages/liip/imagine-bundle) | [![Latest Stable Version](https://src.run/shield/liip/LiipImagineBundle/packagist_v.svg)](https://packagist.org/packages/liip/imagine-bundle) | + +*This bundle provides an image manipulation abstraction toolkit for +[Symfony](http://symfony.com/)-based projects.* + +## Overview + +- [Filter Sets](http://symfony.com/doc/master/bundles/LiipImagineBundle/basic-usage.html): + Using any Symfony-supported configuration language (such as YML and XML), + you can create *filter set* definitions that specify transformation routines. + These include a set of *filters* and *post-processors*, as well as other, + optional parameters. +- [Filters](http://symfony.com/doc/master/bundles/LiipImagineBundle/filters.html): + Many built-in filters are provided, allowing the application of common + transformations. Examples include `thumbnail`, `scale`, `crop`, `strip`, `watermark`, + and many more. Additionally, [custom filters](http://symfony.com/doc/master/bundles/LiipImagineBundle/filters.html#filter-custom) + are supported. +- [Post-Processors](http://symfony.com/doc/master/bundles/LiipImagineBundle/post-processors.html): + This component allows for the modification of the resulting binary file + created by filters. Examples include `jpegoptim`, `optipng`, `cjpeg`, + and `pngquant`. Additionally, [custom post-processors](http://symfony.com/doc/master/bundles/LiipImagineBundle/post-processors.html#post-processors-custom) + are supported. + + +### Example + +Suppose you defined a `my_thumb` filter set, which can be configured to +perform any number of different transformations. The simplest invocation would +be to pipe the path of your image to the provided `imagine_filter` Twig +filter. + +```twig + +``` -This bundle is a fork of AvalancheImagineBundle which provides easy image -manipulation support for Symfony2. The goal of the fork is to make the -code more extensible and as a result applicable for more use cases. -For more details on the reason for the fork see: -https://github.com/avalanche123/AvalancheImagineBundle/pull/25 +### Attribution -For example with this bundle the following is possible: +- Thanks to the many [contributors](https://github.com/liip/LiipImagineBundle/graphs/contributors) + who have dedicated their time and code to this project. + +- The standalone PHP + [Imagine Library](https://github.com/avalanche123/Imagine) + is used by this bundle for image transformations. + +- This package was forked from + [AvalancheImagineBundle](https://github.com/avalanche123/AvalancheImagineBundle) + with the goal of making the code more extensible. Reference + [AvalancheImagineBundle#25](https://github.com/avalanche123/AvalancheImagineBundle/pull/25) + for additional information on the reasoning for this fork. -``` jinja - -``` -This will perform the transformation called `thumbnail`, which you can define -to do a number of different things, such as resizing, cropping, drawing, -masking, etc. +## Setup -This bundle integrates the standalone PHP "[Imagine library](https://github.com/avalanche123/Imagine)". -[![Build Status](https://secure.travis-ci.org/liip/LiipImagineBundle.png)](http://travis-ci.org/liip/LiipImagineBundle) -[![Total Downloads](https://poser.pugx.org/liip/imagine-bundle/downloads.png)](https://packagist.org/packages/liip/imagine-bundle) -[![Latest Stable Version](https://poser.pugx.org/liip/imagine-bundle/v/stable.png)](https://packagist.org/packages/liip/imagine-bundle) +### Installation +Using this package is similar to all Symfony bundles. The following steps must +be performed -## Installation +1. [Download the Bundle](http://symfony.com/doc/master/bundles/LiipImagineBundle/installation.html#step-1-download-the-bundle) +2. [Enable the Bundle](http://symfony.com/doc/master/bundles/LiipImagineBundle/installation.html#step-2-enable-the-bundle) +3. [Register the Routes](http://symfony.com/doc/master/bundles/LiipImagineBundle/installation.html#step-3-register-the-bundle-s-routes) + +Detailed setup instructions can be found in the +[installation](http://symfony.com/doc/master/bundles/LiipImagineBundle/installation.html) +chapter of the documentation. -In case you are not sure how to install this bundle, see the [installation instructions](http://symfony.com/doc/master/bundles/LiipImagineBundle/installation.html). ### Configuration -After installing the bundle, make sure you add this route to your routing: +Detailed information on all available configuration options can be found in the +[configuration](http://symfony.com/doc/master/bundles/LiipImagineBundle/configuration.html) +chapter of the documentation. + + +## Usage Primer + +Generally, this bundle works by applying *filter sets* to images from inside +a template. Your *filter sets* are defined within the application's configuration +file (often `app/config/config.yml`) and are comprised of a collection of +*filters*, *post-processors*, and other optional parameters. + +We'll learn more about *post-processors* and other available parameters later, +but for now lets focus on how to define a simple *filter set* comprised of a +few *filters*. + + +### Create Thumbnails + +Before we get started, there is a small amount of configuration needed to ensure +our [data loaders](http://symfony.com/doc/master/bundles/LiipImagineBundle/data-loaders.html) +and [cache resolvers](http://symfony.com/doc/master/bundles/LiipImagineBundle/cache-resolvers.html) +operate correctly. Use the following boilerplate in your configuration file. + +```yml +# app/config/config.yml + +liip_imagine : + + # configure resolvers + resolvers : + + # setup the default resolver + default : + + # use the default web path + web_path : ~ -``` yaml -# app/config/routing.yml + # your filter sets are defined here + filter_sets : -_liip_imagine: - resource: "@LiipImagineBundle/Resources/config/routing.xml" + # use the default cache configuration + cache : ~ ``` -For a complete configuration drill-down see [the respective chapter in the documentation](http://symfony.com/doc/master/bundles/LiipImagineBundle/configuration.html). +With the basic configuration in place, we'll start with an example that fulfills a +common use-case: creating thumbnails. Lets assume we want the resulting thumbnails +to have the following transformations applied to them: -## Basic Usage +- Scale and crop the image to 120x90px. +- Add a 2px black border to the scaled image. +- Adjust the image quality to 75. -This bundle works by configuring a set of filters and then applying those -filters to images inside a template So, start by creating some sort of filter -that you need to apply somewhere in your application. For example, suppose -you want to thumbnail an image to a size of 120x90 pixels: +Adding onto our boilerplate from above, we need to define a *filter set* (which we'll +name `my_thumb`) with two *filters* configured: the `thumbnail` and `background` +*filters*. -``` yaml +```yml # app/config/config.yml -liip_imagine: - resolvers: - default: - web_path: ~ +liip_imagine : + resolvers : + default : + web_path : ~ + + filter_sets : + cache : ~ + + # the name of the "filter set" + my_thumb : + + # adjust the image quality to 75% + quality : 75 + + # list of transformations to apply (the "filters") + filters : - filter_sets: - cache: ~ - my_thumb: - quality: 75 - filters: - thumbnail: { size: [120, 90], mode: outbound } + # create a thumbnail: set size to 120x90 and use the "outbound" mode + # to crop the image when the size ratio of the input differs + thumbnail : { size : [120, 90], mode : outbound } + + # create a 2px black border: center the thumbnail on a black background + # 4px larger to create a 2px border around the final image + background : { size : [124, 94], position : center, color : '#000000' } ``` -You've now defined a filter set called `my_thumb` that performs a thumbnail transformation. -We'll learn more about available transformations later, but for now, this -new filter can be used immediately in a template: +You've now created a *filter set* called `my_thumb` that performs a thumbnail +transformation. The `thumbnail` filter sizes the image to the desired width +and height (in this example, 120x90px), and its `mode: outbound` option causes +the resulting image to be cropped if the input ratio differs. The `background` +filter results in a 2px black border by creating a black canvas 124x94px in size, +and positioning the thumbnail at its center. + +**Note:** +*A *filter set* can have any number of *filters* defined for it. Simple +transformations may only require a single *filter* while complex +transformations can have an unlimited number of *filters* defined for them.* + +There are a number of additional [filters](http://symfony.com/doc/master/bundles/LiipImagineBundle/filters.html), +but for now you can use your newly defined ``my_thumb`` *filter set* immediately +within a template. -``` jinja +*For Twig-based template, use:* + +```twig ``` -Or if you're using PHP templates: +*Or, for PHP-based template, use:* -``` php +```php ``` -Behind the scenes, the bundles applies the filter(s) to the image on the first -request and then caches the image to a similar path. On the next request, -the cached image would be served directly from the file system. +Behind the scenes, the bundle applies the filter(s) to the image on-the-fly +when the first page request is served. The transformed image is then cached +for subsequent requests. The final cached image path would be similar to +`/media/cache/my_thumb/relative/path/to/image.jpg`. -In this example, the final rendered path would be something like -`/media/cache/my_thumb/relative/path/to/image.jpg`. This is where Imagine -would save the filtered image file. +**Note:** +*Using the ``dev`` environment you might find that images are not properly +rendered via the template helper. This is often caused by having +`intercept_redirect` enabled in your application configuration. To ensure +images are rendered, it is strongly suggested to disable this option: -You can also pass some options at runtime: +```yml +# app/config/config_dev.yml -``` jinja +web_profiler : + intercept_redirects : false +``` + + +### Runtime Options + +Sometime, you may have a filter defined that fulfills 99% of your usage +scenarios. Instead of defining a new filter for the erroneous 1% of cases, +you may instead choose to alter the behavior of a filter at runtime by +passing the template helper an options array. + +*For Twig-based template, use:* + +```twig {% set runtimeConfig = {"thumbnail": {"size": [50, 50] }} %} + ``` -Or if you're using PHP templates: +*Or, for PHP-based template, use:* ```php filter('/relative/path/to/image.jpg', 'my_thumb', $runtimeConfig) ?>" /> ``` -Also you can resolve image url from console: -```jinja -app/console liip:imagine:cache:resolve relative/path/to/image.jpg relative/path/to/image2.jpg --filters=my_thumb --filters=thumbnail_default + + +### Path Resolution + +Sometime you need to resolve the image path returned by this bundle for a +filtered image. This can easily be achieved using Symfony's console binary +or pragmatically from within a controller or other piece of code. + + +#### Resolve with the Console + +You can resolve an image URL using the console command +`liip:imagine:cache:resolve`. The only required argument is one or more +relative image paths (which must be separated by a space). + +```bash +$ php app/console liip:imagine:cache:resolve relative/path/to/image1.jpg relative/path/to/image2.jpg +``` + +Additionally, you can use the ``--filters`` option to specify which filter +you want to resolve for (if the ``--filters`` option is omitted, all +available filters will be resolved). + +```bash +$ php app/console liip:imagine:cache:resolve relative/path/to/image1.jpg --filters=my_thumb ``` -Where only paths required parameter. They are separated by space. If you omit filters option will be applied all available filters. -If you need to access filtered image URL in your controller: -``` php -$this->get('liip_imagine.cache.manager')->getBrowserPath('/relative/path/to/image.jpg', 'my_thumb'), +#### Resolve Pragmatically + +You can resolve the image URL in your code using the `getBrowserPath` +method of the `liip_imagine.cache.manager` service. Assuming you already +have the service assigned to a variable called `$imagineCacheManager`, +you would run: + +```php +$imagineCacheManager->getBrowserPath('/relative/path/to/image.jpg', 'my_thumb'); ``` -In this case, the final rendered path would contain some random data in the path -`/media/cache/my_thumb/S8rrlhhQ/relative/path/to/image.jpg`. This is where Imagine -would save the filtered image file. +Often, you need to perform this operation in a controller. Assuming your +controller inherits from the base Symfony controller, you can take advantage +of the inherited ``get`` method to request the ``liip_imagine.cache.manager`` +service, from which you can call ``getBrowserPath`` on a relative image +path to get its resolved location. -Note: Using the ``dev`` environment you might find that the images are not properly rendered when -using the template helper. This is likely caused by having ``intercept_redirect`` enabled in your -application configuration. To ensure that the images are rendered disable this option: +```php +/** @var CacheManager */ +$imagineCacheManager = $this->get('liip_imagine.cache.manager'); -``` jinja -web_profiler: - intercept_redirects: false +/** @var string */ +$resolvedPath = $this->getBrowserPath('/relative/path/to/image.jpg', 'my_thumb'); ``` + ## Filters -The LiipImagineBundle provides a set of built-in filters. -You may easily roll your own filter, see [the filters chapter in the documentation](http://symfony.com/doc/master/bundles/LiipImagineBundle/filters.html). +This bundle provides a set of built-in filters andy ou may easily +define your own filters as well. Reference the +[filters chapter](http://symfony.com/doc/master/bundles/LiipImagineBundle/filters.html) +from our documentation. -## Using the controller as a service -If you need to use the filters in a controller, you can just load `ImagineController.php` controller as a service and handle the response: +## Use as a Service + +If you need to use your defined "filter sets" from within your controller, you +can fetch this bundle's controller from the service container and handle +the response yourself. + +```php +container - ->get('liip_imagine.controller') + /** @var ImagineController */ + $imagine = $this + ->container + ->get('liip_imagine.controller'); + + /** @var RedirectResponse */ + $imagemanagerResponse = $imagine ->filterAction( $this->request, // http request 'uploads/foo.jpg', // original image you want to apply a filter to 'my_thumb' // filter defined in config.yml ); - // string to put directly in the "src" of the tag - $cacheManager = $this->container->get('liip_imagine.cache.manager'); - $srcPath = $cacheManager->getBrowserPath('uploads/foo.jpg', 'my_thumb'); + /** @var CacheManager */ + $cacheManager = $this + ->container + ->get('liip_imagine.cache.manager'); + + /** @var string */ + $sourcePath = $cacheManager + ->getBrowserPath( + 'uploads/foo.jpg', + 'my_thumb' + ); // .. } } + +?> ``` -In case you need to add more logic the recommended solution is to either extend `ImagineController.php` controller or take the code from that controller as a basis for your own controller. +If you need to add more logic, the recommended solution is to either +extend `ImagineController.php` or use it as the basis for your own +implementation. + +To use the controller in another service, you have to simulate a new request. + +```php +container + ->get('liip_imagine.controller'); -If you want to use the service in another service, you have to simulate a new request: +/** @var Response */ +$response = $imagine + ->filterAction( + new Symfony\Component\HttpFoundation\Request(), + 'uploads/foo.jpg', + 'my_thumb' + ); -``` php -$imagemanagerResponse = $this->container - ->get('liip_imagine.controller') - ->filterAction(new Symfony\Component\HttpFoundation\Request(), 'uploads/foo.jpg', 'my_thumb'); +?> ``` -## Outside the web root -When your setup requires your source images to live outside the web root, or if that's just the way you roll, -you have to set your loader's parameter `data_root` in the `config.yml` with the absolute path where your source images are -located: +## Images Outside Data Root + +When your setup requires your source images reside outside the web root, +you have to set your loader's `data_root` parameter in your configuration +(often `app/config/config.yml`) with the absolute path to your source image +location. -``` yaml +```yml liip_imagine: loaders: default: @@ -188,10 +382,27 @@ liip_imagine: data_root: /path/to/source/images/dir ``` -Afterwards, you need to grant read access on Apache to access the images source directory. For achieving it you have -to add the following directive to your project's vhost file: +This location must be readable by your web server. On a system that supports +`setfacl` (such as Linux/BSD), use -``` xml +```sh +HTTPDUSER=`ps axo user,comm | grep -E '[a]pache|[h]ttpd|[_]www|[w]ww-data|[n]ginx' | grep -v root | head -1 | cut -d\ -f1` + +sudo setfacl -R -m u:"$HTTPDUSER":rwX -m u:`whoami`:rwX /path/to/source/images/dir + +sudo setfacl -dR -m u:"$HTTPDUSER":rwX -m u:`whoami`:rwX /path/to/source/images/dir +``` + +See the [Symfony Permissions documentation](http://symfony.com/doc/current/setup/file_permissions.html) +for commands compatible with macOS and other environments. + + +### Using Apache + +You need to grant read access for Apache by adding the following to your +Apache VHost configuration + +```xml @@ -203,10 +414,12 @@ to add the following directive to your project's vhost file: ``` -Another way would be placing the directive in a separate file living inside your project. For instance, -you can create a file `app/config/apache/photos.xml` and add to the project's vhost the following directive: +Alternatively, you can place the directive in a separate file within your +project, and include it within your Apache VHost configuration. For example, +you can create the file `app/config/apache/photos.xml` and add the following +to your VHost file -``` xml +```xml @@ -214,12 +427,15 @@ you can create a file `app/config/apache/photos.xml` and add to the project's vh ``` -This way you keep the file along with your code and you are able to change your files directory access easily or create -different environment-dependant configuration files. +This method keeps the file with the rest of your code, allowing you to change +it easily or create different environment-dependent configuration files. + +Once you have configured Apache properly, the relative path to an image with +the following absolute path `/path/to/source/images/dir/logo.png` must be +`/FavouriteAlias/logo.png`. -Either way, once you have granted access on Apache to read the `data_root` files, the relative path of an image with this -absolute path `/path/to/source/images/dir/logo.png` must be `/FavouriteAlias/logo.png` to be readable. ## Documentation -For more detailed information about the features of this bundle, please refer to [the documentation](http://symfony.com/doc/master/bundles/LiipImagineBundle/index.html). +For more detailed information about the features of this bundle, refer to +the [documentation](http://symfony.com/doc/master/bundles/LiipImagineBundle). diff --git a/Resources/doc/basic-usage.rst b/Resources/doc/basic-usage.rst index 901fa46e4..69d3d0cdc 100644 --- a/Resources/doc/basic-usage.rst +++ b/Resources/doc/basic-usage.rst @@ -1,14 +1,63 @@ + + Basic Usage =========== -This bundle works by configuring a set of filters and then applying those -filters to images inside a template. So, start by creating some sort of filter -that you need to apply somewhere in your application. For example, suppose -you want to thumbnail an image to a size of 120x90 pixels: +Generally, this bundle works by applying filter sets to images from inside +a template. Your filter sets are defined within the application's configuration +file (often ``app/config/config.yml``) and are comprised of a collection of +filters, post-processors, and other optional parameters. + +We'll learn more about post-processors and other available parameters later, +but for now lets focus on how to define a simple filter set comprised of a +few filters. + +.. _usage-create-thumbnails: + +Create Thumbnails +----------------- + +Before we get started, there is a small amount of configuration needed to ensure +our :doc:`data loaders ` and :doc:`cache-resolvers ` +operate correctly. Use the following configuration boilerplate. + +.. code-block:: yaml + + # app/config/config.yml + + liip_imagine: + + # configure resolvers + resolvers: + + # setup the default resolver + default: + + # use the default web path + web_path: ~ + + # your filter sets are defined here + filter_sets: + + # use the default cache configuration + cache: ~ + +With the basic configuration in place, we'll start with an example that fulfills a +common use-case: creating thumbnails. Lets assume we want the resulting thumbnails +to have the following transformations applied to them: + +* Scale and crop the image to 120x90px. +* Add a 2px black border to the scaled image. +* Adjust the image quality to 75. + +Adding onto our boilerplate from above, we need to define a filter set (which we'll +name ``my_thumb``) with two filters configured: the ``thumbnail`` and ``background`` +filters. .. code-block:: yaml # app/config/config.yml + liip_imagine: resolvers: default: @@ -16,40 +65,84 @@ you want to thumbnail an image to a size of 120x90 pixels: filter_sets: cache: ~ + + # the name of the "filter set" my_thumb: + + # adjust the image quality to 75% quality: 75 + + # list of transformations to apply (the "filters") filters: + + # create a thumbnail: set size to 120x90 and use the "outbound" mode + # to crop the image when the size ratio of the input differs thumbnail: { size: [120, 90], mode: outbound } -You've now defined a filter set called ``my_thumb`` that performs a thumbnail -transformation. We'll learn more about available transformations later, but -for now, this new filter can be used immediately in a template: + # create a 2px black border: center the thumbnail on a black background + # 4px larger to create a 2px border around the final image + background: { size: [124, 94], position: center, color: '#000000' } + +You've now created a filter set called ``my_thumb`` that performs a thumbnail +transformation. The ``thumbnail`` filter sizes the image to the desired width +and height (120x90px), and its ``mode: outbound`` option causes +the resulting image to be cropped if the input ratio differs. The ``background`` +filter results in a 2px black border by creating a black canvas 124x94px in size, +and positioning the thumbnail at its center. + +.. note:: + + A filter set can have any number of filters defined for it. Simple + transformations may only require a single filter, while more complex + transformations can have any number of filters defined for them. + +There are a number of additional :doc:`filters `, but for now you can use +your newly defined ``my_thumb`` filter set immediately within a template. .. configuration-block:: - .. code-block:: html+jinja + .. code-block:: html+twig - + .. code-block:: html+php -Behind the scenes, the bundles applies the filter(s) to the image on the -first request and then caches the image to a similar path. On the next request, -the cached image would be served directly from the file system. +Behind the scenes, the bundle applies the filter(s) to the image on-the-fly +when the first page request is served. The transformed image is then cached +for subsequent requests. The final cached image path would be similar to +``/media/cache/my_thumb/relative/path/to/image.jpg``. + +.. note:: + + Using the ``dev`` environment you might find that images are not properly + rendered via the template helper. This is often caused by having + ``intercept_redirect`` enabled in your application configuration. To ensure + images are rendered, it is strongly suggested to disable this option: + + .. code-block:: yaml + + # app/config/config_dev.yml + + web_profiler: + intercept_redirects: false + -In this example, the final rendered path would be something like -``/media/cache/my_thumb/relative/path/to/image.jpg``. This is where Imagine -would save the filtered image file. +Runtime Options +--------------- -You can also pass some options at runtime: +Sometimes, you may have a filter defined that fulfills 99% of your usage +scenarios. Instead of defining a new filter for the erroneous 1% of cases, +you may instead choose to alter the behavior of a filter at runtime by +passing the template helper an options array. .. configuration-block:: - .. code-block:: html+jinja + .. code-block:: html+twig {% set runtimeConfig = {"thumbnail": {"size": [50, 50] }} %} + .. code-block:: html+php @@ -62,35 +155,59 @@ You can also pass some options at runtime: ); ?> - + + -Also you can resolve image url from console: +Path Resolution +--------------- + +Sometimes you need to resolve the image path returned by this bundle for a +filtered image. This can easily be achieved using Symfony's console binary +or pragmatically from within a controller or other piece of code. + + +Resolve with the Console +~~~~~~~~~~~~~~~~~~~~~~~~ + +You can resolve an image URL using the console command +``liip:imagine:cache:resolve``. The only required argument is one or more +relative image paths (which must be separated by a space). .. code-block:: bash - $ php app/console liip:imagine:cache:resolve relative/path/to/image.jpg relative/path/to/image2.jpg --filters=my_thumb --filters=thumbnail_default + $ php app/console liip:imagine:cache:resolve relative/path/to/image1.jpg relative/path/to/image2.jpg -Where only paths required parameter. They are separated by space. If you -omit filters option will be applied all available filters. +Additionally, you can use the ``--filters`` option to specify which filter +you want to resolve for (if the ``--filters`` option is omitted, all +available filters will be resolved). -If you need to access filtered image URL in your controller: +.. code-block:: bash -.. code-block:: php + $ php app/console liip:imagine:cache:resolve relative/path/to/image1.jpg --filters=my_thumb - $this->get('liip_imagine.cache.manager')->getBrowserPath('/relative/path/to/image.jpg', 'my_thumb') -In this case, the final rendered path would contain some random data in the -path ``/media/cache/my_thumb/S8rrlhhQ/relative/path/to/image.jpg``. This is where -Imagine would save the filtered image file. +Resolve Pragmatically +~~~~~~~~~~~~~~~~~~~~~ -.. note:: +You can resolve the image URL in your code using the ``getBrowserPath`` +method of the ``liip_imagine.cache.manager`` service. Assuming you already +have the service assigned to a variable called ``$imagineCacheManager``, +you would run: - Using the ``dev`` environment you might find that the images are not properly - rendered when using the template helper. This is likely caused by having - ``intercept_redirect`` enabled in your application configuration. To ensure - that the images are rendered disable this option: +.. code-block:: php - .. code-block:: yaml + $imagineCacheManager->getBrowserPath('/relative/path/to/image.jpg', 'my_thumb'); - web_profiler: - intercept_redirects: false +Often, you need to perform this operation in a controller. Assuming your +controller inherits from the base Symfony controller, you can take advantage +of the inherited ``get`` method to request the ``liip_imagine.cache.manager`` +service, from which you can call ``getBrowserPath`` on a relative image +path to get its resolved location. + +.. code-block:: php + + /** @var CacheManager */ + $imagineCacheManager = $this->get('liip_imagine.cache.manager'); + + /** @var string */ + $resolvedPath = $this->getBrowserPath('/relative/path/to/image.jpg', 'my_thumb'); diff --git a/Resources/doc/cache-manager.rst b/Resources/doc/cache-manager.rst index 989bcbac1..50bb69abe 100644 --- a/Resources/doc/cache-manager.rst +++ b/Resources/doc/cache-manager.rst @@ -1,7 +1,9 @@ -CacheManager -============ -Cache removal + +Cache Manager +============= + +Cache Removal ------------- CacheManager allows to remove cache in various ways. diff --git a/Resources/doc/cache-resolver/amazons3.rst b/Resources/doc/cache-resolver/amazons3.rst index bc139dc83..81a674355 100644 --- a/Resources/doc/cache-resolver/amazons3.rst +++ b/Resources/doc/cache-resolver/amazons3.rst @@ -1,39 +1,50 @@ -AmazonS3Resolver -================ -The AmazonS3Resolver requires the `aws-sdk-php`_ library. Open a command -console, enter your project directory and execute the following command to -download the latest stable version of this library: +.. _cache-resolver-amazon-s3: + +Amazon S3 Resolver +================== + +The ``AmazonS3Resolver`` resolver enables cache resolution using Amazon S3. + +Dependencies +------------ + +This cache resolver requires the `aws-sdk-php`_ library, which can be installed +by executing the following command in your project directory: .. code-block:: bash $ composer require aws/aws-sdk-php -This command requires you to have Composer installed globally, as explained -in the `installation chapter`_ of the Composer documentation. +.. note:: + + This command requires that `Composer`_ is installed globally, as explained in + their `installation documentation`_. -Afterwards, you only need to configure some information regarding your AWS -account and the bucket. +Configuration +------------- + +To begin, you must assign your Amazon key, secret, and bucket to their respective parameters. .. code-block:: yaml + # app/config/config.yml or app/config/parameters.yml + parameters: - amazon_s3.key: 'your-aws-key' - amazon_s3.secret: 'your-aws-secret' - amazon_s3.bucket: 'your-bucket.example.com' + amazon_s3.key: "your-aws-key" + amazon_s3.secret: "your-aws-secret" + amazon_s3.bucket: "your-bucket.example.com" -Now you can set up the services required: +Prerequisites +------------- + +Next, you must define the required services. .. code-block:: yaml + # app/config/services.yml + services: - acme.amazon_s3: - class: AmazonS3 - arguments: - - - key: %amazon_s3.key% - secret: %amazon_s3.secret% - # more S3 specific options, see \AmazonS3::__construct() acme.imagine.cache.resolver.amazon_s3: class: Liip\ImagineBundle\Imagine\Cache\Resolver\AmazonS3Resolver @@ -41,18 +52,52 @@ Now you can set up the services required: - "@acme.amazon_s3" - "%amazon_s3.bucket%" tags: - - { name: 'liip_imagine.cache.resolver', resolver: 'amazon_s3' } + - { name: "liip_imagine.cache.resolver", resolver: "amazon_s3" } -Now you are ready to use the ``AmazonS3Resolver`` by configuring the bundle. -The following example will configure the resolver is default. + acme.amazon_s3: + class: AmazonS3 + arguments: + - + key: "%amazon_s3.key%" + secret: "%amazon_s3.secret%" + +Usage +----- + +After configuring ``AmazonS3Resolver``, you can set it as the default cache resolver +for ``LiipImagineBundle`` using the following configuration. + +.. code-block:: yaml + + # app/config/config.yml + + liip_imagine: + cache: amazon_s3 + + +Usage on a Specific Filter +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Alternatively, you can set ``AmazonS3Resolver`` as the cache resolver for a specific +filter set using the following configuration. .. code-block:: yaml + # app/config/config.yml + liip_imagine: - cache: 'amazon_s3' + filter_sets: + cache: ~ + my_thumb: + cache: amazon_s3 + filters: + # the filter list + +.. tip:: + + If you want to use other buckets for other images, simply alter the parameter + names and create additional services. -If you want to use other buckets for other images, simply alter the parameter -names and create additional services! Object URL Options ------------------ @@ -62,6 +107,8 @@ service, to alter those options you need. .. code-block:: yaml + # app/config/services.yml + services: acme.imagine.cache.resolver.amazon_s3: class: Liip\ImagineBundle\Imagine\Cache\Resolver\AmazonS3Resolver @@ -72,13 +119,15 @@ service, to alter those options you need. # This calls $service->setObjectUrlOption('https', true); - [ setObjectUrlOption, [ 'https', true ] ] tags: - - { name: 'liip_imagine.cache.resolver', resolver: 'amazon_s3' } + - { name: "liip_imagine.cache.resolver", resolver: "amazon_s3" } You can also use the constructor of the resolver to directly inject multiple options. .. code-block:: yaml + # app/config/services.yml + services: acme.imagine.cache.resolver.amazon_s3: class: Liip\ImagineBundle\Imagine\Cache\Resolver\AmazonS3Resolver @@ -88,7 +137,9 @@ options. - "public-read" # AmazonS3::ACL_PUBLIC (default) - { https: true, torrent: true } tags: - - { name: 'liip_imagine.cache.resolver', resolver: 'amazon_s3' } + - { name: "liip_imagine.cache.resolver", resolver: "amazon_s3" } + .. _`aws-sdk-php`: https://github.com/amazonwebservices/aws-sdk-for-php -.. _`installation chapter`: https://getcomposer.org/doc/00-intro.md +.. _`Composer`: https://getcomposer.org/ +.. _`installation documentation`: https://getcomposer.org/doc/00-intro.md diff --git a/Resources/doc/cache-resolver/aws_s3.rst b/Resources/doc/cache-resolver/aws_s3.rst index 5ac8115b8..4b3a3f6b2 100644 --- a/Resources/doc/cache-resolver/aws_s3.rst +++ b/Resources/doc/cache-resolver/aws_s3.rst @@ -1,76 +1,109 @@ -AwsS3Resolver -============= -The AwsS3Resolver requires the `aws-sdk-php`_ library. Open a command -console, enter your project directory and execute the following command to -download the latest stable version of this library: +.. _cache-resolver-aws-s3: + +AWS S3 Resolver +=============== + +The ``AwsS3Resolver`` resolver enables cache resolution using Amazon S3. + + +Dependencies +------------ + +This cache resolver requires the `aws-sdk-php`_ library, which can be installed +by executing the following command in your project directory: .. code-block:: bash $ composer require aws/aws-sdk-php -This command requires you to have Composer installed globally, as explained -in the `installation chapter`_ of the Composer documentation. -Afterwards, you only need to configure some information regarding your AWS -account and the bucket. +.. note:: + + This command requires that `Composer`_ is installed globally, as explained in + their `installation documentation`_. + + +Configuration +------------- + +To begin, you must assign your AWS key, secret, bucket, and region to their respective parameters. .. code-block:: yaml + # app/config/config.yml or app/config/parameters.yml + parameters: - amazon.s3.key: 'your-aws-key' - amazon.s3.secret: 'your-aws-secret' - amazon.s3.bucket: 'your-bucket.example.com' - amazon.s3.region: 'your-bucket-region' + amazon.s3.key: "your-aws-key" + amazon.s3.secret: "your-aws-secret" + amazon.s3.bucket: "your-bucket.example.com" + amazon.s3.region: "your-bucket-region" + -Create resolver using factory ------------------------------ +Prerequisites +------------- + +Create Resolver from a Factory +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. code-block:: yaml + # app/config/config.yml + liip_imagine: resolvers: - profile_photos: - aws_s3: - client_config: - key: %amazon.s3.key% - secret: %amazon.s3.secret% - region: %amazon.s3.region% - bucket: %amazon.s3.cache_bucket% - get_options: - Scheme: 'https' - put_options: - CacheControl: 'max-age=86400' - -If you use `aws-sdk-php`_ library version >= 3.0.0 client config credentials -must be an associative array containing key and secret. + profile_photos: + aws_s3: + client_config: + credentials: + key: "%amazon.s3.key%" + secret: "%amazon.s3.secret%" + region: "%amazon.s3.region%" + bucket: "%amazon.s3.cache_bucket%" + get_options: + Scheme: https + put_options: + CacheControl: "max-age=86400" -.. code-block:: yaml - aws_s3: - client_config: - credentials: - key: %amazon.s3.key% - secret: %amazon.s3.secret% - region: %amazon.s3.region% +.. tip:: + + If using `aws-sdk-php`_ < ``3.0.0``, you must omit the ``credentials`` key and instead + place the ``key`` and ``secret`` keys at the same level as ``region`` and ``bucket``. + + .. code-block:: yaml + + # app/config/services.yml + + services: + aws_s3: + client_config: + key: "%amazon.s3.key%" + secret: "%amazon.s3.secret%" + region: "%amazon.s3.region%" + bucket: "%amazon.s3.cache_bucket%" + + # ... -Create resolver as a service ----------------------------- + +Create Resolver as a Service +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ You have to set up the services required: .. code-block:: yaml + # app/config/services.yml + services: acme.amazon_s3: class: Aws\S3\S3Client factory_class: Aws\S3\S3Client - factory_method: factory + factory_method: factory arguments: - - key: %amazon.s3.key% - secret: %amazon.s3.secret% - region: %amazon.s3.region% + credentials: { key: "%amazon.s3.key%", secret: "%amazon.s3.secret%" } + region: "%amazon.s3.region%" acme.imagine.cache.resolver.amazon_s3: class: Liip\ImagineBundle\Imagine\Cache\Resolver\AwsS3Resolver @@ -78,63 +111,99 @@ You have to set up the services required: - "@acme.amazon_s3" - "%amazon.s3.bucket%" tags: - - { name: 'liip_imagine.cache.resolver', resolver: 'profile_photos' } + - { name: "liip_imagine.cache.resolver", resolver: "amazon_s3" } -If you use `aws-sdk-php`_ library version >= 3.0.0 client config credentials -must be an associative array containing key and secret. -.. code-block:: yaml +.. tip:: + + If using `aws-sdk-php`_ < ``3.0.0``, you must omit the ``credentials`` key and instead + place the ``key`` and ``secret`` keys at the same level as ``region`` and ``bucket``. + + .. code-block:: yaml + + # app/config/services.yml + + services: + acme.amazon_s3: + # ... + arguments: + - + key: "%amazon.s3.key%" + secret: "%amazon.s3.secret%" + region: "%amazon.s3.region%" - acme.amazon_s3: - class: Aws\S3\S3Client - factory_class: Aws\S3\S3Client - factory_method: factory - arguments: - - - credentials: { key: %amazon.s3.key%, secret: %amazon.s3.secret% } - region: %amazon.s3.region% Usage ----- -Now you are ready to use the ``AwsS3Resolver`` by configuring the bundle. -The following example will configure the resolver is default. +After configuring ``AwsS3Resolver``, you can set it as the default cache resolver +for ``LiipImagineBundle`` using the following configuration. .. code-block:: yaml + # app/config/config.yml + liip_imagine: cache: profile_photos -If you want to use other buckets for other images, simply alter the parameter -names and create additional services! -Additional options +Usage on a Specific Filter +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Alternatively, you can set ``AmazonS3Resolver`` as the cache resolver for a specific +filter set using the following configuration. + +.. code-block:: yaml + + # app/config/config.yml + + liip_imagine: + filter_sets: + cache: ~ + my_thumb: + cache: profile_photos + filters: + # the filter list + +.. tip:: + + If you want to use other buckets for other images, simply alter the parameter + names and create additional services. + + +Additional Options ------------------ -You can use :doc:`Cache ` and :doc:`Proxy ` resolvers in chain with +You can use :ref:`Cache ` and :ref:`Proxy ` resolvers in chain with current. You just need to configure them with defined options. .. code-block:: yaml + # app/config/config.yml + liip_imagine: resolvers: profile_photos: aws_s3: - ... - proxies: ['http://one.domain.com', 'http://two.domain.com'] + #... + proxies: ["http://one.domain.com", "http://two.domain.com"] cache: true -If enabled both first one will be :doc:`Cache `, then :doc:`Proxy ` -and after all process delegates to AwsS3 resolver. + +If enabled both first one will be :ref:`Cache `, then +:ref:`Proxy ` and after all process delegates to AwsS3 resolver. + Object GET Options ------------------- +~~~~~~~~~~~~~~~~~~ In order to make use of the object GET options, you can simply add a call to the service, to alter those options you need. .. code-block:: yaml + # app/config/services.yml + services: acme.imagine.cache.resolver.amazon_s3: class: Liip\ImagineBundle\Imagine\Cache\Resolver\AwsS3Resolver @@ -143,14 +212,17 @@ service, to alter those options you need. - "%amazon_s3.bucket%" calls: # This calls $service->setGetOption('Scheme', 'https'); - - [ setGetOption, [ 'Scheme', 'https' ] ] + - [ setGetOption, [ Scheme, https ] ] tags: - - { name: 'liip_imagine.cache.resolver', resolver: 'amazon_s3' } + - { name: "liip_imagine.cache.resolver", resolver: "amazon_s3" } + You can also use the constructor of the resolver to directly inject multiple options. .. code-block:: yaml + # app/config/services.yml + services: acme.imagine.cache.resolver.amazon_s3: class: Liip\ImagineBundle\Imagine\Cache\Resolver\AwsS3Resolver @@ -160,10 +232,11 @@ You can also use the constructor of the resolver to directly inject multiple opt - "public-read" # Aws\S3\Enum\CannedAcl::PUBLIC_READ (default) - { Scheme: https } tags: - - { name: 'liip_imagine.cache.resolver', resolver: 'amazon_s3' } + - { name: "liip_imagine.cache.resolver", resolver: "amazon_s3" } + Object PUT Options ------------------- +~~~~~~~~~~~~~~~~~~ Similar to Object GET Options you can configure additional options to be passed to S3 when storing objects. This is useful, for example, to configure Cache- @@ -179,11 +252,14 @@ ignored, even if you configure it via ObjectOptions: * ``Body`` * ``ContentType`` + In order to make use of the object PUT options, you can simply add a call to the service, to alter those options you need. .. code-block:: yaml + # app/config/services.yml + services: acme.imagine.cache.resolver.amazon_s3: class: Liip\ImagineBundle\Imagine\Cache\Resolver\AwsS3Resolver @@ -192,14 +268,17 @@ service, to alter those options you need. - "%amazon_s3.bucket%" calls: # This calls $service->setPutOption('CacheControl', 'max-age=86400'); - - [ setPutOption, [ 'CacheControl', 'max-age=86400' ] ] + - [ setPutOption, [ CacheControl, "max-age=86400" ] ] tags: - - { name: 'liip_imagine.cache.resolver', resolver: 'amazon_s3' } + - { name: "liip_imagine.cache.resolver", resolver: "amazon_s3" } + You can also use the constructor of the resolver to directly inject multiple options. .. code-block:: yaml + # app/config/services.yml + services: acme.imagine.cache.resolver.amazon_s3: class: Liip\ImagineBundle\Imagine\Cache\Resolver\AwsS3Resolver @@ -208,10 +287,12 @@ You can also use the constructor of the resolver to directly inject multiple opt - "%amazon_s3.bucket%" - "public-read" # Aws\S3\Enum\CannedAcl::PUBLIC_READ (default) - { Scheme: https } - - { CacheControl: 'max-age=86400' } + - { CacheControl: "max-age=86400" } tags: - - { name: 'liip_imagine.cache.resolver', resolver: 'amazon_s3' } + - { name: "liip_imagine.cache.resolver", resolver: "amazon_s3" } + .. _`aws-sdk-php`: https://github.com/amazonwebservices/aws-sdk-for-php -.. _`installation chapter`: https://getcomposer.org/doc/00-intro.md +.. _`Composer`: https://getcomposer.org/ +.. _`installation documentation`: https://getcomposer.org/doc/00-intro.md .. _`S3 SDK documentation`: http://docs.aws.amazon.com/aws-sdk-php/latest/class-Aws.S3.S3Client.html#_putObject diff --git a/Resources/doc/cache-resolver/cache.rst b/Resources/doc/cache-resolver/cache.rst index 14bae1751..6b960218d 100644 --- a/Resources/doc/cache-resolver/cache.rst +++ b/Resources/doc/cache-resolver/cache.rst @@ -1,21 +1,45 @@ -CacheResolver -============= -The ``CacheResolver`` requires the `Doctrine Cache`_ library. +.. _cache-resolver-cache: -This resolver wraps another resolver around a ``Cache``. +Cache Resolver +============== -Now you can set up the services required; by example using the ``AmazonS3Resolver``. +The ``CacheResolver`` cannot be used by itself. Instead, it is a "wrapper" for +another resolver. + + +Dependencies +------------ + +This cache resolver requires the `Doctrine Cache`_ library, which can be installed +by executing the following command in your project directory: + +.. code-block:: bash + + $ composer require doctrine/cache + +.. note:: + + This command requires that `Composer`_ is installed globally, as explained in + their `installation documentation`_. + +Configuration +------------- + +First, you need to setup the required services. In this example we're wrapping an +instance of ``AmazonS3Resolver`` inside this resolver. .. code-block:: yaml + # app/config/services.yml + services: acme.amazon_s3: class: AmazonS3 arguments: - - key: %amazon_s3.key% - secret: %amazon_s3.secret% + key: "%amazon_s3.key%" + secret: "%amazon_s3.secret%" acme.imagine.cache.resolver.amazon_s3: class: Liip\ImagineBundle\Imagine\Cache\Resolver\AmazonS3Resolver @@ -26,39 +50,65 @@ Now you can set up the services required; by example using the ``AmazonS3Resolve memcache: class: Memcache calls: - - [ 'connect', [ '127.0.0.1', 11211 ] ] + - [ connect, [ "127.0.0.1", 11211 ] ] cache.memcache: class: Doctrine\Common\Cache\MemcacheCache calls: - - [ 'setMemcache', [ '@memcache' ] ] + - [ setMemcache, [ "@memcache" ] ] - # The actual acme.imagine.cache.resolver.amazon_s3.cache: class: Liip\ImagineBundle\Imagine\Cache\Resolver\CacheResolver arguments: - "@cache.memcache" - "@acme.imagine.cache.resolver.amazon_s3" - - - prefix: "amazon_s3" + - { prefix: "amazon_s3" } tags: - - { name: 'liip_imagine.cache.resolver', resolver: 'cached_amazon_s3' } + - { name: "liip_imagine.cache.resolver", resolver: "cached_amazon_s3" } -There are currently three options available when configuring the ``CacheResolver``: +There are three options available: -* ``global_prefix`` A prefix for all keys within the cache. This is useful to +* ``global_prefix``: A prefix for all keys within the cache. This is useful to avoid colliding keys when using the same cache for different systems. -* ``prefix`` A "local" prefix for this wrapper. This is useful when re-using the +* ``prefix``: A "local" prefix for this wrapper. This is useful when re-using the same resolver for multiple filters. This mainly affects the clear method. -* ``index_key`` The name of the index key being used to save a list of created +* ``index_key``: The name of the index key being used to save a list of created cache keys regarding one image and filter pairing. -Now you are ready to use the ``CacheResolver`` by configuring the bundle. -The following example will configure the resolver is default. + +Usage +----- + +After configuring ``CacheResolver``, you can set it as the default cache resolver +for ``LiipImagineBundle`` using the following configuration. .. code-block:: yaml + # app/config/config.yml + liip_imagine: - cache: 'cached_amazon_s3' + cache: cached_amazon_s3 + + +Usage on a Specific Filter +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Alternatively, you can set ``CacheResolver`` as the cache resolver for a specific +filter set using the following configuration. + +.. code-block:: yaml + + # app/config/config.yml + + liip_imagine: + filter_sets: + cache: ~ + my_thumb: + cache: cached_amazon_s3 + filters: + # the filter list + -.. _`Doctrine Cache`: https://github.com/doctrine/cache \ No newline at end of file +.. _`Doctrine Cache`: https://github.com/doctrine/cache +.. _`Composer`: https://getcomposer.org/ +.. _`installation documentation`: https://getcomposer.org/doc/00-intro.md diff --git a/Resources/doc/cache-resolver/flysystem.rst b/Resources/doc/cache-resolver/flysystem.rst index c755bda0d..3953688f8 100644 --- a/Resources/doc/cache-resolver/flysystem.rst +++ b/Resources/doc/cache-resolver/flysystem.rst @@ -1,27 +1,48 @@ -FlysystemResolver -================= -This resolver lets you load images onto `Flysystem`_ filesystem abstraction layer, -which can be used in Symfony projects by installing, for example, `OneupFlysystemBundle`_. +.. _cache-resolver-flysystem: -Value of ``filesystem_service`` property must be a service, -which returns an instance of League\\Flysystem\\Filesystem. +Flysystem Resolver +================== -For implementation using `OneupFlysystemBundle`_ look below. +The ``FlysystemResolver`` resolver enabled cache resolution using the `Flysystem`_ +filesystem abstraction layer. -Create resolver ---------------- +Dependencies +------------ + +This cache resolver has a soft dependency on `OneupFlysystemBundle`_, which +can be installed by executing the following command in your project directory: + +.. code-block:: bash + + $ composer require oneup/flysystem-bundle + +.. note:: + + This command requires that `Composer`_ is installed globally, as explained in + their `installation documentation`_. + +Configuration +------------- + +The value of the ``filesystem_service`` property must be a service that returns an +instance of ``League\\Flysystem\\Filesystem``. + +The following implementation uses `OneupFlysystemBundle`_. .. code-block:: yaml + # app/config/config.yml + liip_imagine: resolvers: profile_photos: flysystem: filesystem_service: oneup_flysystem.profile_photos_filesystem - root_url: http://images.example.com - cache_prefix: media/cache - visibility: public + root_url: "http://images.example.com" + cache_prefix: media/cache + visibility: public + oneup_flysystem: adapters: profile_photos: @@ -34,36 +55,53 @@ Create resolver There are several configuration options available: -* ``root_url`` - must be a valid url to the target system the flysystem adapter +* ``root_url``: must be a valid url to the target system the flysystem adapter points to. This is used to determine how the url should be generated upon request. Default value: ``null`` -* ``cache_prefix`` - this is used for the image path generation. This will be the +* ``cache_prefix``: this is used for the image path generation. This will be the prefix inside the given Flysystem. Default value: ``media/cache`` -* ``visibility`` - one of the two predefined flysystem visibility constants +* ``visibility``: one of the two predefined flysystem visibility constants (``AdapterInterface::VISIBILITY_PUBLIC`` [``public``] / ``AdapterInterface::VISIBILITY_PRIVATE`` [``private``]) The visibility is applied, when the objects are stored on a flysystem filesystem. You will most probably want to leave the default or explicitly set ``public``. Default value: ``public`` + Usage ----- +After configuring ``FlysystemResolver``, you can set it as the default cache resolver +for ``LiipImagineBundle`` using the following configuration. + .. code-block:: yaml + # app/config/config.yml + liip_imagine: cache: profile_photos -Usage on a specific filter --------------------------- + +Usage on a Specific Filter +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Alternatively, you can set it as the cache resolver for a specific filter set using +the following configuration. .. code-block:: yaml + # app/config/config.yml + liip_imagine: filter_sets: cache: ~ my_thumb: cache: profile_photos - quality: 75 filters: - thumbnail: { size: [120, 90], mode: outbound } + # the filter list + + +.. _`Flysystem`: https://github.com/thephpleague/flysystem +.. _`OneupFlysystemBundle`: https://github.com/1up-lab/OneupFlysystemBundle +.. _`Composer`: https://getcomposer.org/ +.. _`installation documentation`: https://getcomposer.org/doc/00-intro.md diff --git a/Resources/doc/cache-resolver/proxy.rst b/Resources/doc/cache-resolver/proxy.rst index 4040a5d71..921796348 100644 --- a/Resources/doc/cache-resolver/proxy.rst +++ b/Resources/doc/cache-resolver/proxy.rst @@ -1,30 +1,72 @@ + +.. _cache-resolver-proxy: + ProxyResolver ============= -The ProxyResolver is a ``decorator`` for every other Resolver +The ``ProxyResolver`` cannot be used by itself. Instead, it is a "decorator" for +another resolver. It add the ability to use "Proxy Hosts" for your assets. If no +"Proxy Domains" are set, it behaves like the underlying cache resolver. -This Resolver adds the possibility to use Proxy Hosts for your Assets. If no -Proxy Domains are set, it behaves like the underlying ``Resolver``. +Prerequisites +------------- -Set Proxy Domains ------------------ +Create Service +~~~~~~~~~~~~~~ -In order to use this Resolver you must create a Service and inject some domains -and your underlying Resolver +To use this cache resolver, you must first define the cache resolver it will decorate. +In this example, we will use the :ref:`AWS Cache Resolver `. + +Next, we need to define a service for this cache resolver and inject an array of domains +and the cache resolver service to decorate. .. code-block:: yaml + # app/config/services.yml + services: acme.imagine.cache.resolver.proxy: class: Liip\ImagineBundle\Imagine\Cache\Resolver\ProxyResolver arguments: - "@acme.imagine.cache.resolver.amazon_s3" - - [ 'http://images0.domain.com', 'http://images1.domain.com','http://images2.domain.com' ] + - [ "http://images0.domain.com", "http://images1.domain.com", "http://images2.domain.com" ] tags: - - { name: 'liip_imagine.cache.resolver', resolver: 'proxy' } + - { name: "liip_imagine.cache.resolver", resolver: "proxy" } + +With this configuration, the cache resolver will generate paths such as +``//images0.domain.com/.../image.jpg``, ``//images1.domain.com/.../image.jpg``, and +``//images2.domain.com/.../image.jpg`` (instead of the original path +returned from the decorated cache resolver, in this example using AWS, +``//bucket.s3.awsamazoncloud.com/.../image.jpg``). + +Usage +----- + +After configuring ``ProxyResolver``, you can set it as the default cache resolver +for ``LiipImagineBundle`` using the following configuration. + +.. code-block:: yaml + + # app/config/config.yml + + liip_imagine: + cache: proxy + + +Usage on a Specific Filter +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Alternatively, you can set ``ProxyResolver`` as the cache resolver for a specific +filter set using the following configuration. + +.. code-block:: yaml + # app/config/config.yml -Now your Resolver would generate ``http://images0.domain.com/thumbs/article_thumb/foo.jpg`` -instead of the original path from the underlying Resolver -``bucket.s3.awsamazoncloud.com/thumbs/article_thumb/foo.jpg`` for every relevant -Action. + liip_imagine: + filter_sets: + cache: ~ + my_thumb: + cache: proxy + filters: + # the filter list diff --git a/Resources/doc/cache-resolver/web_path.rst b/Resources/doc/cache-resolver/web_path.rst index f263f8b80..e29521f73 100644 --- a/Resources/doc/cache-resolver/web_path.rst +++ b/Resources/doc/cache-resolver/web_path.rst @@ -1,8 +1,15 @@ -WebPathResolver -=============== -Create resolver ---------------- +.. _cache-resolver-web-path: + +Web Path Resolver +================= + +The ``WebPathResolver`` resolver enabled cache resolution using the +web path of your application. + + +Configuration +------------- .. code-block:: yaml @@ -10,8 +17,8 @@ Create resolver resolvers: profile_photos: web_path: - web_root: %kernel.root_dir%/../web - cache_prefix: media/cache + web_root: "%kernel.root_dir%/../web" + cache_prefix: "media/cache" There are several configuration options available: @@ -25,10 +32,35 @@ There are several configuration options available: the images would be written to the ``web/media/cache/`` directory. Default value: ``/media/cache`` + Usage ----- +After configuring ``WebPathResolver``, you can set it as the default cache resolver +for ``LiipImagineBundle`` using the following configuration. + .. code-block:: yaml + # app/config/config.yml + liip_imagine: cache: profile_photos + + +Usage on a Specific Filter +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Alternatively, you can set ``WebPathResolver`` as the cache resolver for a specific +filter set using the following configuration. + +.. code-block:: yaml + + # app/config/config.yml + + liip_imagine: + filter_sets: + cache: ~ + my_thumb: + cache: profile_photos + filters: + # the filter list diff --git a/Resources/doc/cache-resolvers.rst b/Resources/doc/cache-resolvers.rst index bf70d02d6..64c6e0f43 100644 --- a/Resources/doc/cache-resolvers.rst +++ b/Resources/doc/cache-resolvers.rst @@ -1,57 +1,170 @@ -Built-In CacheResolver -====================== + + +Cache Resolvers +=============== + +A number of built-in cache resolvers are available: .. toctree:: :maxdepth: 1 + :glob: - cache-resolver/web_path - cache-resolver/amazons3 - cache-resolver/aws_s3 - cache-resolver/cache - cache-resolver/proxy + cache-resolver/* -Changing the default cache resolver ------------------------------------ -The default cache is a web path cache that caches images under -``{web}/media/cache/``. You can specify the cache to use per individual -filter_sets. To change the defaults, you can either change the top level -``cache`` option to the name of the cache resolver you want to use by default, -or redefine the default cache resolver by explicitly defining a resolver called -``default``: +Set the Default Cache Resolver +------------------------------ + +The default cache is the :ref:`web path cache resolver `, +which caches images under ``/media/cache/`` within your application web root path. + +You can specify the cache resolver to use per individual ``filter_sets`` or globally. +To set the default cache resolver globally, use: .. code-block:: yaml + # app/config/config.yml + + liip_imagine: + cache: your_resolver + + +To change the default configuration, you can redefine the default cache resolver +by explicitly defining a resolver called ``default``: + +.. code-block:: yaml + + # app/config/config.yml + liip_imagine: resolvers: default: web_path: cache_prefix: custom_path -Custom cache resolver ---------------------- +To change the cache resolver for a specific ``filter_set``, use the following configuration. -The ImagineBundle allows you to add your custom cache resolver classes. The only -requirement is that each cache resolver loader implement the following interface: -``Liip\ImagineBundle\Imagine\Cache\Resolver\ResolverInterface``. - -To tell the bundle about your new cache resolver, register it in the service -container and apply the ``liip_imagine.cache.resolver`` tag to it (example here -in XML): +.. code-block:: yaml -.. code-block:: xml + # app/config/config.yml - - - - - + liip_imagine: + filter_sets: + cache: ~ + my_thumb: + cache: your_resolver + filters: + # the filter list -For more information on the service container, see the `Symfony Service Container`_ -documentation. +Custom Cache Resolver +--------------------- -You can set your custom cache resolver by adding it to the your configuration as -the new default resolver as follows: +You can easily define your own, custom cache resolvers to handle cache resolution +using any imaginable backend. Creating a custom cache resolver begins by creating +a class that implements the ``ResolverInterface``, as shown below. + +.. code-block:: php + + interface ResolverInterface + { + public function isStored($path, $filter); + public function resolve($path, $filter); + public function store(BinaryInterface $binary, $path, $filter); + public function remove(array $paths, array $filters); + } + +The following is a template for creating your own cache resolver. You must provide +implementations for all methods to create a valid cache resolver. + +.. code-block:: php + + + + + + + + + +.. note:: + + For more information on the Service Container, reference the official + `Symfony Service Container documentation`_. + +Now your custom cache resolver can be set as the global default +using the name defined in the ``resolver`` attribute of the ``tags`` key. .. code-block:: yaml @@ -67,10 +180,6 @@ filter set: filter_sets: my_special_style: cache: my_custom_cache - filters: - my_custom_filter: { } -For an example of a cache resolver implementation, refer to -``Liip\ImagineBundle\Imagine\Cache\Resolver\WebPathResolver``. -.. _`Symfony Service Container`: http://symfony.com/doc/current/book/service_container.html +.. _`Symfony Service Container documentation`: http://symfony.com/doc/current/book/service_container.html diff --git a/Resources/doc/commands.rst b/Resources/doc/commands.rst index d985b7184..23248e8a0 100644 --- a/Resources/doc/commands.rst +++ b/Resources/doc/commands.rst @@ -1,7 +1,9 @@ -Commands -======== -Remove cache + +Console Commands +================ + +Remove Cache ------------ All cache for a given paths will be removed: @@ -29,7 +31,8 @@ without parameters: $ php app/console liip:imagine:cache:remove -Resolve cache + +Resolve Cache ------------- .. code-block:: bash diff --git a/Resources/doc/configuration.rst b/Resources/doc/configuration.rst index 289665322..e506071f9 100644 --- a/Resources/doc/configuration.rst +++ b/Resources/doc/configuration.rst @@ -1,3 +1,5 @@ + + Configuration ============= @@ -87,4 +89,5 @@ Each filter set that you specify has the following options: * ``animated`` - support for resizing animated gif (currently not supported by Imagine (PR pending)) + .. _`PHP Manual`: http://php.net/imagepng diff --git a/Resources/doc/data-loader/filesystem.rst b/Resources/doc/data-loader/filesystem.rst index 8a03b01c7..efebdbfbe 100644 --- a/Resources/doc/data-loader/filesystem.rst +++ b/Resources/doc/data-loader/filesystem.rst @@ -1,23 +1,38 @@ -Filesystem -========== -Using factory +.. _data-loaders-filesystem: + +File System Loader +================== + +The ``FileSystem`` data loader allows for loading images from local file system paths. + +.. tip:: + + If you don't configure anything, this loader is used by default. + + +Configuration ------------- +To set this loader for a specific context called ``profile_photos``, use: + .. code-block:: yaml + # app/config/config.yml + liip_imagine: loaders: profile_photos: filesystem: ~ -If you don't configure anything, this loader is set by default. You can -also configure a root dir where to look for the origin images: +You can configure the ``data_root``, used as the root path to search for images: .. code-block:: yaml + # app/config/config.yml + liip_imagine: loaders: profile_photos: filesystem: - data_root: %kernel.root_dir%/../web + data_root: "%kernel.root_dir%/../web" diff --git a/Resources/doc/data-loader/flysystem.rst b/Resources/doc/data-loader/flysystem.rst index b41706d6d..9b96f15d9 100644 --- a/Resources/doc/data-loader/flysystem.rst +++ b/Resources/doc/data-loader/flysystem.rst @@ -1,19 +1,37 @@ -FlysystemLoader -=============== -This loader lets you load images from `Flysystem`_ filesystem abstraction layer, -which can be used in Symfony projects by installing, for example, `OneupFlysystemBundle`_. +.. _data-loaders-flysystem: -Value of ``filesystem_service`` property must be a service, -which returns an instance of League\\Flysystem\\Filesystem. +FlySystem Loader +================ -For implementation using `OneupFlysystemBundle`_ look below. +The ``FlysystemLoader`` lets you load images using the `Flysystem`_ filesystem abstraction +layer. -Using factory +Dependencies +------------ + +This cache resolver has a soft dependency on `OneupFlysystemBundle`_, which +can be installed by executing the following command in your project directory: + +.. code-block:: bash + + $ composer require oneup/flysystem-bundle + +.. note:: + + This command requires that `Composer`_ is installed globally, as explained in + their `installation documentation`_. + + +Configuration ------------- +Using `OneupFlysystemBundle`_, a basic configuration might look like the following. + .. code-block:: yaml + # app/config/config.yml + liip_imagine: loaders: profile_photos: @@ -30,6 +48,13 @@ Using factory profile_photos: adapter: profile_photos +.. note:: + + The value of ``filesystem_service`` must be a service id that returns an instance + of ``League\\Flysystem\\Filesystem``. + .. _`Flysystem`: https://github.com/thephpleague/flysystem .. _`OneupFlysystemBundle`: https://github.com/1up-lab/OneupFlysystemBundle +.. _`Composer`: https://getcomposer.org/ +.. _`installation documentation`: https://getcomposer.org/doc/00-intro.md diff --git a/Resources/doc/data-loader/gridfs.rst b/Resources/doc/data-loader/gridfs.rst index dd31c5db7..9474fd61d 100644 --- a/Resources/doc/data-loader/gridfs.rst +++ b/Resources/doc/data-loader/gridfs.rst @@ -1,10 +1,18 @@ -GridFSLoader -============ -Load your images from `MongoDB GridFS`_. +.. _data-loaders-grid-fs: + +GridFS Loader +============= + +The ``GridFSLoader`` allows you to load your images from `MongoDB GridFS`_. + +Configuration +------------- .. code-block:: yaml + # app/config/config.yml + liip_imagine: filter_sets: my_special_style: @@ -12,20 +20,48 @@ Load your images from `MongoDB GridFS`_. filters: my_custom_filter: { } -Add loader to your services: +Define a service for the loader: + +.. configuration-block:: + + .. code-block:: yaml + + # app/config/services.yml + + services: + liip_imagine.binary.loader.grid_fs: + class: Liip\ImagineBundle\Binary\Loader\GridFSLoader + arguments: + - "@doctrine.odm.mongodb.document_manager" + - Application\ImageBundle\Document\Image + tags: + - { name: "liip_imagine.binary.loader", loader: grid_fs } + + .. code-block:: xml + + + + + + + Application\ImageBundle\Document\Image + + + +Usage +----- + +Reference the image by its ``id`` when piping to the template helper: + +.. configuration-block:: -.. code-block:: xml + .. code-block:: html+twig - - - - Application\ImageBundle\Document\Image - + -Reference the image by its id: + .. code-block:: html+php -.. code-block:: jinja + - .. _`MongoDB GridFS`: http://docs.mongodb.org/manual/applications/gridfs/ diff --git a/Resources/doc/data-loader/stream.rst b/Resources/doc/data-loader/stream.rst index 70898fc29..6316edc3d 100644 --- a/Resources/doc/data-loader/stream.rst +++ b/Resources/doc/data-loader/stream.rst @@ -1,7 +1,13 @@ -StreamLoader -============ -Using factory +.. _data-loaders-stream: + +Stream Loader +============= + +The ``StreamLoader`` allows you to load images using PHP Streams. + + +Configuration ------------- .. code-block:: yaml @@ -12,8 +18,9 @@ Using factory stream: wrapper: gaufrette://profile_photos + Custom ------- +~~~~~~ The ``Liip\ImagineBundle\Binary\Loader\StreamLoader`` allows to read images from any stream (http, ftp, and others…) registered thus allowing you to serve your images from @@ -21,14 +28,16 @@ literally anywhere. The example service definition shows how to use a stream wrapped by the `Gaufrette`_ filesystem abstraction layer. In order to have this example -working, you need to register the stream wrapper first, refer to the `Gaufrette -README`_ on how to do this. +working, you need to register the stream wrapper first, refer to the `Gaufrette README`_ +on how to do this. If you are using the `KnpGaufretteBundle`_ you can make use of the `StreamWrapper configuration`_ to register the filesystems. .. code-block:: yaml + # app/config/services.yml + services: acme.liip_imagine.binary.loader.stream.profile_photos: class: "%liip_imagine.binary.loader.stream.class%" @@ -37,6 +46,7 @@ If you are using the `KnpGaufretteBundle`_ you can make use of the tags: - { name: 'liip_imagine.binary.loader', loader: 'stream.profile_photos' } + Usage ----- @@ -45,10 +55,13 @@ The following example will configure the resolver as default. .. code-block:: yaml + # app/config/config.yml + liip_imagine: data_loader: stream.profile_photos + +.. _`StreamWrapper configuration`: https://github.com/KnpLabs/KnpGaufretteBundle#stream-wrapper .. _`Gaufrette`: https://github.com/KnpLabs/Gaufrette .. _`Gaufrette README`: https://github.com/KnpLabs/Gaufrette/blob/master/README.markdown .. _`KnpGaufretteBundle`: https://github.com/KnpLabs/KnpGaufretteBundle -.. _`StreamWrapper configuration`: https://github.com/KnpLabs/KnpGaufretteBundle#stream-wrapper diff --git a/Resources/doc/data-loaders.rst b/Resources/doc/data-loaders.rst index f05de8a8b..e54ff451f 100644 --- a/Resources/doc/data-loaders.rst +++ b/Resources/doc/data-loaders.rst @@ -1,62 +1,131 @@ -Built-In DataLoader -=================== + + +Data Loaders +============ + +A number of built-in data loaders are available: .. toctree:: :maxdepth: 1 + :glob: + + data-loader/* - data-loader/filesystem - data-loader/gridfs - data-loader/stream - data-loader/flysystem -Other data loaders +Other Data Loaders ------------------ -* `Doctrine PHPCR-ODM`_: you can include the CmfMediaBundle alone if you just - want to use the images but no other CMF features. +* `Doctrine PHPCR-ODM`_: You can include the ``CmfMediaBundle`` alone if you just + want to use the images but no other Symfony CMF features. + + +.. _data-loaders-custom: + +Custom Data Loader +------------------ + +You can easily define your own, custom data loaders to allow you to retrieve you +image data from any imaginable backend. Creating a custom data loader begins by creating +a class that implements the ``LoaderInterface``, as shown below. + +.. code-block:: php + + interface LoaderInterface + { + public function find($path); + } + +As defined in ``LoaderInterface``, the only required method is one named ``find``, +which is provided a relative image path as its singular parameter, and +subsequently provides an instance of ``BinaryInterface`` in return. + +The following is a template for creating your own data loader. You must provide +the implementation for the ``find`` method to create a valid data loader. -Custom image loaders --------------------- +.. code-block:: php -The ImagineBundle allows you to add your custom image loader classes. The only -requirement is that each data loader implements the following interface: -``Liip\ImagineBundle\Binary\Loader\LoaderInterface``. + namespace AppBundle\Imagine\Binary\Loader; -To tell the bundle about your new data loader, register it in the service -container and apply the ``liip_imagine.binary.loader`` tag to it (example here -in XML): + use Liip\ImagineBundle\Binary\BinaryInterface; + use Liip\ImagineBundle\Binary\Loader\LoaderInterface; + use Liip\ImagineBundle\Model\Binary; -.. code-block:: xml + class MyCustomDataLoader implements LoaderInterface + { + /** + * @param mixed $path + * + * @return BinaryInterface + */ + public function find($path) + { + $data = /** @todo: implement logic to read image data */ + $mime = /** @todo: implement logic to determine image mime-type */ - - - - + // return binary instance with data + return new Binary($data, $mime); + } + } -For more information on the service container, see the `Symfony Service Container`_ -documentation. +Once you have defined your custom data loader, you must define it as a service and tag it +with ``liip_imagine.binary.loader``. + +.. note:: + + For more information on the Service Container, reference the official + `Symfony Service Container documentation`_. + +To register ``AppBundle\Imagine\Binary\Loader\MyCustomDataLoader`` with the name +``my_custom_data_loader``, you would use the following configuration. + +.. configuration-block:: + + .. code-block:: yaml + + # app/config/services.yml + + services: + imagine.data.loader.my_custom: + class: AppBundle\Imagine\Binary\Loader\MyCustomDataLoader + arguments: + - "@liip_imagine" + - "%liip_imagine.formats%" + tags: + - { name: "liip_imagine.data.loader", loader: my_custom_data_loader } + + .. code-block:: xml + + + + + + + + You can set your custom data loader by adding it to the configuration as the new default -loader as follows: +loader: .. code-block:: yaml + # app/config/config.yml + liip_imagine: - data_loader: my_custom_data + data_loader: my_custom_data_loader -Alternatively you can only set the custom data loader for just a specific filter set: +Alternatively, you can only set the custom data loader for just a specific filter set: .. code-block:: yaml + # app/config/config.yml + liip_imagine: filter_sets: my_special_style: - data_loader: my_custom_data + data_loader: my_custom_data_loader filters: - my_custom_filter: { } + # your filters -For an example of a data loader implementation, refer to -``Liip\ImagineBundle\Binary\Loader\FileSystemLoader``. +.. _`Symfony Service Container documentation`: http://symfony.com/doc/current/book/service_container.html .. _`Doctrine PHPCR-ODM`: http://symfony.com/doc/master/cmf/bundles/media.html#liipimagine -.. _`Symfony Service Container`: http://symfony.com/doc/current/book/service_container.html diff --git a/Resources/doc/filters.rst b/Resources/doc/filters.rst index 7fb92a6c4..e240084d8 100644 --- a/Resources/doc/filters.rst +++ b/Resources/doc/filters.rst @@ -1,302 +1,125 @@ -Filters -======= - -Built-in Filters ----------------- - -The ``thumbnail`` filter -~~~~~~~~~~~~~~~~~~~~~~~~ - -The thumbnail filter, as the name implies, performs a thumbnail transformation -on your image. - -The ``mode`` can be either ``outbound`` or ``inset``. Option ``inset`` does a -relative resize, where the height and the width will not exceed the values in -the configuration. Option ``outbound`` does a relative resize, but the image -gets cropped if width and height are not the same. -Given an input image sized 50x40 (width x height), consider the following -annotated configuration examples: - -.. code-block:: yaml - - liip_imagine: - filter_sets: - my_thumb_out: - filters: - # Transforms 50x40 to 32x32, while cropping the width - thumbnail: { size: [32, 32], mode: outbound } - my_thumb_in: - filters: - # Transforms 50x40 to 32x26, no cropping - thumbnail: { size: [32, 32], mode: inset } - - -There is also an option ``allow_upscale`` (default: ``false``). By setting -``allow_upscale`` to ``true``, an image which is smaller than 32x32px in the -example above will be expanded to the requested size by interpolation of its -content. Without this option, a smaller image will be left as it. This means you -may get images that are smaller than the specified dimensions. - -The ``relative_resize`` filter -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -The ``relative_resize`` filter may be used to ``heighten``, ``widen``, -``increase`` or ``scale`` an image with respect to its existing dimensions. -These options directly correspond to methods on Imagine's ``BoxInterface``. - -Given an input image sized 50x40 (width, height), consider the following -annotated configuration examples: - -.. code-block:: yaml - - liip_imagine: - filter_sets: - my_heighten: - filters: - relative_resize: { heighten: 60 } # Transforms 50x40 to 75x60 - my_widen: - filters: - relative_resize: { widen: 32 } # Transforms 50x40 to 32x26 - my_increase: - filters: - relative_resize: { increase: 10 } # Transforms 50x40 to 60x50 - my_widen: - filters: - relative_resize: { scale: 2.5 } # Transforms 50x40 to 125x100 - -The ``scale`` filter -~~~~~~~~~~~~~~~~~~~~~~ - -It performs an upscale or downscale transformation on your image to increase its size to the -given dimensions or ratio: - -.. code-block:: yaml - - liip_imagine: - filter_sets: - my_thumb: - filters: - scale: { dim: [600, 750] } #or { to: 1.56 } -> Upscales to [936, 1170] | { to: 0.66 } -> Downscales to [396, 495] - - -The ``upscale`` filter -~~~~~~~~~~~~~~~~~~~~~~ - -It performs an upscale transformation on your image to increase its size to the -given dimensions or ratio: - -.. code-block:: yaml - - liip_imagine: - filter_sets: - my_thumb: - filters: - upscale: { min: [800, 600] } #or { by: 0.7 } -> Upscales to [1360, 1020] - -The ``downscale`` filter -~~~~~~~~~~~~~~~~~~~~~~~~ - -It performs a downscale transformation on your image to reduce its size to the -given dimensions or ratio: - -.. code-block:: yaml - - liip_imagine: - filter_sets: - my_thumb: - filters: - downscale: { max: [1980, 1280] } #or { by: 0.6 } -> Downscales to [792, 512] -The ``crop`` filter -~~~~~~~~~~~~~~~~~~~ - -It performs a crop transformation on your image. The ``start`` option defines -the coordinates of the left-top pixel where the crop begins (the ``[0, 0]`` -coordinates correspond to the top leftmost pixel of the original image). The -``size`` option defines in pixels the width and height (in this order) of the -area cropped: - -.. code-block:: yaml - - liip_imagine: - filter_sets: - my_thumb: - filters: - crop: { start: [10, 20], size: [120, 90] } - -The ``strip`` filter -~~~~~~~~~~~~~~~~~~~~ - -It removes all profiles and comments from your image to reduce its file size -without degrading its quality. This filter provides no configuration options, -so you just need to enable it as follows: - -.. code-block:: yaml - - liip_imagine: - filter_sets: - my_thumb: - filters: - strip: ~ - -The ``background`` filter -~~~~~~~~~~~~~~~~~~~~~~~~~ - -It sets a background color for the image. The default color is white (``#FFF``): - -.. code-block:: yaml - - liip_imagine: - filter_sets: - my_thumb: - filters: - background: { color: '#00FFFF' } - -By default, the background color is only visible through the transparent sections -of the image (if any). However, if you provide a ``size`` option, a new image is -created (with the given size and color) and the original image is placed on top: - -.. code-block:: yaml - - liip_imagine: - filter_sets: - my_thumb: - filters: - background: { size: [1026, 684], position: center, color: '#fff' } - -The ``watermark`` filter -~~~~~~~~~~~~~~~~~~~~~~~~ - -The watermark filter pastes a second image onto your image while keeping its -ratio. Configuration looks like this: - -.. code-block:: yaml - - liip_image: - filter_sets: - my_image: - filters: - watermark: - # Relative path to the watermark file (prepended with "%kernel.root_dir%/") - image: Resources/data/watermark.png - # Size of the watermark relative to the origin images size - size: 0.5 - # Position: One of topleft,top,topright,left,center,right,bottomleft,bottom,bottomright - position: center +Filters +======= -.. note:: +Filters perform image transformation operations. While some filter set +definitions may only require a single filter, more complex definitions +often require many filters. Any number of filters can be chained to +achieve the desired result. - Please note that position of watermark filter is important. If you have some - filters like ``crop`` after it is possible that watermark image will be - cropped. +.. tip:: -The ``auto_rotate`` filter -~~~~~~~~~~~~~~~~~~~~~~~~~~ + You may need to define your own filter to meet your application's specific + requirements. Reference the :ref:`custom filters section ` + for implementation details. -It rotates the image automatically to display it as correctly as possible. The -rotation to apply is obtained through the metadata stored in the EXIF data of -the original image. This filter provides no configuration options, so you just -need to enable it as follows: -.. code-block:: yaml +Built-in filters +---------------- - liip_imagine: - filter_sets: - my_thumb: - filters: - auto_rotate: ~ +A number of built-in filters are provided to fulfill the majority of common +use-cases. -.. note:: - This filter should be called as early as possible to get better results. +.. toctree:: + :maxdepth: 2 -The ``rotate`` filter -~~~~~~~~~~~~~~~~~~~~~ + filters/sizing + filters/orientation + filters/general -It rotates the image based on specified angle (in degrees). The value of the -``angle`` configuration option must be a positive integer or float number: -.. code-block:: yaml +.. _filter-custom: - liip_imagine: - filter_sets: - my_thumb: - filters: - rotate: { angle: 90 } +Custom filters +-------------- -The ``interlace`` filter -~~~~~~~~~~~~~~~~~~~~~~~~ +You can easily define your own, custom filters to perform any image +transformation operations required. Creating a custom filter begins +by creating a class that implements the following interface: -It modifies the way the image is loaded progressively: +.. code-block:: php -.. code-block:: yaml + namespace Liip\ImagineBundle\Imagine\Filter\Loader; - liip_imagine: - filter_sets: - my_thumb: - filters: - interlace: - # mode can be one of: 'none', 'line', 'plane' and 'partition' - mode: line + interface LoaderInterface + { + public function load(ImageInterface $image, array $options = array()); + } -The ``grayscale`` filter -~~~~~~~~~~~~~~~~~~~~~~~~ +As defined in ``LoaderInterface``, the only required method is one named ``load``, +which is provided an instance of ``ImageInterface`` and an array of options, and +subsequently provides an instance of ``ImageInterface`` in return. -It modifies the image colors by calculating the gray-value based on RGB: +The following is a template for creating your own filter. You must provide +the implementation for the ``load`` method to create a valid filter. -.. code-block:: yaml +.. code-block:: php - liip_imagine: - filter_sets: - my_thumb: - filters: - grayscale: ~ + namespace AppBundle\Imagine\Filter\Loader; -Load your Custom Filters ------------------------- + use Imagine\Image\ImageInterface; + use Liip\ImagineBundle\Imagine\Filter\Loader\LoaderInterface; -The ImagineBundle allows you to load your own custom filter classes. The only -requirement is that each filter loader implements the following interface: -``Liip\ImagineBundle\Imagine\Filter\Loader\LoaderInterface``. + class MyCustomFilter implements LoaderInterface + { + /** + * @param ImageInterface $image + * @param array $options + * + * @return ImageInterface + */ + public function load(ImageInterface $image, array $options = array()) + { + /** @todo: implement */ + } + } -To tell the bundle about your new filter loader, register it in the service -container and apply the ``liip_imagine.filter.loader`` tag to it (example here -in XML): +After you have finished implementing your custom filter class, it must be defined +as a service in the Symfony Service Container and tagged with ``liip_imagine.filter.loader``. +To register a our filter, ``AppBundle\Imagine\Filter\Loader\MyCustomFilter``, as +``my_custom_filter``, use the following configuration. .. configuration-block:: .. code-block:: yaml # app/config/services.yml - app.filter.my_custom_filter: - class: AppBundle\Imagine\Filter\Loader\MyCustomFilterLoader - tags: - - { name: 'liip_imagine.filter.loader', loader: 'my_custom_filter' } + + services: + app.filter.my_custom_filter: + class: AppBundle\Imagine\Filter\Loader\MyCustomFilter + tags: + - { name: "liip_imagine.filter.loader", loader: my_custom_filter } .. code-block:: xml - + + -For more information on the service container, see the `Symfony Service Container`_ -documentation. +.. note:: + + For more information on the Service Container, reference the official + `Symfony Service Container documentation`_. -You can now reference and use your custom filter when defining filter sets you'd -like to apply in your configuration: +You can now reference and use your custom filter when defining filter sets in your configuration: .. code-block:: yaml + # app/config/config.yml + liip_imagine: filter_sets: my_special_style: filters: my_custom_filter: { } -For an example of a filter loader implementation, refer to -``Liip\ImagineBundle\Imagine\Filter\Loader\ThumbnailFilterLoader``. + +.. _filter-dynamic: Dynamic filters --------------- @@ -330,198 +153,10 @@ A simple example showing how to change the filter configuration dynamically. return new RedirectResponse($this->cacheManager->resolve($path, $filter), Response::HTTP_MOVED_PERMANENTLY); } -.. note:: +.. tip:: The constant ``Response::HTTP_MOVED_PERMANENTLY`` was introduced in Symfony 2.4. Developers using older versions of Symfony, please replace the constant by ``301``. -Post-Processors ---------------- - -Filters allow modifying the image, but in order to modify the resulting binary -file created by filters, you can use post-processors. Post-processors must -implement ``Liip\ImagineBundle\Imagine\Filter\PostProcessor\PostProcessorInterface``. - -``PostProcessorInterface::process`` method receives ``BinaryInterface`` - -basically, the file containing an image after all filters have been applied. It -should return the ``BinaryInterface`` as well. - -Post-Processors, for this reason, may be safely chained. This is true even if they -operate on different mime-types, meaning that they are perfect for image-specific -optimisation techniques. A number of optimisers, lossy and loss-less, are provided -by default. - -To tell the bundle about your post-processor, register it in the service -container and apply the ``liip_imagine.filter.post_processor`` tag to it: - -.. configuration-block:: - - .. code-block:: yaml - - # app/config/services.yml - app.post_processor.my_custom_post_processor: - class: AppBundle\Imagine\Filter\PostProcessor\MyCustomPostProcessor - tags: - - { name: 'liip_imagine.filter.post_processor', post_processor: 'my_custom_post_processor' } - - .. code-block:: xml - - - - - - -For more information on the service container, see the `Symfony Service Container`_ -documentation. - -You can now reference and use your custom filter when defining filter sets you'd -like to apply in your configuration: - -.. code-block:: yaml - - liip_imagine: - filter_sets: - my_special_style: - post_processors: - my_custom_post_processor: { } - -For an example of a post processor implementation, refer to -``Liip\ImagineBundle\Imagine\Filter\PostProcessor\JpegOptimPostProcessor``. - -The ``JpegOptimPostProcessor`` can be used to provide lossless JPEG -optimization, which is good for you website loading speed. Parameters to configure -stripping of comment and exif data, max quality and progressive rendering may be -passed in optionally. In order to add lossless JPEG optimization to your filters, -use the following configuration: - -.. code-block:: yaml - - liip_imagine: - filter_sets: - my_thumb: - filters: - thumbnail: { size: [150, 150], mode: outbound } - post_processors: - jpegoptim: { strip_all: true, max: 70, progressive: true } - -Make sure that jpegoptim binary is installed on the system. If path to jpegoptim -binary is different from ``/usr/bin/jpegoptim``, adjust the path by overriding -parameters, for example: - -.. code-block:: yaml - - parameters: - liip_imagine.jpegoptim.binary: /usr/local/bin/jpegoptim - -.. _`Symfony Service Container`: http://symfony.com/doc/current/book/service_container.html - -It is also possible to configure other defaults for the conversion process via parameters, -for example: - -.. code-block:: yaml - - parameters: - # When true, this passes down --strip-all to jpegoptim, which strips all markers from the output jpeg. - liip_imagine.jpegoptim.stripAll: true - - # Sets the maxiumum image quality factor. - liip_imagine.jpegoptim.max: null - - # When true, --all-progressive is passed to jpegoptim, which results in the output being a progressive jpeg. - liip_imagine.jpegoptim.progressive: true - - # The directory where temporary file will be written. By default it's empty, and computed using `sys_get_temp_dir()` - # You can set it to `/run/shm` or something similar for writing temporary files in-memory, for decrease of disk load - liip_imagine.jpegoptim.tempDir: "" - -.. _`Symfony Service Container`: http://symfony.com/doc/current/book/service_container.html - - -The ``OptiPngPostProcessor`` is also available by default and can be used just as jpegoptim. -Make sure that optipng binary is installed on the system and change the -``liip_imagine.optipng.binary`` in parameters if needed. - -.. code-block:: yaml - - parameters: - liip_imagine.optipng.binary: /usr/local/bin/optipng - -.. _`Symfony Service Container`: http://symfony.com/doc/current/book/service_container.html - -It is also possible to configure other defaults for the conversion process via parameters, -for example: - -.. code-block:: yaml - - parameters: - # When true, this passes down --strip=all to optipng, which removes all metadata from the output image. - liip_imagine.optipng.stripAll: true - - # The optimisation level to be used by optipng. Defaults to 7. - liip_imagine.optipng.level: 7 - - # The directory where temporary file will be written. By default is empty, and computed using `sys_get_temp_dir()` - # You can set it to `/run/shm` or something similar for writing temporary files in-memory, for decrease of disk load - liip_imagine.optipng.tempDir: "" - -.. _`Symfony Service Container`: http://symfony.com/doc/current/book/service_container.html - - -The ``MozJpegPostProcessor`` can be used to provide safe lossy JPEG optimization. -Optionally, a quality parameter may be passed down to each instance. -More parameters may surface in the future. - -.. code-block:: yaml - - liip_imagine: - filter_sets: - my_thumb: - filters: - thumbnail: { size: [150, 150], mode: outbound } - post_processors: - mozjpeg: {} - my_other_thumb: - filters: - thumbnail: { size: [150, 150], mode: outbound } - post_processors: - mozjpeg: { quality: 90 } - -Make sure that you have installed the mozjpeg tools on your system, and please adjust the -``liip_imagine.mozjpeg.binary`` in parameters if needed. - -.. code-block:: yaml - - parameters: - liip_imagine.mozjpeg.binary: /opt/mozjpeg/bin/cjpeg - -.. _`Symfony Service Container`: http://symfony.com/doc/current/book/service_container.html - - -The ``PngquantPostProcessor`` can be used to provide safe lossy PNG optimization. -Optionally, a quality parameter may be passed down to each instance. -More parameters may surface in the future. - -.. code-block:: yaml - - liip_imagine: - filter_sets: - my_thumb: - filters: - thumbnail: { size: [150, 150], mode: outbound } - post_processors: - pngquant: {} - my_other_thumb: - filters: - thumbnail: { size: [150, 150], mode: outbound } - post_processors: - pngquant: { quality: "80-100" } - -Make sure that you have installed a recent version (at least 2.3) of pngquant on your system, and please adjust the -``liip_imagine.pngquant.binary`` in parameters if needed. - -.. code-block:: yaml - - parameters: - liip_imagine.pngquant.binary: /usr/bin/pngquant -.. _`Symfony Service Container`: http://symfony.com/doc/current/book/service_container.html +.. _`Symfony Service Container documentation`: http://symfony.com/doc/current/book/service_container.html diff --git a/Resources/doc/filters/general.rst b/Resources/doc/filters/general.rst new file mode 100644 index 000000000..82b0fadbf --- /dev/null +++ b/Resources/doc/filters/general.rst @@ -0,0 +1,213 @@ + + +General Filters +=============== + +.. _filter-background: + +Background +---------- + +The built-in ``background`` filter performs layer transformations +(which includes creating and mergin layer operations). This +filter exposes a number of `background options`_ which may be used +to configure its behavior. + +Example configuration: + +.. code-block:: yaml + + # app/config/config.yml + + liip_imagine: + filter_sets: + + # name our filter set "my_background_filter" + my_background_filter: + filters: + + # use and setup the "background" filter + background: + + # set the background color to #00ffff + color: '#00ffff' + + # set a size different from the input image + size: [1026, 684] + + # center input image on the newly created background + position: center + + +.. note:: + + The background color is only visible through transparent image sections (if + any), unless a **size** option is provided, in which case a new image is + created and the input image is placed on top according to the **position** option. + + +Background Options +~~~~~~~~~~~~~~~~~~ + +:strong:`color:` ``string`` + Sets the background color HEX value. The default color is white (``#fff``). + +:strong:`size:` ``int[]`` + Sets the generated background size as an integer array containing the dimensions + as width and height values. + +:strong:`position:` ``string`` + Sets the position of the input image on the newly created background image. Valid + values: ``topleft``, ``top``, ``topright``, ``left``, ``center``, ``right``, ``bottomleft``, + ``bottom``, and ``bottomright``. + +.. _filter-grayscale: + +Grayscale +--------- + +The built-in ``grayscale`` filter performs color transformations +(which includes gray value calculations). This +filter does not exposes any options which may be used +to configure its behavior. + +Example configuration: + +.. code-block:: yaml + + # app/config/config.yml + + liip_imagine: + filter_sets: + + # name our filter set "my_grayscale_filter" + my_grayscale_filter: + filters: + + # use and setup the "grayscale" filter + grayscale: ~ + + +.. _filter-interlace: + +Interlace +--------- + +The built-in ``interlace`` filter performs file transformations +(which includes modifying the encoding method). This +filter exposes a number of `interlace options`_ which may be used +to configure its behavior. + +Example configuration: + +.. code-block:: yaml + + # app/config/config.yml + + liip_imagine: + filter_sets: + + # name our filter set "my_interlace_filter" + my_interlace_filter: + filters: + + # use and setup the "interlace" filter + interlace: + + # set the interlace mode to line + mode: line + + +Interlace Options +~~~~~~~~~~~~~~~~~ + +:strong:`mode:` ``string`` + Sets the interlace mode to encode the file with. Valid values: ``none``, ``line``, + ``plane``, and ``partition``. + + +.. _filter-strip: + +Strip +----- + + +The built-in ``strip`` filter performs file transformations +(which includes metadata removal). This +filter does not exposes any options which may be used +to configure its behavior. + +Example configuration: + +.. code-block:: yaml + + # app/config/config.yml + + liip_imagine: + filter_sets: + + # name our filter set "my_strip_filter" + my_strip_filter: + filters: + + # use and setup the "strip" filter + strip: ~ + + +.. _filter-watermark: + +Watermark +--------- + +The built-in ``watermark`` filter merge transformations +(which includes creating and merging image operations). This +filter exposes a number of `watermark options`_ which may be used +to configure its behavior. + +Example configuration: + +.. code-block:: yaml + + # app/config/config.yml + + liip_imagine: + filter_sets: + + # name our filter set "my_watermark_filter" + my_watermark_filter: + filters: + + # use and setup the "watermark" filter + watermark: + + # path to the watermark file (prepended with "%kernel.root_dir%") + image: Resources/data/watermark.png + + # size of the water mark relative to the input image + size: 0.5 + + # set the position of the watermark + position: center + + +Watermark Options +~~~~~~~~~~~~~~~~~ + +:strong:`image:` ``string`` + Sets the location of the watermark image. The value of this option is prepended + with the resolved value of the ``%kernel.root_dir%`` parameter. + +:strong:`size:` ``float`` + Sets the size of the watermark as a relative ration, relative to the original + input image. + +:strong:`position:` ``string`` + Sets the position of the watermark on the input image. Valid values: ``topleft``, + ``top``, ``topright``, ``left``, ``center``, ``right``, ``bottomleft``, ``bottom``, and + ``bottomright``. + +.. caution:: + + The chosen watermark position and order this filter is called is important. + For example, calling a ``crop`` afterwards could unintentionally remove the + watermark entirely. diff --git a/Resources/doc/filters/orientation.rst b/Resources/doc/filters/orientation.rst new file mode 100644 index 000000000..50f41db42 --- /dev/null +++ b/Resources/doc/filters/orientation.rst @@ -0,0 +1,74 @@ + + +Orientation Filters +=================== + +.. _filter-auto-rotate: + +Auto Rotate +----------- + +The built-in ``auto_rotate`` filter performs orientation transformations +(which includes rotating the image). This filter does not expose any +options to configure its behavior. + +Example configuration: + +.. code-block:: yaml + + # app/config/config.yml + + liip_imagine: + filter_sets: + + # name our filter set "my_auto_rotate_filter" + my_auto_rotate_filter: + filters: + + # use the "auto_rotate" filter + auto_rotate: ~ + +.. tip:: + + This filter should be called as early as possible to get the best results. + + +.. _filter-rotate: + +Rotate +------ + +The built-in ``rotate`` filter performs orientation transformations (specifically +image rotation). This filter exposes `rotate options`_ which may be used to +configure its behavior. + +Example configuration: + +.. code-block:: yaml + + # app/config/config.yml + + liip_imagine: + filter_sets: + + # name our filter set "my_rotate_filter" + my_rotate_filter: + filters: + + # use the "rotate" filter + rotate: + + # set the degree to rotate the image + angle: 90 + + +Rotate Options +~~~~~~~~~~~~~~ + +:strong:`degree:` ``float`` + Sets the "rotation angle" that defines the degree to rotate the image. Must be a + positive number. + +.. _`BoxInterface`: http://imagine.readthedocs.io/en/latest/usage/coordinates.html#boxinterface +.. _`Imagine Library`: http://imagine.readthedocs.io/en/latest/ + diff --git a/Resources/doc/filters/sizing.rst b/Resources/doc/filters/sizing.rst new file mode 100644 index 000000000..f1332e74b --- /dev/null +++ b/Resources/doc/filters/sizing.rst @@ -0,0 +1,361 @@ + + +Size Filters +============ + + +.. _filter-thumbnail: + +Thumbnails +---------- + +The built-in ``thumbnail`` filter performs thumbnail transformations +(which includes scaling and potentially cropping operations). This +filter exposed a number of `thumbnail options`_ which may be used +to configure its behavior. + +Example configuration: + +.. code-block:: yaml + + # app/config/config.yml + + liip_imagine: + filter_sets: + + # name our filter set "my_thumb_filter" + my_thumb_filter: + filters: + + # use and setup the "thumbnail" filter + thumbnail: + + # set the thumbnail size to "32x32" pixels + - size: [32, 32] + + # crop the input image, if required + - mode: outbound + +.. seealso:: + + More examples are available in the + :ref:`Basic Usage: Create Thumbnails ` chapter. + + +Thumbnail Options +~~~~~~~~~~~~~~~~~ + +:strong:`mode:` ``string`` + Sets the desired resize method: ``'outbound'`` crops the image as required, while + ``'inset'`` performs a non-cropping relative resize. + +:strong:`size:` ``int[]`` + Sets the generated thumbnail size as an integer array containing the dimensions + as width and height values. + +:strong:`allow_upscale:` ``bool`` + Toggles allowing image up-scaling when the image is smaller than the desired + thumbnail size. + + +.. _filter-crop: + +Cropping Images +--------------- + +The built-in ``crop`` filter performs sizing transformations (which +includes cropping operations). This filter exposed a number of +`crop options`_ which may be used to configure its behavior. + +Example configuration: + +.. code-block:: yaml + + # app/config/config.yml + + liip_imagine: + filter_sets: + + # name our filter set "my_crop_filter" + my_crop_filter: + filters: + + # use and setup the "crop" filter + crop: + + # set the size of the cropping area + - size: [ 300, 600 ] + + # set the starting coordinates of the crop + - start: [ 040, 160 ] + + +Crop Options +~~~~~~~~~~~~ + +:strong:`size:` ``int[]`` + Sets the crop size as an integer array containing the dimensions as width and + height values. + +:strong:`start:` ``int[]`` + Sets the top, left-post anchor coordinates where the crop operation starts. + + +.. _filter-relative-resize: + +Relative Resize +--------------- + +The built-in ``relative_resize`` filter performs sizing transformations (specifically +relative resizing). This filter exposed a number of `relative resize options`_ which +may be used to configure its behavior. + +Example configuration: + +.. code-block:: yaml + + # app/config/config.yml + + liip_imagine: + filter_sets: + + # name our first filter set "my_heighten_filter" + my_heighten_filter: + filters: + + # use and setup the "relative_resize" filter + relative_resize: + + # given 50x40px, output 75x60px using "heighten" option + - heighten: 60 + + # name our second filter set "my_widen_filter" + my_widen_filter: + + # use and setup the "relative_resize" filter + relative_resize: + + # given 50x40px, output 32x26px using "widen" option + - widen: 32 + + # name our second filter set "my_increase_filter" + my_increase_filter: + + # use and setup the "relative_resize" filter + relative_resize: + + # given 50x40px, output 60x50px, using "increase" option + - increase: 10 + + # name our second filter set "my_scale_filter" + my_scale_filter: + + # use and setup the "relative_resize" filter + relative_resize: + + # given 50x40px, output 125x100px using "scale" option + - scale: 2.5 + + +.. tip:: + + The "relative resize" filter options map directly to the methods of the + `BoxInterface`_ interface provided by the `Imagine Library`_. + + +Relative Resize Options +~~~~~~~~~~~~~~~~~~~~~~~ + +:strong:`heighten:` ``float`` + Sets the "desired height" which initiates a proportional scale operation that up- or + down-scales until the image height matches this value. + +:strong:`widen:` ``float`` + Sets the "desired width" which initiates a proportional scale operation that up- or + down-scales until the image width matches this value. + +:strong:`increase:` ``float`` + Sets the "desired additional size" which initiates a scale operation computed by + adding this value to all image sides. + +:strong:`scale:` ``float`` + Sets the "ratio multiple" which initiates a proportional scale operation computed + by multiplying all image sides by this value. + + +.. _filter-scale: + +Scale +----- + +The built-in ``scale`` filter performs sizing transformations (specifically +image scaling). This filter exposed a number of `scale options`_ which +may be used to configure its behavior. + +Example configuration: + +.. code-block:: yaml + + # app/config/config.yml + + liip_imagine: + filter_sets: + + # name our first filter set "my_ratio_down_scale_filter" + my_ratio_down_scale_filter: + filters: + + # use and setup the "scale" filter + scale: + + # given 1920x1600px -> output 960x800px (relative down-scale) + - to: 0.5 + + # name our first filter set "my_ratio_up_scale_filter" + my_ratio_up_scale_filter: + filters: + + # use and setup the "scale" filter + scale: + + # given 1920x1600px -> output 5760x3200px (relative up-scale) + - to: 2 + + # name our third filter set "my_dim_down_scale_filter" + my_dim_down_scale_filter: + filters: + + # use and setup the "scale" filter + scale: + + # input 1200x1600px -> output 750x1000px (relative down-scale) + - dim: [ 800, 1000 ] + + # name our fourth filter set "my_dim_up_scale_filter" + my_dim_up_scale_filter: + filters: + + # use and setup the "scale" filter + scale: + + # input 300x900px -> output 900x2700px (relative up-scale) + - dim: [ 1200, 2700 ] + + +Scale Options +~~~~~~~~~~~~~ + +:strong:`dim:` ``int[]`` + Sets the "desired dimensions" as an array containing a width and height integer, from + which a relative resize is performed within these constraints. + +:strong:`to:` ``float`` + Sets the "ratio multiple" which initiates a proportional scale operation computed + by multiplying all image sides by this value. + + +.. _filter-down-scale: + +Down Scale +---------- + +The built-in ``downscale`` filter performs sizing transformations (specifically +image down-scaling). This filter exposed a number of `down scale options`_ which +may be used to configure its behavior. + +Example configuration: + +.. code-block:: yaml + + # app/config/config.yml + + liip_imagine: + filter_sets: + + # name our first filter set "my_max_down_scale_filter" + my_max_down_scale_filter: + filters: + + # use and setup the "downscale" filter + downscale: + + # input 3960x2560px -> output 1980x1280px + max: [1980, 1280] + + # name our second filter set "my_by_down_scale_filter" + my_by_down_scale_filter: + filters: + + # use and setup the "downscale" filter + downscale: + + # input 1980x1280px -> output 792x512px + by: 0.6 + + +Down Scale Options +~~~~~~~~~~~~~~~~~~ + +:strong:`max:` ``int[]`` + Sets the "desired max dimensions" as an array containing a width and height integer, from + which a down-scale is performed to meet the passed constraints. + +:strong:`by:` ``float`` + Sets the "ratio multiple" which initiates a proportional scale operation computed + by multiplying all image sides by this value. + + +.. _filter-up-scale: + +Up Scale +-------- + +The built-in ``upscale`` filter performs sizing transformations (specifically +image up-scaling). This filter exposed a number of `up scale options`_ which +may be used to configure its behavior. + +Example configuration: + +.. code-block:: yaml + + # app/config/config.yml + + liip_imagine: + filter_sets: + + # name our first filter set "my_min_up_scale_filter" + my_min_up_scale_filter: + filters: + + # use and setup the "upscale" filter + upscale: + + # input 1980x1280px -> output 3960x2560px + min: [3960, 2560] + + # name our second filter set "my_by_up_scale_filter" + my_by_up_scale_filter: + filters: + + # use and setup the "upscale" filter + upscale: + + # input 800x600px -> output 1360x1020px + by: 0.7 + + +Up Scale Options +~~~~~~~~~~~~~~~~ + +:strong:`min:` ``int[]`` + Sets the "desired min dimensions" as an array containing a width and height integer, from + which an up-scale is performed to meet the passed constraints. + +:strong:`by:` ``float`` + Sets the "ratio multiple" which initiates a proportional scale operation computed + by multiplying all image sides by this value. + + +.. _`BoxInterface`: http://imagine.readthedocs.io/en/latest/usage/coordinates.html#boxinterface +.. _`Imagine Library`: http://imagine.readthedocs.io/en/latest/ + diff --git a/Resources/doc/index.rst b/Resources/doc/index.rst index 4df5e0762..d801c0c44 100644 --- a/Resources/doc/index.rst +++ b/Resources/doc/index.rst @@ -1,19 +1,49 @@ + + LiipImagineBundle ================= -This bundle allows to alter images in certain ways, such as scaling or rotating -them, creating thumbnails, adding watermarks, etc. In order to not hurt application -performance, altered images can be cached locally and in Amazon S3 service. +Overview +-------- + +The `LiipImagineBundle`_ package provides an *image manipulation abstraction toolkit* +for Symfony-based projects. Features include: + +* :doc:`Filter Sets `: Using any Symfony-supported configuration language + (such as YML and XML), you can create *filter set* definitions that specify + transformation routines. These include a set of *filters* and *post-processors*, as + well as other, optional parameters. +* :doc:`Filters `: A number of built-in filters are provided, allowing for an array of + common image transformations. Examples include :ref:`thumbnail `, + :ref:`scale `, :ref:`crop `, :ref:`strip `, + and :ref:`watermark `, and many more. Additionally, + :ref:`custom filters ` are supported. +* :doc:`Post-Processors `: A number of build-in post-processors are provided, + allowing for the modification of the resulting binary file created by filters. Examples include + :ref:`JpegOptim `, :ref:`OptiPNG `, + :ref:`MozJpeg `, and :ref:`PngQuant `. Additionally, + :ref:`custom post-processors ` are supported. + + +Chapters +-------- + +Jump into any of the available chapters to learn more about anything from the basic +usage to the architecture of bundle. .. toctree:: - :maxdepth: 1 + :maxdepth: 2 installation introduction basic-usage filters + post-processors configuration data-loaders cache-resolvers cache-manager commands + + +.. _`LiipImagineBundle`: https://github.com/liip/LiipImagineBundle diff --git a/Resources/doc/installation.rst b/Resources/doc/installation.rst index 8bb366dc2..d140e42f3 100644 --- a/Resources/doc/installation.rst +++ b/Resources/doc/installation.rst @@ -1,28 +1,34 @@ + + Installation ============ Step 1: Download the Bundle --------------------------- -Open a command console, enter your project directory and execute the -following command to download the latest stable version of this bundle: +Open a command console, enter your project directory, and execute the +following command to download the latest stable version of this bundle +and add it as a dependency to your project: .. code-block:: bash $ composer require liip/imagine-bundle -This command requires you to have Composer installed globally, as explained -in the `installation chapter`_ of the Composer documentation. +This command requires that `Composer`_ is installed globally, as explained in +the `installation documentation`_ for Composer. + Step 2: Enable the Bundle ------------------------- -Then, enable the bundle by adding the following line in the ``app/AppKernel.php`` -file of your project: +Then, enable the bundle by adding ``new Liip\ImagineBundle\LiipImagineBundle()`` +to the bundles array of the ``registerBundles`` method in your project's +``app/AppKernel.php`` file: .. code-block:: php - # app/config/routing.yml - _liip_imagine: - resource: "@LiipImagineBundle/Resources/config/routing.xml" +Congratulations; you are ready to rock your images! -Congratulations! You're ready to rock your images! -.. _`installation chapter`: https://getcomposer.org/doc/00-intro.md +.. _`installation documentation`: https://getcomposer.org/doc/00-intro.md +.. _`Composer`: https://getcomposer.org/ diff --git a/Resources/doc/introduction.rst b/Resources/doc/introduction.rst index d4e9c4d9a..950c3126f 100644 --- a/Resources/doc/introduction.rst +++ b/Resources/doc/introduction.rst @@ -1,5 +1,7 @@ -LiipImagineBundle -================= + + +Introduction +============ Basic Data Flow --------------- @@ -8,6 +10,7 @@ The core feature of this bundle is to provide a way to alter images in certain ways and cache the altered versions. There are several components involved to get this done. + Retrieving the original image ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -31,6 +34,7 @@ The most important parts about those ``DataLoader``: Check out the :doc:`chapter about data loaders ` to learn more about them. + Apply filters on the original image ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -51,6 +55,7 @@ customize the outcome. Check out the :doc:`chapter about filters ` to learn more about them. + Cache the filtered image ~~~~~~~~~~~~~~~~~~~~~~~~ @@ -67,8 +72,7 @@ image in the web directory as a static file, so the web server won't call the application stack anymore on those images. The images will be created upon first request and will remain in their static cached version until removed. -A ``CacheResolver`` implements the -``Liip\ImagineBundle\Imagine\Cache\Resolver\ResolverInterface``. +A ``CacheResolver`` implements the ``Liip\ImagineBundle\Imagine\Cache\Resolver\ResolverInterface``. It handles the so-called ``path``, which is the identifier you use, when addressing the original image, e.g. in your template. This path relates to the diff --git a/Resources/doc/post-processors.rst b/Resources/doc/post-processors.rst new file mode 100644 index 000000000..67ebb1c1c --- /dev/null +++ b/Resources/doc/post-processors.rst @@ -0,0 +1,181 @@ + + +Post-Processors +=============== + +We already know that :doc:`filters ` perform image transformation. This may +leave you wondering how post-processors fit into the runtime. To help illustrate the +difference between filters and post-processors, it is important to highlight the following. + +* Filters modify the **image**. +* Post-processors modify the **image binary**. + +After all filters have run, the result is an image binary. This is then provided to, +processed by, and returned from all configured post-processors. + +.. tip:: + + Post-Processors can be safely chained, even if they operate on different mime-types. + This makes them perfect for image-specific optimisation techniques. + + +Built-in processors +------------------- + +A number of built-in post-processors are provided by default. + + +Image Optimizers +~~~~~~~~~~~~~~~~ + +Post-processors of the *image optimizer* classification are intended to reduce the +final image file size, and therefore improve the load performance of your +application's assets. + +.. toctree:: + :maxdepth: 1 + :glob: + + post-processors/* + + +.. _post-processors-custom: + +Custom processors +----------------- + +Just like filters, you can easily define your own, custom post-processors to +perform any image binary operations required. Creating a custom post-processor +begins by creating a class that implements the ``PostProcessorInterface`` +interface, as shown below. + +.. code-block:: php + + interface PostProcessorInterface + { + public function process(BinaryInterface $binary); + } + +As defined in ``PostProcessorInterface``, the only required method is one named ``process``, +which is provided an instance of ``BinaryInterface`` as its singular parameter, and +subsequently provides an instance of ``BinaryInterface`` in return. + +.. tip:: + + You may optionally implement ``ConfigurablePostProcessorInterface`` in your + post-processor to allow it to be configurable. + +The following is a template for creating your own post-processor that calls an executable. +You must set the ``EXECUTABLE_PATH`` class constant to the absolute path of the desired +executable. You may also want to change ``array('image/png')`` to the supported mime types +for your custom post-processor. + +.. code-block:: php + + namespace AppBundle\Imagine\Filter\PostProcessor; + + use Liip\ImagineBundle\Binary\BinaryInterface; + use Liip\ImagineBundle\Model\Binary; + use Liip\ImagineBundle\Imagine\Filter\PostProcessor\PostProcessorInterface; + use Symfony\Component\Process\Exception\ProcessFailedException; + use Symfony\Component\Process\ProcessBuilder; + + class MyCustomPostProcessor implements PostProcessorInterface + { + const EXECUTABLE_PATH = '/path/to/your/executable'; + + /** + * @param BinaryInterface $binary + * + * @return BinaryInterface + */ + public function process(BinaryInterface $binary) + { + // ensure the passed binary is a png + if (!in_array(strtolower($binary->getMimeType()), array('image/png'))) { + return $binary; + } + + // create a temporary input file + if (false === $input = tempnam($path = sys_get_temp_dir(), 'custom_')) { + throw new \Exception(sprintf('Error created tmp file in "%s".', $path)); + } + + // populate temporary file with passed file contents + file_put_contents($input, $binary->getContent()); + + // create a process builder, add the input file as argument + $pb = new ProcessBuilder(array(self::EXECUTABLE_PATH)); + $pb->add($input); + + // get a process instance and run it + $process = $pb->getProcess(); + $process->run(); + + // error out if command returned non-zero + if (0 !== $process->getExitCode()) { + unlink($input); + throw new ProcessFailedException($process); + } + + // retrieve the result + $result = new Binary( + file_get_contents($input), + $binary->getMimeType(), + $binary->getFormat() + ); + + // remove temporary file + unlink($input); + + // return the result + return $result; + } + } + +Once you have defined your custom post-processor, you must define it as a service and tag it +with ``liip_imagine.filter.post_processor``. + +.. note:: + + For more information on the Service Container, reference the official + `Symfony Service Container documentation`_. + +To register ``AppBundle\Imagine\Filter\PostProcessor\MyCustomPostProcessor`` with the name +``my_custom_post_processor``, you would use the following configuration. + +.. configuration-block:: + + .. code-block:: yaml + + # app/config/services.yml + + app.post_processor.my_custom_post_processor: + class: AppBundle\Imagine\Filter\PostProcessor\MyCustomPostProcessor + tags: + - { name: 'liip_imagine.filter.post_processor', post_processor: 'my_custom_post_processor' } + + .. code-block:: xml + + + + + + + +Now your custom post-processor can be referenced in a filter set using the name +assigned via the ``post_processor`` tag attribute above (in this example, +``my_custom_post_processor``). + +.. code-block:: yaml + + # app/config/config.yml + + liip_imagine: + filter_sets: + my_special_style: + post_processors: + my_custom_post_processor: { } + + +.. _`Symfony Service Container documentation`: http://symfony.com/doc/current/book/service_container.html diff --git a/Resources/doc/post-processors/jpeg-moz.rst b/Resources/doc/post-processors/jpeg-moz.rst new file mode 100644 index 000000000..9857674ab --- /dev/null +++ b/Resources/doc/post-processors/jpeg-moz.rst @@ -0,0 +1,51 @@ + +.. _post-processor-mozjpeg: + +Moz JPEG +======== + +The ``MozJpegPostProcessor`` is a built-in post-processor that performs a number of +*safe, lossy* optimizations on *JPEG* encoded images. +To add this post-processor to the filter set created in the +:ref:`thumbnail usage example ` use: + +.. code-block:: yaml + + # app/config/config.yml + + liip_imagine: + filter_sets: + my_thumb: + filters: + thumbnail: { size: [120, 90], mode: outbound } + background: { size: [124, 94], position: center, color: '#000' } + post_processors: + mozjpeg: { quality: 70 } + +This configuration sets a maximum quality factor of 70 for the resulting image binary. + +.. note:: + + The default executable path is ``/opt/mozjpeg/bin/cjpeg``. If installed elsewhere + on your system, you must set the ``liip_imagine.mozjpeg.binary`` parameter accordingly. + + .. code-block:: yaml + + # app/config/config.yml + + parameters: + liip_imagine.mozjpeg.binary: /your/custom/path/to/cjpeg + + +Options +------- + +:strong:`quality:` ``int`` + Sets the image quality factor. + + +Parameters +---------- + +:strong:`liip_imagine.mozjpeg.binary:` ``string`` + Sets the location of the ``cjpeg`` executable. Default is ``/opt/mozjpeg/bin/cjpeg``. diff --git a/Resources/doc/post-processors/jpeg-optim.rst b/Resources/doc/post-processors/jpeg-optim.rst new file mode 100644 index 000000000..b125fa7a8 --- /dev/null +++ b/Resources/doc/post-processors/jpeg-optim.rst @@ -0,0 +1,78 @@ + +.. _post-processor-jpegoptim: + +JPEG Optim +========== + +The ``JpegOptimPostProcessor`` is a built-in post-processor that performs a number of +*lossless* optimizations on *JPEG* encoded images. + +To add this post-processor to the filter set created in the +:ref:`thumbnail usage example ` use: + +.. code-block:: yaml + + # app/config/config.yml + + liip_imagine: + filter_sets: + my_thumb: + filters: + thumbnail: { size: [120, 90], mode: outbound } + background: { size: [124, 94], position: center, color: '#000' } + post_processors: + jpegoptim: { strip_all: true, max: 70, progressive: true } + +This configuration enables metadata stripping and progressive JPEG encoding, and sets +a maximum quality factor of 70 for the resulting image binary. + +.. note:: + + The default executable path is ``/usr/bin/jpegoptim``. If installed elsewhere + on your system, you must set the ``liip_imagine.jpegoptim.binary`` parameter accordingly. + + .. code-block:: yaml + + # app/config/config.yml + + parameters: + liip_imagine.jpegoptim.binary: /your/custom/path/to/jpegoptim + + +Options +------- + +:strong:`strip_all:` ``bool`` + Removes all comments, EXIF markers, and other image metadata. + +:strong:`max:` ``int`` + Sets the maximum image quality factor. + +:strong:`progressive:` ``bool`` + Ensures the image uses progressive encoding. + + +Parameters +---------- + +:strong:`liip_imagine.jpegoptim.stripAll:` ``bool`` + Removes all comments, EXIF markers, and other metadata from the image binary. + +:strong:`liip_imagine.jpegoptim.max:` ``int`` + Assigns the maximum quality factor for the image binary. + +:strong:`liip_imagine.jpegoptim.progressive:` ``bool`` + Ensures that progressive encoding is enabled for the image binary. + +:strong:`liip_imagine.jpegoptim.binary:` ``string`` + Sets the location of the ``jpegoptim`` executable. Default is ``/usr/bin/jpegoptim``. + +:strong:`liip_imagine.jpegoptim.tempDir:` ``string`` + Sets the directory to store temporary files. + + +.. tip:: + + The value of ``liip_imagine.jpegoptim.tempDir`` can be set to an in-memory mount point + on supported operating systems, such as ``/run/shm`` on Linux. This will decrease disk + load and may increase performance. diff --git a/Resources/doc/post-processors/png-opti.rst b/Resources/doc/post-processors/png-opti.rst new file mode 100644 index 000000000..0e884e22f --- /dev/null +++ b/Resources/doc/post-processors/png-opti.rst @@ -0,0 +1,72 @@ + +.. _post-processor-optipng: + +Opti PNG +======== + +The ``OptiPngPostProcessor`` is a built-in post-processor that performs a number of +*lossless* optimizations on *PNG* encoded images. + +To add this post-processor to the filter set created in the +:ref:`thumbnail usage example ` use: + +.. code-block:: yaml + + # app/config/config.yml + + liip_imagine: + filter_sets: + my_thumb: + filters: + thumbnail: { size: [120, 90], mode: outbound } + background: { size: [124, 94], position: center, color: '#000' } + post_processors: + optipng: { strip_all: true, level: 5 } + +This configuration enables metadata stripping, and sets a maximum optimization factor of 5 +for the resulting image binary. + +.. note:: + + The default executable path is ``/usr/bin/optipng``. If installed elsewhere + on your system, you must set the ``liip_imagine.optipng.binary`` parameter accordingly. + + .. code-block:: yaml + + # app/config/config.yml + + parameters: + liip_imagine.optipng.binary: /your/custom/path/to/optipng + + +Options +------- + +:strong:`strip_all:` ``bool`` + Removes all comments, EXIF markers, and other image metadata. + +:strong:`level:` ``int`` + Sets the image optimization factor. + + +Parameters +---------- + +:strong:`liip_imagine.optipng.stripAll:` ``bool`` + Removes all comments, EXIF markers, and other metadata from the image binary. + +:strong:`liip_imagine.optipng.level:` ``int`` + Sets the image optimization factor. Default is ``7``. + +:strong:`liip_imagine.optipng.binary:` ``string`` + Sets the location of the ``optipng`` executable. Default is ``/usr/bin/optipng``. + +:strong:`liip_imagine.optipng.tempDir:` ``string`` + Sets the directory to store temporary files. + + +.. tip:: + + The value of ``liip_imagine.optipng.tempDir`` can be set to an in-memory mount point + on supported operating systems, such as ``/run/shm`` on Linux. This will decrease disk + load and may increase performance. diff --git a/Resources/doc/post-processors/png-quant.rst b/Resources/doc/post-processors/png-quant.rst new file mode 100644 index 000000000..61c3431f5 --- /dev/null +++ b/Resources/doc/post-processors/png-quant.rst @@ -0,0 +1,52 @@ + +.. _post-processor-pngquant: + +PNG Quant +========= + +The ``PngquantPostProcessor`` is a built-in post-processor that performs a number of +*safe, lossy* optimizations on *PNG* encoded images. + +To add this post-processor to the filter set created in the +:ref:`thumbnail usage example ` use: + +.. code-block:: yaml + + # app/config/config.yml + + liip_imagine: + filter_sets: + my_thumb: + filters: + thumbnail: { size: [120, 90], mode: outbound } + background: { size: [124, 94], position: center, color: '#000' } + post_processors: + pngquant: { quality: "75-85" } + +This configuration sets a quality factor range of 75 to 80 for the resulting image binary. + +.. note:: + + The default executable path is ``/usr/bin/pngquant``. If installed elsewhere + on your system, you must set the ``liip_imagine.pngquant.binary`` parameter accordingly. + + .. code-block:: yaml + + # app/config/config.yml + + parameters: + liip_imagine.pngquant.binary: /your/custom/path/to/pngquant + + +Options +------- + +:strong:`quality:` ``int`` + Sets the image optimization factor. + + +Parameters +---------- + +:strong:`liip_imagine.pngquant.binary:` ``string`` + Sets the location of the ``pnquant`` executable. Default is ``/usr/bin/pnquant``.