Conditional image transformations
Cloudinary supports conditional transformations for images, where a transformation is only applied if a specified condition is met, for example, if an image's width is greater than 300 pixels, apply a certain transformation.
See also: Conditional transformations for video.
Specifying conditions
To specify a condition to be met before applying a transformation use the if
parameter (also if
in URLs). The if
parameter accepts a string value detailing the condition to evaluate, and is given in the following format:
if_<image characteristic>_<operator>_<image characteristic value>
Where:
image characteristic
: The image parameter representing the characteristic to evaluate, for example 'w' (or 'width' in SDKs).operator
: The comparison operator for the comparison, for example 'lt' for 'less than' (or '<' in SDKs).image characteristic value
: A hard coded value of the characteristic or a different image characteristic.
Specify strings for a characteristic sub-element or value surrounded by ! !
. For example, if_ if_ctx:!productType!_eq_!shoes!
.
!!
.
For example:
if some-condition_eq_!!
See examples below.
Supported image characteristics
Characteristic | Description |
---|---|
w |
(also width in SDKs) The asset's current width. |
iw |
The asset's initial width. |
h |
(also height in SDKs) The asset's current height. |
ih |
The asset's initial height. |
ar |
(also aspect_ratio in SDKs) The aspect ratio of the asset. The compared value can be either decimal (e.g., 1.5) or a ratio (e.g., 3:4). |
iar |
The asset's initial aspect ratio. |
ctx |
A contextual metadata value assigned to an asset. |
md |
A structured metadata value assigned to an asset. |
tags |
The set of tags assigned to the asset. |
tar (trimmed_aspect_ratio in SDKs) |
The aspect ratio of the image IF it was trimmed (using the 'trim' effect) without actually trimming the image. The compared value can be either decimal (e.g., 1.5) or a ratio (e.g., 3:4). |
cp |
The current page in the image/document. |
fc (face_count in SDKs) |
The total number of detected faces in the image. |
pc (page_count in SDKs) |
The total number of pages in the image/document. |
px |
A layer or page's original x offset position relative to the whole composition (for example, in a PSD or TIFF file). |
py |
A layer or page's original y offset position relative to the whole composition (for example, in a PSD or TIFF file). |
idn |
The initial density (dpi) of the image. |
ils |
The likelihood that the image is an illustration (as opposed to a photo). Supported values: 0 (photo) to 1 (illustration) |
pgnames |
The names of layers in a TIFF file. Use with the in or nin operators. |
Supported operators
URL | SDK symbol | Description |
---|---|---|
eq |
= |
Equal to |
ne |
!= |
Not equal to |
lt |
< |
Less than |
gt |
> |
Greater than |
lte |
<= |
Less than or equal to |
gte |
>= |
Greater than or equal to |
in |nin |
in |nin |
Included in | Not included in Compares a set of strings against another set of strings. See Using the in and nin operators for examples. |
When working with the Cloudinary SDKs, you can specify the condition using the SDK characteristic names and operator symbols, or you can specify it using the URL format. For example, both of the following are valid:
- { if: "w_gt_1000", crop: "scale", width: 500}
- { if: "width > 1000", crop: "scale", width: 500}
Using the in and nin operators
The in
and nin
operators compare two sets of strings. The :
delimiter between strings denotes AND.
String sets can include tags, contextual metadata or structured metadata values, for example:
- To determine if
sale
andin_stock
are present in the tags of a particular asset, use:if_!sale:in_stock!_in_tags
. - To determine if the key named
color
exists in the contextual metadata of a particular asset, use:if_!color!_in_ctx
. - To determine if a structured metadata field with external ID,
color-id
, has been set for a particular asset, use:if_!color-id!_in_md
. - To determine if a list value with external ID,
green-id
, has been selected from a multiple-selection structured metadata field with external ID,colors-id
, for a particular asset, use:if_!green-id!_in_md!colors-id!
.
For TIFF files:
- To determine if a TIFF file contains a layer called
Shadow
, use:if_!Shadow!_in_pgnames
.
Supported conditional image transformation parameters and flags
All image transformation parameters can be assigned in conditions except:
- You cannot assign transformation parameters in conditions for the
default_image
,color_space
, ordelay
parameters. - The
page
(pg
in URLs) parameter cannot be assigned in conditions for animated images.
(page
can be used in conditions for PSD, PDF, or TIFF documents).
- You cannot assign transformation parameters in conditions for the
Only the following flags are supported inside conditional transformations:
layer_apply
,region_relative
,relative
,progressive
,cutter
,png8
,attachment
,awebp
,lossy
Conditional transformation examples
Conditional text overlay based on width This example limits an image size to a width of 300 pixels using the limit crop mode, and then uses a conditional transformation to add a text caption only to images whose initial width was wider than 300 and were scaled down (
if_w_gt_300
):
URL:Ruby:PHP v1:cl_image_tag("sample.jpg", array("transformation"=>array( array("width"=>300, "crop"=>"limit"), array("if"=>"iw_gt_300", "color"=>"white", "gravity"=>"south_east", "overlay"=>array("font_family"=>"Arial", "font_size"=>15, "font_weight"=>"bold", "text"=>"Image%20scaled%20down%20to%20300px")) )))
PHP v2:(new ImageTag('sample.jpg')) ->resize(Resize::limitFit()->width(300)) ->conditional( Conditional::ifCondition('initial_width > 300', (new Transformation()) ->overlay( Overlay::source( Source::text('Image scaled down to 300px', (new TextStyle('Arial', 15)) ->fontWeight(FontWeight::bold())) ->textColor(Color::WHITE)) ->position((new Position()) ->gravity(Gravity::compass(Compass::southEast())) ))));
Python:Node.js:Java:cloudinary.url().transformation(new Transformation() .width(300).crop("limit").chain() .if("iw_gt_300").color("white").gravity("south_east").overlay(new TextLayer().fontFamily("Arial").fontSize(15).fontWeight("bold").text("Image%20scaled%20down%20to%20300px"))).imageTag("sample.jpg");
JS:cloudinary.imageTag('sample.jpg', {transformation: [ {width: 300, crop: "limit"}, {if: "iw_gt_300", color: "white", gravity: "south_east", overlay: new cloudinary.TextLayer().fontFamily("Arial").fontSize(15).fontWeight("bold").text("Image%20scaled%20down%20to%20300px")} ]}).toHtml();
jQuery:React:Vue.js:Angular:.NET:cloudinary.Api.UrlImgUp.Transform(new Transformation() .Width(300).Crop("limit").Chain() .If("iw_gt_300").Color("white").Gravity("south_east").Overlay(new TextLayer().FontFamily("Arial").FontSize(15).FontWeight("bold").Text("Image%20scaled%20down%20to%20300px"))).BuildImageTag("sample.jpg")
Android:MediaManager.get().url().transformation(new Transformation() .width(300).crop("limit").chain() .if("iw_gt_300").color("white").gravity("south_east").overlay(new TextLayer().fontFamily("Arial").fontSize(15).fontWeight("bold").text("Image%20scaled%20down%20to%20300px"))).generate("sample.jpg");
iOS:imageView.cldSetImage(cloudinary.createUrl().setTransformation(CLDTransformation() .setWidth(300).setCrop("limit").chain() .setIf("iw_gt_300").setColor("white").setGravity("south_east").setOverlay("text:Arial_15_bold:Image%20scaled%20down%20to%20300px")).generate("sample.jpg")!, cloudinary: cloudinary)
Conditional cropping mode based on illustration score This example ensures that uploaded graphics such as logos are never cut off, even if the art design changes its aspect ratio, but photos will always fill the full space available. Using the
ils
conditional characteristic, thecloudinary_icon_blue
logo is cropped using the pad method and thesample
photo is cropped using the fill method:
Conditional resize based on a contextual metadata value This example resizes an image to a 200*200 square image (using g_auto cropping) if it has a contextual metadata key named 'productType' with the value 'shoes'.
Conditional image overlay based on tags This example adds a sale icon to a product image if both the strings ‘sale’ and ‘in_stock” are among the tags assigned to the image:
URL:Ruby:PHP v1:PHP v2:(new ImageTag('backpack.jpg')) ->conditional( Conditional::ifCondition('!sale:in_stock! in tags', (new Transformation()) ->overlay( Overlay::source(Source::image('sale_icon') ->transformation((new ImageTransformation()) ->resize(Resize::scale()->width(180)))) ->position((new Position()) ->gravity(Gravity::compass(Compass::southEast())) ->offsetX(30)->offsetY(30))))) ->resize(Resize::scale()->width(250));
Python:Node.js:Java:JS:jQuery:React:Vue.js:Angular:.NET:Android:iOS:imageView.cldSetImage(cloudinary.createUrl().setTransformation(CLDTransformation() .setIf("!sale:in_stock!_in_tags").setOverlay("sale_icon").setWidth(180).setGravity("south_east").setX(30).setY(30).chain() .setWidth(250).setCrop("scale")).generate("backpack.jpg")!, cloudinary: cloudinary)
tags
, ctx
or md
parameters, their values are exposed publicly in the URL. If you want to prevent such values from being exposed, you can disable the Usage of tags/context/metadata in transformation URLs option in the Security tab of your account settings (enabled by default). When this setting is disabled, any URL that exposes tags, contextual metadata or structured metadata values will return an error.Notes
- The position of the
if
parameter inside a transformation component doesn't matter and it applies to the whole component (a single transformation between a pair of slashes). - For the
w
,h
,cp
andar
parameters, the values refer to the current image status in the transformation chain (i.e., if transformations have already been applied to the image), whileiw
,ih
,fc
andpc
always refer to the original image. dpr
is not supported as a conditional transformation with thecp
andar
characteristics. Additionally,w
andh
are supported withdpr
as long as they are still equal toiw
orih
when the condition is evaluated.- The
ar
(aspect ratio) parameter should be compared using 'greater than' or 'less than' rather than with 'equals'. This is because the width and height values are given as integers and not floating point values, leading to an "almost exact" calculated aspect ratio.
Multiple conditions
You can specify multiple conditions to evaluate by joining the conditions with AND or OR conjunction operators.
For example, to crop the sample
image to a width of 300 pixels and a height of 200 pixels, only if the aspect ratio is greater than 3:4, the width is greater than 300, and the height is greater than 200 (if_ar_gt_3:4_and_w_gt_300_and_h_gt_200
):

Conditions with chained transformations
To set a condition for applying multiple transformations (in the form of chained transformation components), add an if_end
parameter to the last transformation component in the chain. In order to avoid ambiguity when applying a condition on multiple chained components, the components with the if
and the if_end
parameters should not have additional transformation instructions. For example:
- Wrong:
if_w_gt_500,c_crop,h_200,w_300,e_red:50/e_blur/if_end
- Right:
if_w_gt_500/c_crop,h_200,w_300/e_red:50/e_blur/if_end
For example, if you allocate space on your page for an image with a width of 600px, you can conditionally add a blurred background for images whose width is less than 600px:
cl_image_tag("small_dinosaur.jpg", :transformation=>[ {:if=>"w_lt_600"}, {:overlay=>{:font_family=>"Arial", :font_size=>20, :text=>"Image%20shown%20in%20full%20scale"}, :color=>"white", :gravity=>"south_east"}, {:effect=>"blur:400", :underlay=>"small_dinosaur", :width=>600, :crop=>"scale"}, {:if=>"end"} ])
cl_image_tag("small_dinosaur.jpg", array("transformation"=>array( array("if"=>"w_lt_600"), array("overlay"=>array("font_family"=>"Arial", "font_size"=>20, "text"=>"Image%20shown%20in%20full%20scale"), "color"=>"white", "gravity"=>"south_east"), array("effect"=>"blur:400", "underlay"=>"small_dinosaur", "width"=>600, "crop"=>"scale"), array("if"=>"end") )))
(new ImageTag('small_dinosaur.jpg')) ->conditional( Conditional::ifCondition('width < 600', (new Transformation()) ->overlay( Overlay::source(Source::text('Image shown in full scale', (new TextStyle('Arial', 20))) ->textColor(Color::WHITE)) ->position((new Position()) ->gravity(Gravity::compass(Compass::southEast())))) ->underlay( Underlay::source(Source::image('small_dinosaur') ->transformation((new ImageTransformation()) ->resize(Resize::scale()->width(600)) ->effect(Effect::blur()->strength(400)) )))));
CloudinaryImage("small_dinosaur.jpg").image(transformation=[ {'if': "w_lt_600"}, {'overlay': {'font_family': "Arial", 'font_size': 20, 'text': "Image%20shown%20in%20full%20scale"}, 'color': "white", 'gravity': "south_east"}, {'effect': "blur:400", 'underlay': "small_dinosaur", 'width': 600, 'crop': "scale"}, {'if': "end"} ])
cloudinary.image("small_dinosaur.jpg", {transformation: [ {if: "w_lt_600"}, {overlay: {font_family: "Arial", font_size: 20, text: "Image%20shown%20in%20full%20scale"}, color: "white", gravity: "south_east"}, {effect: "blur:400", underlay: "small_dinosaur", width: 600, crop: "scale"}, {if: "end"} ]})
cloudinary.url().transformation(new Transformation() .if("w_lt_600").chain() .overlay(new TextLayer().fontFamily("Arial").fontSize(20).text("Image%20shown%20in%20full%20scale")).color("white").gravity("south_east").chain() .effect("blur:400").underlay(new Layer().publicId("small_dinosaur")).width(600).crop("scale").chain() .if("end")).imageTag("small_dinosaur.jpg");
cloudinary.imageTag('small_dinosaur.jpg', {transformation: [ {if: "w_lt_600"}, {overlay: new cloudinary.TextLayer().fontFamily("Arial").fontSize(20).text("Image%20shown%20in%20full%20scale"), color: "white", gravity: "south_east"}, {effect: "blur:400", underlay: new cloudinary.Layer().publicId("small_dinosaur"), width: 600, crop: "scale"}, {if: "end"} ]}).toHtml();
$.cloudinary.image("small_dinosaur.jpg", {transformation: [ {if: "w_lt_600"}, {overlay: new cloudinary.TextLayer().fontFamily("Arial").fontSize(20).text("Image%20shown%20in%20full%20scale"), color: "white", gravity: "south_east"}, {effect: "blur:400", underlay: new cloudinary.Layer().publicId("small_dinosaur"), width: 600, crop: "scale"}, {if: "end"} ]})
<Image publicId="small_dinosaur.jpg" > <Transformation if="w_lt_600" /> <Transformation overlay={{fontFamily: "Arial", fontSize: 20, text: "Image%20shown%20in%20full%20scale"}} color="white" gravity="south_east" /> <Transformation effect="blur:400" underlay="small_dinosaur" width="600" crop="scale" /> <Transformation if="end" /> </Image>
<cld-image publicId="small_dinosaur.jpg" > <cld-transformation if="w_lt_600" /> <cld-transformation :overlay="{fontFamily: 'Arial', fontSize: 20, text: 'Image%20shown%20in%20full%20scale'}" color="white" gravity="south_east" /> <cld-transformation effect="blur:400" :underlay="small_dinosaur" width="600" crop="scale" /> <cld-transformation if="end" /> </cld-image>
<cl-image public-id="small_dinosaur.jpg" > <cl-transformation if="w_lt_600"> </cl-transformation> <cl-transformation overlay="text:Arial_20:Image%20shown%20in%20full%20scale" color="white" gravity="south_east"> </cl-transformation> <cl-transformation effect="blur:400" underlay="small_dinosaur" width="600" crop="scale"> </cl-transformation> <cl-transformation if="end"> </cl-transformation> </cl-image>
cloudinary.Api.UrlImgUp.Transform(new Transformation() .If("w_lt_600").Chain() .Overlay(new TextLayer().FontFamily("Arial").FontSize(20).Text("Image%20shown%20in%20full%20scale")).Color("white").Gravity("south_east").Chain() .Effect("blur:400").Underlay(new Layer().PublicId("small_dinosaur")).Width(600).Crop("scale").Chain() .If("end")).BuildImageTag("small_dinosaur.jpg")
MediaManager.get().url().transformation(new Transformation() .if("w_lt_600").chain() .overlay(new TextLayer().fontFamily("Arial").fontSize(20).text("Image%20shown%20in%20full%20scale")).color("white").gravity("south_east").chain() .effect("blur:400").underlay(new Layer().publicId("small_dinosaur")).width(600).crop("scale").chain() .if("end")).generate("small_dinosaur.jpg");
imageView.cldSetImage(cloudinary.createUrl().setTransformation(CLDTransformation() .setIf("w_lt_600").chain() .setOverlay("text:Arial_20:Image%20shown%20in%20full%20scale").setColor("white").setGravity("south_east").chain() .setEffect("blur:400").setUnderlay("small_dinosaur").setWidth(600).setCrop("scale").chain() .setIf("end")).generate("small_dinosaur.jpg")!, cloudinary: cloudinary)

- Multiple separate conditions can be used in a single URL, but only one per transformation component.
- A named transformation must not be placed in the same transformation component as its condition (e.g.,
if_w_eq_h,t_trans
is not supported). Apply the condition on the named transformation by using a chained transformation (e.g.,if_w_eq_h/t_trans/if_end
).
Else branch transformations
You can specify a transformation that is applied in the case that the initial condition is evaluated as false (and hence the transformations associated with the condition are not applied), by using the if_else
parameter to specify this fallback transformation.
For example, to fill an image to a width of 80 pixels and a height of 120 pixels if the original image has a width less than or equal to 200 pixels (the condition: if_iw_lte_200,c_fill,h_120,w_80
), and to fill the image to a width of 100 pixels and a height of 150 pixels if the original image has a width greater than 200 pixels (the fallback: if_else,c_fill,h_90,w_100
):

In cases where the if
condition is not in the preceding transformation component, then the if_else
parameter also acts as an if_end
parameter: all chained transformation components until the one with if_else
are only applied if the previous condition holds true. Multiple conditional transformations can also be applied by adding an if_end
parameter to the last transformation component in the chain, and to avoid ambiguity, the component with the if_else
parameter should not have additional transformation instructions.
For example, if the width is less than or equal to 400 pixels then fill the image to 220x180 and add a red effect, else if the width is greater than 400 pixels then fill the image to 190x300 and add an oil painting effect:
cl_image_tag("sample.jpg", array("transformation"=>array( array("if"=>"w_lte_400"), array("height"=>220, "width"=>180, "crop"=>"fill"), array("effect"=>"red"), array("if"=>"else"), array("height"=>190, "width"=>300, "crop"=>"fill"), array("effect"=>"oil_paint"), array("if"=>"end") )))
(new ImageTag('sample.jpg')) ->conditional( Conditional::ifCondition('w_lte_400', (new Transformation()) ->resize(Resize::fill()->width(180)->height(220)) ->adjust(Adjust::red())) ->otherwise((new Transformation()) ->resize(Resize::fill()->width(300)->height(190)) ->effect(Effect::oilPaint()) ));
<Image publicId="sample.jpg" > <Transformation if="w_lte_400" /> <Transformation height="220" width="180" crop="fill" /> <Transformation effect="red" /> <Transformation if="else" /> <Transformation height="190" width="300" crop="fill" /> <Transformation effect="oil_paint" /> <Transformation if="end" /> </Image>
<cld-image publicId="sample.jpg" > <cld-transformation if="w_lte_400" /> <cld-transformation height="220" width="180" crop="fill" /> <cld-transformation effect="red" /> <cld-transformation if="else" /> <cld-transformation height="190" width="300" crop="fill" /> <cld-transformation effect="oil_paint" /> <cld-transformation if="end" /> </cld-image>
<cl-image public-id="sample.jpg" > <cl-transformation if="w_lte_400"> </cl-transformation> <cl-transformation height="220" width="180" crop="fill"> </cl-transformation> <cl-transformation effect="red"> </cl-transformation> <cl-transformation if="else"> </cl-transformation> <cl-transformation height="190" width="300" crop="fill"> </cl-transformation> <cl-transformation effect="oil_paint"> </cl-transformation> <cl-transformation if="end"> </cl-transformation> </cl-image>
MediaManager.get().url().transformation(new Transformation() .if("w_lte_400").chain() .height(220).width(180).crop("fill").chain() .effect("red").chain() .if("else").chain() .height(190).width(300).crop("fill").chain() .effect("oil_paint").chain() .if("end")).generate("sample.jpg");
imageView.cldSetImage(cloudinary.createUrl().setTransformation(CLDTransformation() .setIf("w_lte_400").chain() .setHeight(220).setWidth(180).setCrop("fill").chain() .setEffect("red").chain() .setIf("else").chain() .setHeight(190).setWidth(300).setCrop("fill").chain() .setEffect("oil_paint").chain() .setIf("end")).generate("sample.jpg")!, cloudinary: cloudinary)
