Post-Processors
We already know that 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.
Custom processors
You can define your own post-processors to perform any image binary operations
required. Post-processor need to implement the PostProcessorInterface
:
1 2 3 4
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 ['image/png']
to the supported mime types
for your custom post-processor.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
namespace App\Service;
use Liip\ImagineBundle\Binary\BinaryInterface;
use Liip\ImagineBundle\Model\Binary;
use Liip\ImagineBundle\Imagine\Filter\PostProcessorInterface;
use Symfony\Component\Process\Exception\ProcessFailedException;
use Symfony\Component\Process\ProcessBuilder;
class MyCustomPostProcessor implements PostProcessorInterface
{
public 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()), ['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([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;
}
}
Register it: automatically
By default, your post-processor will be automatically registered as it implements the PostProcessorInterface
.
You will be able to reference and use your custom post-processor in your configuration by using its Fully Qualified Class Name.
Register it: manually
If you want to give it a different name you need to configure a service with your custom post-processor and tag it
with liip_imagine.filter.post_processor
.
To register App\Service\MyCustomPostProcessor
with the name
my_custom_post_processor
, you would use the following configuration.
1 2 3 4 5 6
# app/config/services.yml
app.post_processor.my_custom_post_processor:
class: App\Service\MyCustomPostProcessor
tags:
- { name: 'liip_imagine.filter.post_processor', post_processor: 'my_custom_post_processor' }
1 2 3 4 5
<!-- app/config/services.xml -->
<service id="app.post_processor.my_custom_post_processor" class="App\Service\MyCustomPostProcessor">
<tag name="liip_imagine.filter.post_processor" post_processor="my_custom_post_processor" />
</service>
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
).
1 2 3 4 5 6 7
# app/config/config.yml
liip_imagine:
filter_sets:
my_special_style:
post_processors:
my_custom_post_processor: { }