Image asset transformations
Introduction
A derivative is defined with an array of configured transformations that the original asset binary will be passed through in order to create a new version.
A transformation is defined as a CFML structure, with the following keys:
- method (required): Method that matches a method implemented in the api-assettransformer service object
- args (optional): Structure of arguments passed to the transformation method.
- inputfiletype (optional): Only apply this transformation to images of this type. e.g. "pdf".
- outputfiletype (optional): Expected output filetype of the transformation
An example using all of the above arguments, is the admin thumbnail derivative that works for both PDFs and images:
settings.assetmanager.derivatives.adminthumbnail = {
permissions = "inherit"
, inEditor = false
, transformations = [
{ method="pdfPreview" , args={ page=1 }, inputfiletype="pdf", outputfiletype="jpg" }
, { method="shrinkToFit", args={ width=200, height=200 } }
]
};
Available transformations
There are three transformation methods built in to Preside:
- shrinkToFit
- resize
- pdfPreview
shrinkToFit
shrinkToFit will resize an image so it fits within the specified width and height, while maintaining the source image's aspect ratio.
The following settings can be passed to the method in the args struct:
- width (required): Maximum width in pixels for the resulting image.
- height (required): Maximum height in pixels for the resulting image.
- quality (optional): The image quality to use when resizing the image. Available values are
highestQuality
,highQuality
,mediumQuality
,highestPerformance
,highPerformance
andmediumPerformance
. Defaults tohighPerformance
.
resize
resize will resize and crop an image if necesary, and is probably the more often used transformation.
The following settings can be passed to the method in the args struct:
- width (optional): Width in pixels for the resulting image.
- height (optional): Height in pixels for the resulting image.
- quality (optional): The image quality to use when resizing the image. Available values are
highestQuality
,highQuality
,mediumQuality
,highestPerformance
,highPerformance
andmediumPerformance
. Defaults tohighPerformance
. - maintainAspectRatio (optional): Whether or not the aspect ratio of the source image should be maintained when resizing. Defaults to
false
. - useCropHint (optional): Introduced in 10.9.0. Whether or not the image should be cropped according to the crop hint, if one is defined. Defaults to
false
.
Note that while width and height are both optional, at least one of them is required.
Resize with width or height
If only one dimension is specified, then the image will be resized so it matches that width or height. Setting maintainAspectRatio is irrelevant here, as it will always be true: the image is resized proportionally; the unspecified dimension is not constrained.
Resize with width and height
If both width and height are specified, but maintainAspectRatio is false
, then the whole image will be resized to those dimensions. If the aspect ratio of the transformation does not match the aspect ratio of the source image, the image will be stretched either vertically or horizontally to fit the new aspect ratio.
If both width and height are specified, and maintainAspectRatio is true
, then the image will be cropped to the largest area possible that matches the target aspect ratio. By default, this will be based around the centre point of the image. However, as of 10.9.0, the asset edit UI includes a cropping tab which allows you to set the focal point of the image. If this is set, then the cropping process will keep this focal point as close as possible to the centre of the resulting image.
Also introduced in 10.9.0 are crop hints. In the same cropping tab of the asset edit UI, you can set an area of the image as a crop hint. If useCropHint is set to true
, then the image will be pre-cropped to the smallest size that includes the whole of the crop hint before the resizing is applied.
Examples
The following examples show the different results from different resize arguments, based on this source image:
{ method="resize", args={ width=300 } }
{ method="resize", args={ width=300, height=300 } }
{ method="resize", args={ width=300, height=300, maintainAspectRatio=true } }
{ method="resize", args={ width=300, height=300, maintainAspectRatio=true } }
Focal point set in the asset edit UI towards the left of the image
{ method="resize", args={ width=300, height=300, maintainAspectRatio=true, useCropHint=true } }
Crop hint set in the asset edit UI around the centre of the image
Developing custom transformations
As of Preside 10.11.0, Transformations are created as coldbox handlers with a convention based path of assettransformers.{transformername}
. For example, the resize
transformation has a corresponding private handler action at /handlers/AssetTransformers.cfc$resize()
:
component {
property name="imageManipulationService" inject="imageManipulationService";
private binary function resize( event, rc, prc, args={} ) {
return imageManipulationService.resize( argumentCollection=args );
}
// ...
}
Create your own handler actions and use the handler name in your transformations. Any arguments set in the derivative transformation config will be passed in the args
structure sent to the handler action, along with a binary
asset
argument.
The handler must return a binary
object that is the asset binary. A blank example:
// /application/handlers/AssetTransformers.cfc
component {
private binary function doNothing( event, rc, prc, args={} ) {
return args.asset;
}
// ...
}
// /application/config/Config.cfc
component extends="preside.system.config.Config" {
public void function configure() {
super.configure();
// ...
settings.assetManager.derivatives.example = {
permissions = "inherit"
, transformations = [
{ method="doNothing" , args={} } // refers to our custom, pointless, transformation
, { method="shrinkToFit", args={ width=200, height=200 } }
]
};
}