Chained and named transformations

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.

Chained Transformations

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:

  1. Two chained transformations: crop to 300x300 and scale down to a 150 width circle:

    Ruby:
    Copy to clipboard
    cl_image_tag("flower.jpg", :transformation=>[
      {:width=>300, :height=>300, :crop=>"crop"},
      {:width=>150, :radius=>"max", :crop=>"scale"}
      ])
    PHP:
    Copy to clipboard
    cl_image_tag("flower.jpg", array("transformation"=>array(
      array("width"=>300, "height"=>300, "crop"=>"crop"),
      array("width"=>150, "radius"=>"max", "crop"=>"scale")
      )))
    Python:
    Copy to clipboard
    CloudinaryImage("flower.jpg").image(transformation=[
      {'width': 300, 'height': 300, 'crop': "crop"},
      {'width': 150, 'radius': "max", 'crop': "scale"}
      ])
    Node.js:
    Copy to clipboard
    cloudinary.image("flower.jpg", {transformation: [
      {width: 300, height: 300, crop: "crop"},
      {width: 150, radius: "max", crop: "scale"}
      ]})
    Java:
    Copy to clipboard
    cloudinary.url().transformation(new Transformation()
      .width(300).height(300).crop("crop").chain()
      .width(150).radius("max").crop("scale")).imageTag("flower.jpg");
    JS:
    Copy to clipboard
    cloudinary.imageTag('flower.jpg', {transformation: [
      {width: 300, height: 300, crop: "crop"},
      {width: 150, radius: "max", crop: "scale"}
      ]}).toHtml();
    jQuery:
    Copy to clipboard
    $.cloudinary.image("flower.jpg", {transformation: [
      {width: 300, height: 300, crop: "crop"},
      {width: 150, radius: "max", crop: "scale"}
      ]})
    React:
    Copy to clipboard
    <Image publicId="flower.jpg" >
      <Transformation width="300" height="300" crop="crop" />
      <Transformation width="150" radius="max" crop="scale" />
    </Image>
    Vue.js:
    Copy to clipboard
    <cld-image publicId="flower.jpg" >
      <cld-transformation width="300" height="300" crop="crop" />
      <cld-transformation width="150" radius="max" crop="scale" />
    </cld-image>
    Angular:
    Copy to clipboard
    <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:
    Copy to clipboard
    cloudinary.Api.UrlImgUp.Transform(new Transformation()
      .Width(300).Height(300).Crop("crop").Chain()
      .Width(150).Radius("max").Crop("scale")).BuildImageTag("flower.jpg")
    Android:
    Copy to clipboard
    MediaManager.get().url().transformation(new Transformation()
      .width(300).height(300).crop("crop").chain()
      .width(150).radius("max").crop("scale")).generate("flower.jpg");
    iOS:
    Copy to clipboard
    imageView.cldSetImage(cloudinary.createUrl().setTransformation(CLDTransformation()
      .setWidth(300).setHeight(300).setCrop("crop").chain()
      .setWidth(150).setRadius("max").setCrop("scale")).generate("flower.jpg")!, cloudinary: cloudinary)
    2 chained transformations applied to an image

  2. 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:
    Copy to clipboard
    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:
    Copy to clipboard
    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:
    Copy to clipboard
    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:
    Copy to clipboard
    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:
    Copy to clipboard
    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:
    Copy to clipboard
    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:
    Copy to clipboard
    $.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:
    Copy to clipboard
    <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:
    Copy to clipboard
    <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:
    Copy to clipboard
    <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:
    Copy to clipboard
    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:
    Copy to clipboard
    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:
    Copy to clipboard
    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)
    4 chained transformations applied to an image

Named Transformations

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:
Copy to clipboard
cl_image_tag("sample.jpg", :transformation=>["fit_100x150"])
PHP:
Copy to clipboard
cl_image_tag("sample.jpg", array("transformation"=>array("fit_100x150")))
Python:
Copy to clipboard
CloudinaryImage("sample.jpg").image(transformation=["fit_100x150"])
Node.js:
Copy to clipboard
cloudinary.image("sample.jpg", {transformation: ["fit_100x150"]})
Java:
Copy to clipboard
cloudinary.url().transformation(new Transformation().named("fit_100x150")).imageTag("sample.jpg");
JS:
Copy to clipboard
cloudinary.imageTag('sample.jpg', {transformation: ["fit_100x150"]}).toHtml();
jQuery:
Copy to clipboard
$.cloudinary.image("sample.jpg", {transformation: ["fit_100x150"]})
React:
Copy to clipboard
<Image publicId="sample.jpg" >
  <Transformation transformation={["fit_100x150"]} />
</Image>
Vue.js:
Copy to clipboard
<cld-image publicId="sample.jpg" >
  <cld-transformation transformation={["fit_100x150"]} />
</cld-image>
Angular:
Copy to clipboard
<cl-image public-id="sample.jpg" >
  <cl-transformation transformation={{["fit_100x150"]}}>
  </cl-transformation>
</cl-image>
.Net:
Copy to clipboard
cloudinary.Api.UrlImgUp.Transform(new Transformation().Named("fit_100x150")).BuildImageTag("sample.jpg")
Android:
Copy to clipboard
MediaManager.get().url().transformation(new Transformation().named("fit_100x150")).generate("sample.jpg");
iOS:
Copy to clipboard
imageView.cldSetImage(cloudinary.createUrl().setTransformation(CLDTransformation().setNamed("fit_100x150")).generate("sample.jpg")!, cloudinary: cloudinary)
fit_100x150 named transformation applied to image

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:
Copy to clipboard
cl_image_tag("sample.jpg", :transformation=>["jpg_with_quality_30"], :width=>100, :height=>50, :crop=>"fit")
PHP:
Copy to clipboard
cl_image_tag("sample.jpg", array("transformation"=>array("jpg_with_quality_30"), "width"=>100, "height"=>50, "crop"=>"fit"))
Python:
Copy to clipboard
CloudinaryImage("sample.jpg").image(transformation=["jpg_with_quality_30"], width=100, height=50, crop="fit")
Node.js:
Copy to clipboard
cloudinary.image("sample.jpg", {transformation: ["jpg_with_quality_30"], width: 100, height: 50, crop: "fit"})
Java:
Copy to clipboard
cloudinary.url().transformation(new Transformation().named("jpg_with_quality_30").width(100).height(50).crop("fit")).imageTag("sample.jpg");
JS:
Copy to clipboard
cloudinary.imageTag('sample.jpg', {transformation: ["jpg_with_quality_30"], width: 100, height: 50, crop: "fit"}).toHtml();
jQuery:
Copy to clipboard
$.cloudinary.image("sample.jpg", {transformation: ["jpg_with_quality_30"], width: 100, height: 50, crop: "fit"})
React:
Copy to clipboard
<Image publicId="sample.jpg" >
  <Transformation transformation={["jpg_with_quality_30"]} width="100" height="50" crop="fit" />
</Image>
Vue.js:
Copy to clipboard
<cld-image publicId="sample.jpg" >
  <cld-transformation transformation={["jpg_with_quality_30"]} width="100" height="50" crop="fit" />
</cld-image>
Angular:
Copy to clipboard
<cl-image public-id="sample.jpg" >
  <cl-transformation transformation={{["jpg_with_quality_30"]}} width="100" height="50" crop="fit">
  </cl-transformation>
</cl-image>
.Net:
Copy to clipboard
cloudinary.Api.UrlImgUp.Transform(new Transformation().Named("jpg_with_quality_30").Width(100).Height(50).Crop("fit")).BuildImageTag("sample.jpg")
Android:
Copy to clipboard
MediaManager.get().url().transformation(new Transformation().named("jpg_with_quality_30").width(100).height(50).crop("fit")).generate("sample.jpg");
iOS:
Copy to clipboard
imageView.cldSetImage(cloudinary.createUrl().setTransformation(CLDTransformation().setNamed("jpg_with_quality_30").setWidth(100).setHeight(50).setCrop("fit")).generate("sample.jpg")!, cloudinary: cloudinary)
jpg_with_quality_30 named transformation with 100x50 fit applied to image

You can also chain multiple named transformations. For example, to chain the three named transformations we defined above:

Ruby:
Copy to clipboard
cl_image_tag("sample.jpg", :transformation=>[
  {:transformation=>["jpg_with_quality_30"]},
  {:transformation=>["crop_400x400"]},
  {:transformation=>["fit_100x150"]}
  ])
PHP:
Copy to clipboard
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:
Copy to clipboard
CloudinaryImage("sample.jpg").image(transformation=[
  {'transformation': ["jpg_with_quality_30"]},
  {'transformation': ["crop_400x400"]},
  {'transformation': ["fit_100x150"]}
  ])
Node.js:
Copy to clipboard
cloudinary.image("sample.jpg", {transformation: [
  {transformation: ["jpg_with_quality_30"]},
  {transformation: ["crop_400x400"]},
  {transformation: ["fit_100x150"]}
  ]})
Java:
Copy to clipboard
cloudinary.url().transformation(new Transformation()
  .named("jpg_with_quality_30").chain()
  .named("crop_400x400").chain()
  .named("fit_100x150")).imageTag("sample.jpg");
JS:
Copy to clipboard
cloudinary.imageTag('sample.jpg', {transformation: [
  {transformation: ["jpg_with_quality_30"]},
  {transformation: ["crop_400x400"]},
  {transformation: ["fit_100x150"]}
  ]}).toHtml();
jQuery:
Copy to clipboard
$.cloudinary.image("sample.jpg", {transformation: [
  {transformation: ["jpg_with_quality_30"]},
  {transformation: ["crop_400x400"]},
  {transformation: ["fit_100x150"]}
  ]})
React:
Copy to clipboard
<Image publicId="sample.jpg" >
  <Transformation transformation={["jpg_with_quality_30"]} />
  <Transformation transformation={["crop_400x400"]} />
  <Transformation transformation={["fit_100x150"]} />
</Image>
Vue.js:
Copy to clipboard
<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:
Copy to clipboard
<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:
Copy to clipboard
cloudinary.Api.UrlImgUp.Transform(new Transformation()
  .Named("jpg_with_quality_30").Chain()
  .Named("crop_400x400").Chain()
  .Named("fit_100x150")).BuildImageTag("sample.jpg")
Android:
Copy to clipboard
MediaManager.get().url().transformation(new Transformation()
  .named("jpg_with_quality_30").chain()
  .named("crop_400x400").chain()
  .named("fit_100x150")).generate("sample.jpg");
iOS:
Copy to clipboard
imageView.cldSetImage(cloudinary.createUrl().setTransformation(CLDTransformation()
  .setNamed("jpg_with_quality_30").chain()
  .setNamed("crop_400x400").chain()
  .setNamed("fit_100x150")).generate("sample.jpg")!, cloudinary: cloudinary)
Applying all 3 named transformations

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:
Copy to clipboard
cl_image_tag("sample.jpg", :transformation=>["demo_combined"])
PHP:
Copy to clipboard
cl_image_tag("sample.jpg", array("transformation"=>array("demo_combined")))
Python:
Copy to clipboard
CloudinaryImage("sample.jpg").image(transformation=["demo_combined"])
Node.js:
Copy to clipboard
cloudinary.image("sample.jpg", {transformation: ["demo_combined"]})
Java:
Copy to clipboard
cloudinary.url().transformation(new Transformation().named("demo_combined")).imageTag("sample.jpg");
JS:
Copy to clipboard
cloudinary.imageTag('sample.jpg', {transformation: ["demo_combined"]}).toHtml();
jQuery:
Copy to clipboard
$.cloudinary.image("sample.jpg", {transformation: ["demo_combined"]})
React:
Copy to clipboard
<Image publicId="sample.jpg" >
  <Transformation transformation={["demo_combined"]} />
</Image>
Vue.js:
Copy to clipboard
<cld-image publicId="sample.jpg" >
  <cld-transformation transformation={["demo_combined"]} />
</cld-image>
Angular:
Copy to clipboard
<cl-image public-id="sample.jpg" >
  <cl-transformation transformation={{["demo_combined"]}}>
  </cl-transformation>
</cl-image>
.Net:
Copy to clipboard
cloudinary.Api.UrlImgUp.Transform(new Transformation().Named("demo_combined")).BuildImageTag("sample.jpg")
Android:
Copy to clipboard
MediaManager.get().url().transformation(new Transformation().named("demo_combined")).generate("sample.jpg");
iOS:
Copy to clipboard
imageView.cldSetImage(cloudinary.createUrl().setTransformation(CLDTransformation().setNamed("demo_combined")).generate("sample.jpg")!, cloudinary: cloudinary)
demo_combined named transformation applied to image

Notes

✔️ Feedback sent!