Say hello to
file adapters

Imager X has become even more extensible! 🔌

— Published on June 20, 2022

Today we're taking another cat-step towards making Imager X an extensible platform for everything related to image manipulation and transforms. File adapters join effects, optimizers, external storages and transformers as one of the many ways you can extend Imager with extra functionality.

While effects impact the visual looks of a transformed image, optimizers do post-optimization tasks, external storages let's you store transformed files in the cloud, and transformers pretty much replace how transforms are done - file adapters let's you extend what input formats Imager can work with.

Up until now, Imager has been limited to opening and transforming file formats that GD and Imagick can open, and how they decide to open them. With file adapters, you can open any type of format, do whatever pre-processing you want to do on it, and present Imager with a resulting image that it should use for the actual transforms. If that sounded awfully vague, fear not, there're examples!

First-party file adapters

With the addition of file adapters, there're also two first-party plugins being released. While adding new features in its own right, they also act as examples of how to make a file adapter. Say hello to PDF adapter and Video adapter, too!

The PDF adapter lets you open and transform PDF files, something that has been requested by the community for some time. The adapter lets you inspect the PDF to get the page count, choose which page to extract, and also lets you set the density (DPI) to use when converting from PDF to a rasterized image.

The Video adapter does the same, only for videos. It requires a working installation of ffmpeg, and let's you open and extract any frame you want, from all the video formats that ffmpeg supports.

But how does it work?

There're two ways to use file adapters. You can either create an instance of your adapter and pass that into Imager as you would any normal image format, or the adapter can register file extensions that automatically should trigger the adapter to load. Using the PDF adapter as an example, this is an example of the first approach:

{% set pdf = craft.pdfadapter.load(myPdfAsset, { page: 1, density: 300 }) %}
{% set transform = craft.imagerx.transformImage(pdf, { width: 600 }) %}

But because the PDF adapter registers the .pdf extension with Imager, you can also do:

{% set transforms = craft.imagerx.transformImage(myPdfAsset, { width: 200 }) %}

When using this second approach, you can use the new transform parameter adapterParams to pass in additional parameters that the adapter supports:

{% set transforms = craft.imagerx.transformImage(myPdfAsset, { width: 200, adapterParams: { page: 5, density: 300 } }) %}

Although both the PDF and Video adapters register file extensions with Imager (for the video adapter you can actually choose which), your adapter doesn't need to.

Let's say you're pulling data from an API which have images associated with the data, but don't want to import those images to Craft or expose them through a public URL. You could make a file adapter that takes some kind of unique identifier, uses the API to pull down a copy of the correct image, maybe do some initial manipulation or validation on it, and then pass it on to Imager:

{% set apiFile = craft.myApiAdapter.getImage(uid) %}
{% set transforms = craft.imagerx.transformImage(apiFile, [{ width: 400 }, { width: 2000 }], { ratio: 16/9 }, { fillTransforms: true }) %}

In this case, you'd need to use the prior method of instanciating a file adapter, and passing that into Imager.

Another use-case for file adapters, could be to pass it the URL to a website, and use a service like Urlbox to screenshot it:

{% set urlScreenshot = craft.myUrlboxAdapter.getScreenshot('') %}
{% set transforms = craft.imagerx.transformImage(urlScreenshot, [{ width: 400 }, { width: 2000 }], { ratio: 16/9 }, { fillTransforms: true }) %}

This is just an example, a Urlbox adapter does not exist (yet)!

Although file adapters are primarily meant to add support for new formats, you could even use it as wrappers around formats that Imager already can transform.

You could make a Gif Simplify Adapter that uses gifsicle to reduce the number of frames, frame rate and colors in animated gifs, to ensure that they can be transformed in a timely and resource-friendly manner by Imager. Or, you could make an Add Meta Adapter to clean up and add meta data to all images prior to transforming them (Although, that would probably in most cases be better solved by doing it on asset upload. But then again, external images?)

Sounds interesting?

The documentation is updated with more information on how to make your own file adapters.

If you have a request for a specific file adapter that you think would benefit the whole community, let me know and maybe I can make it a first-party plugin too.