You can chain multiple transformations together to create complex combinations in a single URL. You can also save a complete transformation (with any number of parameters or chained components) with a name and then use the name instead of the individual transformation parameters in your URL. This makes it easy to reuse transformations, to shorten complex transformation URLs or to hide the details of a transformation.
Cloudinary supports powerful image transformations that are applied on the fly using dynamic URLs, and you can also combine multiple transformations together as part of a single delivery request, e.g., crop an image and then add a border. In certain cases you may want to perform additional transformations on the result of another transformation request. In order to do that, you can chain the transformations together.
To support chained transformations, Cloudinary's transformation URLs allow you to include multiple transformation components, each separated by a slash (/
), where each of the transformation components is executed on the result of the previous one. Cloudinary's SDKs can apply multiple transformation components by specifying the transformation
parameter and setting it to an array of transformation maps.
Examples with the uploaded jpg image named flower
:
Two chained transformations: crop to 300x300 and scale down to a 150 width circle:
Ruby:
cl_image_tag("flower.jpg", :transformation=>[
{:width=>300, :height=>300, :crop=>"crop"},
{:width=>150, :radius=>"max", :crop=>"scale"}
])
PHP:
cl_image_tag("flower.jpg", array("transformation"=>array(
array("width"=>300, "height"=>300, "crop"=>"crop"),
array("width"=>150, "radius"=>"max", "crop"=>"scale")
)))
Python:
CloudinaryImage("flower.jpg").image(transformation=[
{'width': 300, 'height': 300, 'crop': "crop"},
{'width': 150, 'radius': "max", 'crop': "scale"}
])
Node.js:
cloudinary.image("flower.jpg", {transformation: [
{width: 300, height: 300, crop: "crop"},
{width: 150, radius: "max", crop: "scale"}
]})
Java:
cloudinary.url().transformation(new Transformation()
.width(300).height(300).crop("crop").chain()
.width(150).radius("max").crop("scale")).imageTag("flower.jpg");
JS:
cloudinary.imageTag('flower.jpg', {transformation: [
{width: 300, height: 300, crop: "crop"},
{width: 150, radius: "max", crop: "scale"}
]}).toHtml();
jQuery:
$.cloudinary.image("flower.jpg", {transformation: [
{width: 300, height: 300, crop: "crop"},
{width: 150, radius: "max", crop: "scale"}
]})
React:
<Image publicId="flower.jpg" >
<Transformation width="300" height="300" crop="crop" />
<Transformation width="150" radius="max" crop="scale" />
</Image>
Vue.js:
<cld-image publicId="flower.jpg" >
<cld-transformation width="300" height="300" crop="crop" />
<cld-transformation width="150" radius="max" crop="scale" />
</cld-image>
Angular:
<cl-image public-id="flower.jpg" >
<cl-transformation width="300" height="300" crop="crop">
</cl-transformation>
<cl-transformation width="150" radius="max" crop="scale">
</cl-transformation>
</cl-image>
.NET:
cloudinary.Api.UrlImgUp.Transform(new Transformation()
.Width(300).Height(300).Crop("crop").Chain()
.Width(150).Radius("max").Crop("scale")).BuildImageTag("flower.jpg")
Android:
MediaManager.get().url().transformation(new Transformation()
.width(300).height(300).crop("crop").chain()
.width(150).radius("max").crop("scale")).generate("flower.jpg");
iOS:
imageView.cldSetImage(cloudinary.createUrl().setTransformation(CLDTransformation()
.setWidth(300).setHeight(300).setCrop("crop").chain()
.setWidth(150).setRadius("max").setCrop("scale")).generate("flower.jpg")!, cloudinary: cloudinary)
Four chained transformations: custom crop to 150x100, fill to 130x100, rotate by 20 degrees and scale to 80%.
In this example, the secure
configuration parameter is also set locally in the SDK image tag method call. Note that the secure
configuration parameter is not part of the transformation
definition:
Ruby:
cl_image_tag("flower.jpg", :secure=>true, :transformation=>[
{:height=>100, :width=>150, :x=>380, :y=>250, :crop=>"crop"},
{:height=>100, :width=>130, :crop=>"fill"},
{:angle=>20},
{:width=>0.8, :crop=>"scale"}
])
PHP:
cl_image_tag("flower.jpg", array("secure"=>true, "transformation"=>array(
array("height"=>100, "width"=>150, "x"=>380, "y"=>250, "crop"=>"crop"),
array("height"=>100, "width"=>130, "crop"=>"fill"),
array("angle"=>20),
array("width"=>"0.8", "crop"=>"scale")
)))
Python:
CloudinaryImage("flower.jpg").image(secure=True, transformation=[
{'height': 100, 'width': 150, 'x': 380, 'y': 250, 'crop': "crop"},
{'height': 100, 'width': 130, 'crop': "fill"},
{'angle': 20},
{'width': "0.8", 'crop': "scale"}
])
Node.js:
cloudinary.image("flower.jpg", {secure: true, transformation: [
{height: 100, width: 150, x: 380, y: 250, crop: "crop"},
{height: 100, width: 130, crop: "fill"},
{angle: 20},
{width: "0.8", crop: "scale"}
]})
Java:
cloudinary.url().transformation(new Transformation()
.height(100).width(150).x(380).y(250).crop("crop").chain()
.height(100).width(130).crop("fill").chain()
.angle(20).chain()
.width(0.8).crop("scale")).secure(true).imageTag("flower.jpg");
JS:
cloudinary.imageTag('flower.jpg', {secure: true, transformation: [
{height: 100, width: 150, x: 380, y: 250, crop: "crop"},
{height: 100, width: 130, crop: "fill"},
{angle: 20},
{width: "0.8", crop: "scale"}
]}).toHtml();
jQuery:
$.cloudinary.image("flower.jpg", {secure: true, transformation: [
{height: 100, width: 150, x: 380, y: 250, crop: "crop"},
{height: 100, width: 130, crop: "fill"},
{angle: 20},
{width: "0.8", crop: "scale"}
]})
React:
<Image publicId="flower.jpg" secure="true">
<Transformation height="100" width="150" x="380" y="250" crop="crop" />
<Transformation height="100" width="130" crop="fill" />
<Transformation angle="20" />
<Transformation width="0.8" crop="scale" />
</Image>
Vue.js:
<cld-image publicId="flower.jpg" secure="true">
<cld-transformation height="100" width="150" x="380" y="250" crop="crop" />
<cld-transformation height="100" width="130" crop="fill" />
<cld-transformation angle="20" />
<cld-transformation width="0.8" crop="scale" />
</cld-image>
Angular:
<cl-image public-id="flower.jpg" secure="true">
<cl-transformation height="100" width="150" x="380" y="250" crop="crop">
</cl-transformation>
<cl-transformation height="100" width="130" crop="fill">
</cl-transformation>
<cl-transformation angle="20">
</cl-transformation>
<cl-transformation width="0.8" crop="scale">
</cl-transformation>
</cl-image>
.NET:
cloudinary.Api.UrlImgUp.Transform(new Transformation()
.Height(100).Width(150).X(380).Y(250).Crop("crop").Chain()
.Height(100).Width(130).Crop("fill").Chain()
.Angle(20).Chain()
.Width(0.8).Crop("scale")).Secure(true).BuildImageTag("flower.jpg")
Android:
MediaManager.get().url().transformation(new Transformation()
.height(100).width(150).x(380).y(250).crop("crop").chain()
.height(100).width(130).crop("fill").chain()
.angle(20).chain()
.width(0.8).crop("scale")).secure(true).generate("flower.jpg");
iOS:
imageView.cldSetImage(cloudinary.createUrl().setTransformation(CLDTransformation()
.setHeight(100).setWidth(150).setX(380).setY(250).setCrop("crop").chain()
.setHeight(100).setWidth(130).setCrop("fill").chain()
.setAngle(20).chain()
.setWidth(0.8).setCrop("scale")).generate("flower.jpg")!, cloudinary: cloudinary)
Cloudinary allows you to define named image transformations through our Management Console or Admin API. A named transformation is a set of image transformations that has been given a custom name for easy reference. It is useful to define a named transformation when you have a set of relatively complex transformations that you use often and that you want to easily reference, and using named transformations simplifies the enabling/disabling of transformations in Strict Transformations mode.
Instead of applying each of the transformations separately to an image, you can apply a single named transformation to apply all the transformations defined for it. Named transformations can also include other named transformations, which allows you to define a chain of transformations to run on uploaded images very easily. Using the named transformations is accomplished with the transformation
parameter (t
for URLs).
For example, the following named transformations have been defined for the Cloudinary demo
account through the Management Console:
jpg_with_quality_30
: Convert the image to a JPEG with 30% quality.
crop_400x400
: Crop the image to 400x400 with center gravity.
fit_100x150
: Fit the image into a 100x150 rectangle.
To create a version of the sample image based on the fit_100x150
transformation:
Ruby:
cl_image_tag("sample.jpg", :transformation=>["fit_100x150"])
PHP:
cl_image_tag("sample.jpg", array("transformation"=>array("fit_100x150")))
Python:
CloudinaryImage("sample.jpg").image(transformation=["fit_100x150"])
Node.js:
cloudinary.image("sample.jpg", {transformation: ["fit_100x150"]})
Java:
cloudinary.url().transformation(new Transformation().named("fit_100x150")).imageTag("sample.jpg");
JS:
cloudinary.imageTag('sample.jpg', {transformation: ["fit_100x150"]}).toHtml();
jQuery:
$.cloudinary.image("sample.jpg", {transformation: ["fit_100x150"]})
React:
<Image publicId="sample.jpg" >
<Transformation transformation={["fit_100x150"]} />
</Image>
Vue.js:
<cld-image publicId="sample.jpg" >
<cld-transformation transformation={["fit_100x150"]} />
</cld-image>
Angular:
<cl-image public-id="sample.jpg" >
<cl-transformation transformation={{["fit_100x150"]}}>
</cl-transformation>
</cl-image>
.NET:
cloudinary.Api.UrlImgUp.Transform(new Transformation().Named("fit_100x150")).BuildImageTag("sample.jpg")
Android:
MediaManager.get().url().transformation(new Transformation().named("fit_100x150")).generate("sample.jpg");
iOS:
imageView.cldSetImage(cloudinary.createUrl().setTransformation(CLDTransformation().setNamed("fit_100x150")).generate("sample.jpg")!, cloudinary: cloudinary)
To create a transformation that combines the jpg_with_quality_30
with additional transformations, such as fitting it to a 100 pixel width and a 50 pixel height:
Ruby:
cl_image_tag("sample.jpg", :transformation=>["jpg_with_quality_30"], :width=>100, :height=>50, :crop=>"fit")
PHP:
cl_image_tag("sample.jpg", array("transformation"=>array("jpg_with_quality_30"), "width"=>100, "height"=>50, "crop"=>"fit"))
Python:
CloudinaryImage("sample.jpg").image(transformation=["jpg_with_quality_30"], width=100, height=50, crop="fit")
Node.js:
cloudinary.image("sample.jpg", {transformation: ["jpg_with_quality_30"], width: 100, height: 50, crop: "fit"})
Java:
cloudinary.url().transformation(new Transformation().named("jpg_with_quality_30").width(100).height(50).crop("fit")).imageTag("sample.jpg");
JS:
cloudinary.imageTag('sample.jpg', {transformation: ["jpg_with_quality_30"], width: 100, height: 50, crop: "fit"}).toHtml();
jQuery:
$.cloudinary.image("sample.jpg", {transformation: ["jpg_with_quality_30"], width: 100, height: 50, crop: "fit"})
React:
<Image publicId="sample.jpg" >
<Transformation transformation={["jpg_with_quality_30"]} width="100" height="50" crop="fit" />
</Image>
Vue.js:
<cld-image publicId="sample.jpg" >
<cld-transformation transformation={["jpg_with_quality_30"]} width="100" height="50" crop="fit" />
</cld-image>
Angular:
<cl-image public-id="sample.jpg" >
<cl-transformation transformation={{["jpg_with_quality_30"]}} width="100" height="50" crop="fit">
</cl-transformation>
</cl-image>
.NET:
cloudinary.Api.UrlImgUp.Transform(new Transformation().Named("jpg_with_quality_30").Width(100).Height(50).Crop("fit")).BuildImageTag("sample.jpg")
Android:
MediaManager.get().url().transformation(new Transformation().named("jpg_with_quality_30").width(100).height(50).crop("fit")).generate("sample.jpg");
iOS:
imageView.cldSetImage(cloudinary.createUrl().setTransformation(CLDTransformation().setNamed("jpg_with_quality_30").setWidth(100).setHeight(50).setCrop("fit")).generate("sample.jpg")!, cloudinary: cloudinary)
You can also chain multiple named transformations. For example, to chain the three named transformations we defined above:
Ruby:
cl_image_tag("sample.jpg", :transformation=>[
{:transformation=>["jpg_with_quality_30"]},
{:transformation=>["crop_400x400"]},
{:transformation=>["fit_100x150"]}
])
PHP:
cl_image_tag("sample.jpg", array("transformation"=>array(
array("transformation"=>array("jpg_with_quality_30")),
array("transformation"=>array("crop_400x400")),
array("transformation"=>array("fit_100x150"))
)))
Python:
CloudinaryImage("sample.jpg").image(transformation=[
{'transformation': ["jpg_with_quality_30"]},
{'transformation': ["crop_400x400"]},
{'transformation': ["fit_100x150"]}
])
Node.js:
cloudinary.image("sample.jpg", {transformation: [
{transformation: ["jpg_with_quality_30"]},
{transformation: ["crop_400x400"]},
{transformation: ["fit_100x150"]}
]})
Java:
cloudinary.url().transformation(new Transformation()
.named("jpg_with_quality_30").chain()
.named("crop_400x400").chain()
.named("fit_100x150")).imageTag("sample.jpg");
JS:
cloudinary.imageTag('sample.jpg', {transformation: [
{transformation: ["jpg_with_quality_30"]},
{transformation: ["crop_400x400"]},
{transformation: ["fit_100x150"]}
]}).toHtml();
jQuery:
$.cloudinary.image("sample.jpg", {transformation: [
{transformation: ["jpg_with_quality_30"]},
{transformation: ["crop_400x400"]},
{transformation: ["fit_100x150"]}
]})
React:
<Image publicId="sample.jpg" >
<Transformation transformation={["jpg_with_quality_30"]} />
<Transformation transformation={["crop_400x400"]} />
<Transformation transformation={["fit_100x150"]} />
</Image>
Vue.js:
<cld-image publicId="sample.jpg" >
<cld-transformation transformation={["jpg_with_quality_30"]} />
<cld-transformation transformation={["crop_400x400"]} />
<cld-transformation transformation={["fit_100x150"]} />
</cld-image>
Angular:
<cl-image public-id="sample.jpg" >
<cl-transformation transformation={{["jpg_with_quality_30"]}}>
</cl-transformation>
<cl-transformation transformation={{["crop_400x400"]}}>
</cl-transformation>
<cl-transformation transformation={{["fit_100x150"]}}>
</cl-transformation>
</cl-image>
.NET:
cloudinary.Api.UrlImgUp.Transform(new Transformation()
.Named("jpg_with_quality_30").Chain()
.Named("crop_400x400").Chain()
.Named("fit_100x150")).BuildImageTag("sample.jpg")
Android:
MediaManager.get().url().transformation(new Transformation()
.named("jpg_with_quality_30").chain()
.named("crop_400x400").chain()
.named("fit_100x150")).generate("sample.jpg");
iOS:
imageView.cldSetImage(cloudinary.createUrl().setTransformation(CLDTransformation()
.setNamed("jpg_with_quality_30").chain()
.setNamed("crop_400x400").chain()
.setNamed("fit_100x150")).generate("sample.jpg")!, cloudinary: cloudinary)
Chaining transformations can create long URLs, so instead you could define a named transformation that includes a chain of other transformations, including other named transformations. For example, the named transformation demo_combined
has been defined for the Cloudinary demo account and is a composite of the three named transformations described above: jpg_with_quality_30
, crop_400x400
and fit_100x150
. It is now simple to specify the demo_combined
named transformation instead:
Ruby:
cl_image_tag("sample.jpg", :transformation=>["demo_combined"])
PHP:
cl_image_tag("sample.jpg", array("transformation"=>array("demo_combined")))
Python:
CloudinaryImage("sample.jpg").image(transformation=["demo_combined"])
Node.js:
cloudinary.image("sample.jpg", {transformation: ["demo_combined"]})
Java:
cloudinary.url().transformation(new Transformation().named("demo_combined")).imageTag("sample.jpg");
JS:
cloudinary.imageTag('sample.jpg', {transformation: ["demo_combined"]}).toHtml();
jQuery:
$.cloudinary.image("sample.jpg", {transformation: ["demo_combined"]})
React:
<Image publicId="sample.jpg" >
<Transformation transformation={["demo_combined"]} />
</Image>
Vue.js:
<cld-image publicId="sample.jpg" >
<cld-transformation transformation={["demo_combined"]} />
</cld-image>
Angular:
<cl-image public-id="sample.jpg" >
<cl-transformation transformation={{["demo_combined"]}}>
</cl-transformation>
</cl-image>
.NET:
cloudinary.Api.UrlImgUp.Transform(new Transformation().Named("demo_combined")).BuildImageTag("sample.jpg")
Android:
MediaManager.get().url().transformation(new Transformation().named("demo_combined")).generate("sample.jpg");
iOS:
imageView.cldSetImage(cloudinary.createUrl().setTransformation(CLDTransformation().setNamed("demo_combined")).generate("sample.jpg")!, cloudinary: cloudinary)