Pre-processors¶
JoliMediaBundle provides different types of transformations, that allow for example to resize or crop images. However, it does not provide advanced transformations to prepare the media before the conversion, such as rotating images, applying filters, backgrounds or watermarks, because these transformations are not supported by all the underlying tools used by the bundle.
Pre-processors are responsible for applying transformations to a media before the conversion. They can be used to prepare the media before the transformation, for example to apply a watermark or rotate the media.
Configuration¶
The pre-processors configuration is defined in the pre_processors key of the joli_media configuration.
joli_media:
pre_processors:
- App\Media\PreProcessor\AutoRotateImagePreProcessor
# - ...
In the example above, the AutoRotateImagePreProcessor will be applied to the media before any of its variation is computed. The pre-processors are executed sequentially, in the order they are defined in the configuration file.
Pre-processors that use an external binary (such as the ExifRemovalPreProcessor) execute it in an external process, which times out after the duration defined in the global joli_media.process_timeout directive (60 seconds by default). To override this value for a given pre-processor, use the alternative map syntax of the pre_processors configuration and define its process_timeout key, in seconds (0 disables the timeout):
joli_media:
pre_processors:
App\Media\PreProcessor\AutoRotateImagePreProcessor: ~
JoliCode\MediaBundle\PreProcessor\ExifRemovalPreProcessor:
process_timeout: 120
For pre-processors defined in your application, the process_timeout value is passed to the $processTimeout argument of the service constructor, which must hence be declared, and returned by an override of the getProcessTimeout() method:
public function __construct(
private ImagineInterface $imagine,
private ?float $processTimeout = null,
) {
}
protected function getProcessTimeout(): ?float
{
return $this->processTimeout;
}
Pre-processors that declare this argument without configuring a process_timeout can inherit the global value by binding the joli_media.process_timeout container parameter in their service definition.
The pre-processors configuration can also be defined within a specific variation configuration, under the variations key of the joli_media configuration. For example:
variations:
real_estate:
format: webp
pre_processors:
- App\Media\PreProcessor\ApplyWatermarkPreProcessor
# - ...
transformers:
resize:
width: 200
height: 150
mode: inside
heighten:
height: 600
In the example above, the ApplyWatermarkPreProcessor will be applied to the media before the "real_estate" variation is computed, and after the global pre-processors.
The PreProcessorInterface¶
A pre-processor class must implement the process method of the Joli\MediaBundle\PreProcessor\PreProcessorInterface interface, in order to manipulate the media. As a normal service, pre-processor can use other services - for example the Imagine library. The following pre-processor shows how to expand the size of an image and add a yellow background to it (although you will probably prefer to use the "Expand" transformer):
namespace App\Media\PreProcessor;
use Imagine\Image\Box;
use Imagine\Image\ImagineInterface;
use Imagine\Image\Point;
use JoliCode\MediaBundle\Binary\Binary;
use JoliCode\MediaBundle\PreProcessor\AbstractPreProcessor;
use JoliCode\MediaBundle\PreProcessor\PreProcessorInterface;
use JoliCode\MediaBundle\Variation\Variation;
readonly class OgImagePreProcessor extends AbstractPreProcessor implements PreProcessorInterface
{
private const WIDTH = 1200;
private const HEIGHT = 1000;
public function __construct(
private ImagineInterface $imagine,
) {
}
public function process(Binary $binary, Variation $variation): Binary
{
$image = $this->imagine->load($binary->getContent());
$width = $image->getSize()->getWidth();
$height = $image->getSize()->getHeight();
if (!$width || !$height) {
return $binary;
}
if ($width > self::WIDTH || $height > self::HEIGHT) {
$ratio = $width / $height;
if ($width > self::WIDTH) {
$height = self::WIDTH / $ratio;
$width = self::WIDTH;
}
if ($height > self::HEIGHT) {
$width = self::HEIGHT * $ratio;
$height = self::HEIGHT;
}
$image = $image->resize(new Box($width, $height));
}
$canvas = $this->imagine->create(
new Box(self::WIDTH, self::HEIGHT),
$image->palette()->color('#ffff00'),
);
$x = (self::WIDTH - $width) / 2;
$y = (self::HEIGHT - $height) / 2;
$canvas->paste($image, new Point($x, $y));
return new Binary(
$binary->getMimeType(),
$binary->getFormat(),
$canvas->get($binary->getFormat()),
);
}
}
Built-in pre-processors¶
Heif pre-processor¶
The bundle provides the HeifPreProcessor pre-processor, which is used to convert HEIF images to JPEG or PNG format. This pre-processor is automatically registered and does not need to be configured in the joli_media configuration.
HEIF (High Efficiency Image File Format) is a modern image format that is not supported by all browsers and tools, but it is gaining traction due to its efficient compression and high quality. However, many web browsers do not support HEIF images, which can lead to compatibility issues when displaying images on the web. iPhone users can encounter this issue when they take photos in HEIF format, which is available on iOS devices since iOS 11.
Therefore, the HeifPreProcessor will automatically convert HEIF images to JPEG format, so that they can be used in variations and displayed in the browser.
Exif removal pre-processor¶
The bundle provides the ExifRemovalPreProcessor pre-processor, which is used to remove EXIF metadata from images. This pre-processor is not registered by default, and must be added to the pre_processors configuration of the joli_media configuration, e.g.:
joli_media:
pre_processors:
- JoliCode\MediaBundle\PreProcessor\ExifRemovalPreProcessor
# - ...
This pre-processor uses the exiftool command line tool to remove EXIF metadata from images. It supports JPEG and TIFF images. exiftool must be installed on the server where the application is running, and its path must be configured in the JOLI_MEDIA_EXIFTOOL_BINARY environment variable or the joli_media.binary.exiftool configuration parameter (by default, it is set to /usr/local/bin/exiftool).