Whether your web application supports user uploaded images, you deliver static images, or you display profile pictures from social networks, you probably need to manipulate them to fit the graphic design of your Web site or mobile application.
For example, the following dynamic URL with on-the-fly image transformation crops an image to a 400x400 circular thumbnail while automatically focusing on the face, and then scales down the result to a width of 200 pixels. Below you can see the original image (scaled down) and the dynamically created face detection based thumbnail.
cl_image_tag("lady.jpg", :transformation=>[ {:width=>400, :height=>400, :gravity=>"face", :radius=>"max", :crop=>"crop"}, {:width=>200} ])
cl_image_tag("lady.jpg", array("transformation"=>array( array("width"=>400, "height"=>400, "gravity"=>"face", "radius"=>"max", "crop"=>"crop"), array("width"=>200) )))
CloudinaryImage("lady.jpg").image(transformation=[ {"width": 400, "height": 400, "gravity": "face", "radius": "max", "crop": "crop"}, {"width": 200} ])
cloudinary.image("lady.jpg", {transformation: [ {width: 400, height: 400, gravity: "face", radius: "max", crop: "crop"}, {width: 200} ]})
cloudinary.url().transformation(new Transformation() .width(400).height(400).gravity("face").radius("max").crop("crop").chain() .width(200)).imageTag("lady.jpg")
$.cloudinary.image("lady.jpg", {transformation: [ {width: 400, height: 400, gravity: "face", radius: "max", crop: "crop"}, {width: 200} ]})
cloudinary.Api.UrlImgUp.Transform(new Transformation() .Width(400).Height(400).Gravity("face").Radius("max").Crop("crop").Chain() .Width(200)).BuildImageTag("lady.jpg")
Cloudinary allows you to easily transform your images on-the-fly to any required format, style and dimension, and also optimizes images to have the minimal file size for an improved user experience and for saving bandwidth. Doing so is done by implementing dynamic image transformation and delivery URLs for accessing the images. You can change the required transformations at any time and all transformed images will be created on-demand (lazily) and delivered to your users through a fast CDN with optimized caching.
You can specify the required height and width, define the way to crop the image, and select the image format that fits your needs. You can also use our face detection based cropping techniques for focusing on the most relevant part of user uploaded photos. For complex transformations, you can use the Management Console or Admin API for defining named transformations and even run a set of chained transformations on your images. You can also use the Management Console to view delivery usage reports and optimization insights.
Cloudinary's image management service supports the following image transformation and delivery capabilities:
- Deliver images using dynamic Cloudinary URLs.
- Embed images in web pages.
- Resize image dimensions and crop to match your graphic design.
- Detect faces in images for automatic cropping, resizing, overlay placement and using visual effects.
- Convert between image formats.
- Adjust image quality.
- Modify the image shape and style.
- Apply effects to images.
- Add image and text overlays.
- Chain transformations together.
- Name custom transformations.
- Optimize images.
- Use responsive images.
- Fetch images from remote locations.
- Use advanced URL delivery options.
- Create images from PDF files.
- Manage animated GIFs.
- Add flags to control transformation behavior.
- Apply transformations only if a specified condition is met.
The Image Transformations Reference table summarizes the extensive list of parameters available for manipulating images.
Cloudinary's client libraries (SDKs) take care of the transformation URL building for you, and simplify the integration even further. They allow you to continue working in your preferred developer framework and provide helper methods to simplify building image tags and image transformation URLs: Rails, PHP, Django, jQuery, Node.js, .NET, Java, Angular, Javascript, iOS, Scala and Android.
Delivering images using dynamic URLs
Accessing images is done using simple delivery HTTP or HTTPS URLs which are then delivered to users via a worldwide fast CDN. The URL contains the Public ID of the requested image plus any optional transformation parameters. Public ID is the unique identifier of the image and is either specified when uploading the image to your Cloudinary account, or automatically assigned by Cloudinary (see Upload images for more details on the various options for specifying the public ID).
The Cloudinary resource delivery URL takes the following structure:
http://res.cloudinary.com/<cloud_name>/<resource_type>/<type>/<version>/<public_id>.<format>
Where:
cloud_name
- the name of your Cloudinary account, a unique public identifier for URL building and API access.resource_type
is the type of file to deliver. Valid values:image
,raw
, andvideo
(note that there are other valid values when fetching remote images: see Fetching images from remote locations for more information).type
- the level of accessibility of the file to deliver. Valid values:upload
,private
andauthenticated
.version
- (optional) can be added to the delivery URL in order to bypass the cached version on the CDN and force delivery of the latest resource (in the case that a resource has been overwritten with a newer file). The version component is generally not included in the example URLs on this page in order to keep them simple. See Image versions for more information.public_id
- the unique identifier of the resource, including the folder structure if defined.format
- (optional) the file extension of the requested delivery format for the resource. The resource is delivered in the original uploaded format if the file extension is not included.
Therefore, in the most general case of delivering an image that has been uploaded to your Cloudinary account, the delivery URL is given as:
http://res.cloudinary.com/<cloud_name>/image/upload/<public_id>.<format>
For example, displaying the image with a public ID of sample
uploaded to Cloudinary's demo
account in jpg
format:
cl_image_tag("sample.jpg")
cl_image_tag("sample.jpg")
CloudinaryImage("sample.jpg").image()
cloudinary.image("sample.jpg")
cloudinary.url().imageTag("sample.jpg")
$.cloudinary.image("sample.jpg")
cloudinary.Api.UrlImgUp.BuildImageTag("sample.jpg")
Any transformation (manipulation) instructions can be added before the public ID in the delivery URL. When the URL is first accessed, the derived image is created on-the-fly and delivered to your user. The derived image is also cached on the CDN and is immediately available to all subsequent users requesting the same image. The image delivery URL with transformation parameters takes the following structure:
http://res.cloudinary.com/<cloud name>/image/upload/<transformation parameters>/<public ID>.<image format file extension>
Following is an example of delivering an image with transformation parameters, where the image with a public ID of sample
is cropped to a width of 300 pixels and a height of 200 pixels, and delivered in JPEG format:
cl_image_tag("sample.jpg", :width=>300, :height=>200, :crop=>"crop")
cl_image_tag("sample.jpg", array("width"=>300, "height"=>200, "crop"=>"crop"))
CloudinaryImage("sample.jpg").image(width=300, height=200, crop="crop")
cloudinary.image("sample.jpg", {width: 300, height: 200, crop: "crop"})
cloudinary.url().transformation(new Transformation().width(300).height(200).crop("crop")).imageTag("sample.jpg")
$.cloudinary.image("sample.jpg", {width: 300, height: 200, crop: "crop"})
cloudinary.Api.UrlImgUp.Transform(new Transformation().Width(300).Height(200).Crop("crop")).BuildImageTag("sample.jpg")
You can also use shortcut URLs for specifically delivering uploaded images. With Cloudinary’s Root Path URL feature, the resource type
and type
parameters can be omitted from the URL (they automatically default to the values 'image' and 'upload' respectively). For example, the Root Path shortcut delivery URL for the cropped image above is:
http://res.cloudinary.com/demo/w_300,h_200,c_crop/sample.jpg
The rest of this page documents the various transformation and delivery options, and you can also see the Image Transformations Reference table for an overview on the extensive list of possible parameters and their values.
Secure HTTPS URLs
Cloudinary supports delivering images using HTTPS URLs. The process for creating HTTPS delivery URLs is identical to creating HTTP URLs, with only the URL protocol changing. When using one of Cloudinary's framework SDKs, you can generate HTTPS URLs by setting the secure
parameter to true
, either globally (e.g., in the CLOUDINARY_URL environment variable) or locally in each call. For example, delivering the sample
image with HTTPS:
cl_image_tag("sample.jpg", :secure=>true)
cl_image_tag("sample.jpg", array("secure"=>true))
CloudinaryImage("sample.jpg").image(secure=True)
cloudinary.image("sample.jpg", {secure: true})
cloudinary.url().secure(true).imageTag("sample.jpg")
$.cloudinary.image("sample.jpg", {secure: true})
cloudinary.Api.UrlImgUp.Secure(true).BuildImageTag("sample.jpg")
For more information on using HTTPS to deliver your images, see the article on Why isn't everyone using HTTPS and how to do it with Cloudinary.
Embedding images in web pages
Accessing uploaded images or their derived transformations is done using simple URLs that you can use as the 'src' of the 'img' tags in your HTML code or Javascript functions. URLs for accessing resources contain the resource kind, the Public ID of the resource, and optional version and transformation parameters. You can also use Cloudinary’s web framework SDKs to aid you in adding images to your web application and simplify the creation of transformation URLs and embedding HTML image tags. Cloudinary offers two main helper methods in this regard:
The Cloudinary URL helper method (e.g. cloudinary_url
in Ruby on Rails) automatically generates the image source URL for use as the 'src' of the 'img' tags in your HTML code or Javascript functions. For example, using the URL helper method to return the URL of the sample
image, scaled to a width of 300 pixels and a height of 100 pixels:
cloudinary_url("sample.jpg", :width=>300, :height=>100, :crop=>"scale", :secure=>true)
Cloudinary::cloudinary_url("sample.jpg", array("width"=>300, "height"=>100, "crop"=>"scale", "secure"=>true))
cloudinary.utils.cloudinary_url("sample.jpg", width=300, height=100, crop="scale", secure=True)
cloudinary.url("sample.jpg", {width: 300, height: 100, crop: "scale", secure: true})
cloudinary.url().transformation(new Transformation().width(300).height(100).crop("scale")).secure(true).generate("sample.jpg")
$.cloudinary.url("sample.jpg", {width: 300, height: 100, crop: "scale", secure: true})
cloudinary.Api.UrlImgUp.Transform(new Transformation().Width(300).Height(100).Crop("scale")).Secure(true).BuildUrl("sample.jpg")
The Cloudinary Image Tag helper method (e.g. cl_image_tag
in Ruby on Rails) automatically generates an HTML image tag including the image source URL. For example, using the Image Tag helper method to create an HTML image tag for the sample
image, scaled to a width of 300 pixels and a height of 100 pixels:
cl_image_tag("sample.jpg", :width=>300, :height=>100, :crop=>"scale", :secure=>true)
cl_image_tag("sample.jpg", array("width"=>300, "height"=>100, "crop"=>"scale", "secure"=>true))
CloudinaryImage("sample.jpg").image(width=300, height=100, crop="scale", secure=True)
cloudinary.image("sample.jpg", {width: 300, height: 100, crop: "scale", secure: true})
cloudinary.url().transformation(new Transformation().width(300).height(100).crop("scale")).secure(true).imageTag("sample.jpg")
$.cloudinary.image("sample.jpg", {width: 300, height: 100, crop: "scale", secure: true})
cloudinary.Api.UrlImgUp.Transform(new Transformation().Width(300).Height(100).Crop("scale")).Secure(true).BuildImageTag("sample.jpg")
The Cloudinary Image Tag helper method allows you to not only specify any Cloudinary transformations parameters, but also to specify regular HTML image tag attributes (e.g., alt, title, width, height).
Notes:
- Specifying the
width
andheight
parameters without acrop
mode will add them as parameters of the HTML img tag, and specifying thewidth
andheight
parameters with acrop
mode will add them as transformation parameters to the image source URL. In this case you can use thehtml_width
andhtml_height
parameters if you need different dimensions for the HTML img tag. - Using a full URL (e.g., http://res.cloudinary.com/demo/image/upload/sample.jpg) instead of only the public ID (e.g., sample.jpg) in the first parameter of the helper methods will result in all other parameters of the helper method being ignored and only using the full URL as the final generated URL.
For more information on these helper methods, see the documentation for the relevant framework: Ruby on Rails, PHP, Django, Node.js, Java, .NET, Angular, Javascript, iOS, Scala and Android.
Resizing and cropping images
You can resize and crop images in order to match the graphic design of your web site or mobile application. Whether images are uploaded in your server-side code or by your users, the original hi-res images are stored in the cloud for further processing and management. You can then dynamically create multiple resized, cropped and manipulated images on-the-fly and deliver them via dynamic URLs.
To change the size of a image, use the width
and height
parameters (w
and h
in URLs) to assign new values. You can resize the image by using both the width and height parameters or with only one of them: the other dimension is automatically updated to maintain the aspect ratio.
- Using an integer value sets the new dimension to that number in pixels. For example,
w_150
sets the width to exactly 150 pixels. - Using a decimal value sets the new dimension as a multiple of the original dimension. For example,
w_0.5
sets the width to half the original width. - Using
oh
orow
as values sets the dimension to the original height or original width respectively. For example,w_ow
sets the width to the same value as the original width. This may be useful when applying chained transformations or setting the dimensions of an overlay.
Examples of resizing the uploaded jpg image named sample
:
Resizing the width to half the original width, maintaining the aspect ratio:
Ruby:cl_image_tag("sample.jpg", :width=>0.5)
PHP:cl_image_tag("sample.jpg", array("width"=>0.5))
Python:CloudinaryImage("sample.jpg").image(width=0.5)
Node.js:cloudinary.image("sample.jpg", {width: 0.5})
Java:cloudinary.url().transformation(new Transformation().width(0.5)).imageTag("sample.jpg")
jQuery:$.cloudinary.image("sample.jpg", {width: 0.5})
.Net:cloudinary.Api.UrlImgUp.Transform(new Transformation().Width(0.5)).BuildImageTag("sample.jpg")
Resizing the height to 200 pixels, maintaining the aspect ratio:
Ruby:cl_image_tag("sample.jpg", :height=>200)
PHP:cl_image_tag("sample.jpg", array("height"=>200))
Python:CloudinaryImage("sample.jpg").image(height=200)
Node.js:cloudinary.image("sample.jpg", {height: 200})
Java:cloudinary.url().transformation(new Transformation().height(200)).imageTag("sample.jpg")
jQuery:$.cloudinary.image("sample.jpg", {height: 200})
.Net:cloudinary.Api.UrlImgUp.Transform(new Transformation().Height(200)).BuildImageTag("sample.jpg")
Resizing to a width of 200 pixels and a height of 100 pixels:
Ruby:cl_image_tag("sample.jpg", :width=>200, :height=>100)
PHP:cl_image_tag("sample.jpg", array("width"=>200, "height"=>100))
Python:CloudinaryImage("sample.jpg").image(width=200, height=100)
Node.js:cloudinary.image("sample.jpg", {width: 200, height: 100})
Java:cloudinary.url().transformation(new Transformation().width(200).height(100)).imageTag("sample.jpg")
jQuery:$.cloudinary.image("sample.jpg", {width: 200, height: 100})
.Net:cloudinary.Api.UrlImgUp.Transform(new Transformation().Width(200).Height(100)).BuildImageTag("sample.jpg")
When changing the dimensions of an uploaded image by manipulating the image's height and/or width, you need to decide how to adapt or "crop" the image to fit into the requested size. Use the crop
parameter for selecting the crop mode (c
in URLs). Cloudinary supports the following image cropping modes: scale, fit, mfit, fill, lfill, limit, pad, lpad, mpad, crop, thumb, imagga_crop and imagga_scale.
Note: When creating dynamic delivery URLs, the image is scaled to the new dimensions by default (as in the examples above), unless a different cropping mode is selected. However, there is no default value when using the Cloudinary SDK helper methods (see Embedding images in web pages), and a cropping mode must be explicitly selected.
scale
Change the size of the image exactly to the given width and height without necessarily retaining the original aspect ratio: all original image parts are visible but might be stretched or shrunk. If only the width or height is given, then the image is scaled to the new dimension while retaining the original aspect ratio, unless you also include the ignore_aspect_ratio
flag). This is the default cropping mode for resizing images if the crop mode is not specified.
Examples of scaling the uploaded image named sample
:
Scaled to a width of 150 pixels (maintains the aspect ratio by default):
Ruby:cl_image_tag("sample.jpg", :width=>150, :crop=>"scale")
PHP:cl_image_tag("sample.jpg", array("width"=>150, "crop"=>"scale"))
Python:CloudinaryImage("sample.jpg").image(width=150, crop="scale")
Node.js:cloudinary.image("sample.jpg", {width: 150, crop: "scale"})
Java:cloudinary.url().transformation(new Transformation().width(150).crop("scale")).imageTag("sample.jpg")
jQuery:$.cloudinary.image("sample.jpg", {width: 150, crop: "scale"})
.Net:cloudinary.Api.UrlImgUp.Transform(new Transformation().Width(150).Crop("scale")).BuildImageTag("sample.jpg")
Scaled to a width and height of 150 pixels without maintaining the aspect ratio:
Ruby:cl_image_tag("sample.jpg", :width=>150, :height=>150, :crop=>"scale")
PHP:cl_image_tag("sample.jpg", array("width"=>150, "height"=>150, "crop"=>"scale"))
Python:CloudinaryImage("sample.jpg").image(width=150, height=150, crop="scale")
Node.js:cloudinary.image("sample.jpg", {width: 150, height: 150, crop: "scale"})
Java:cloudinary.url().transformation(new Transformation().width(150).height(150).crop("scale")).imageTag("sample.jpg")
jQuery:$.cloudinary.image("sample.jpg", {width: 150, height: 150, crop: "scale"})
.Net:cloudinary.Api.UrlImgUp.Transform(new Transformation().Width(150).Height(150).Crop("scale")).BuildImageTag("sample.jpg")
Scaled to a width of 25% (maintains the aspect ratio by default):
Ruby:cl_image_tag("sample.jpg", :width=>0.25, :crop=>"scale")
PHP:cl_image_tag("sample.jpg", array("width"=>0.25, "crop"=>"scale"))
Python:CloudinaryImage("sample.jpg").image(width=0.25, crop="scale")
Node.js:cloudinary.image("sample.jpg", {width: 0.25, crop: "scale"})
Java:cloudinary.url().transformation(new Transformation().width(0.25).crop("scale")).imageTag("sample.jpg")
jQuery:$.cloudinary.image("sample.jpg", {width: 0.25, crop: "scale"})
.Net:cloudinary.Api.UrlImgUp.Transform(new Transformation().Width(0.25).Crop("scale")).BuildImageTag("sample.jpg")
fit
The image is resized so that it takes up as much space as possible within a bounding box defined by the given width and height parameters. The original aspect ratio is retained and all of the original image is visible.
For example, the uploaded image named sample
is resized to fit within a width and height of 250 pixels while retaining the aspect ratio:
cl_image_tag("sample.jpg", :width=>250, :height=>250, :crop=>"fit")
cl_image_tag("sample.jpg", array("width"=>250, "height"=>250, "crop"=>"fit"))
CloudinaryImage("sample.jpg").image(width=250, height=250, crop="fit")
cloudinary.image("sample.jpg", {width: 250, height: 250, crop: "fit"})
cloudinary.url().transformation(new Transformation().width(250).height(250).crop("fit")).imageTag("sample.jpg")
$.cloudinary.image("sample.jpg", {width: 250, height: 250, crop: "fit"})
cloudinary.Api.UrlImgUp.Transform(new Transformation().Width(250).Height(250).Crop("fit")).BuildImageTag("sample.jpg")
limit
Same as the fit
mode but only if the original image is larger than the given limit (width and height), in which case the image is scaled down so that it takes up as much space as possible within a bounding box defined by the given width and height parameters. The original aspect ratio is retained and all of the original image is visible. This mode doesn't scale up the image if your requested dimensions are larger than the original image's.
For example, the uploaded jpg image named sample
limited to a width and height of 250 pixels while retaining the aspect ratio:
cl_image_tag("sample.jpg", :width=>250, :height=>250, :crop=>"limit")
cl_image_tag("sample.jpg", array("width"=>250, "height"=>250, "crop"=>"limit"))
CloudinaryImage("sample.jpg").image(width=250, height=250, crop="limit")
cloudinary.image("sample.jpg", {width: 250, height: 250, crop: "limit"})
cloudinary.url().transformation(new Transformation().width(250).height(250).crop("limit")).imageTag("sample.jpg")
$.cloudinary.image("sample.jpg", {width: 250, height: 250, crop: "limit"})
cloudinary.Api.UrlImgUp.Transform(new Transformation().Width(250).Height(250).Crop("limit")).BuildImageTag("sample.jpg")
mfit (minimum fit)
Same as the fit
mode but only if the original image is smaller than the given minimum (width and height), in which case the image is scaled up so that it takes up as much space as possible within a bounding box defined by the given width and height parameters. The original aspect ratio is retained and all of the original image is visible. This mode doesn't scale down the image if your requested dimensions are smaller than the original image's.
For example, attempting to fit the uploaded image named sample
to a minimum width and height of 250 pixels while retaining the aspect ratio, results in delivering the original larger image:
cl_image_tag("sample.jpg", :width=>250, :height=>250, :crop=>"mfit")
cl_image_tag("sample.jpg", array("width"=>250, "height"=>250, "crop"=>"mfit"))
CloudinaryImage("sample.jpg").image(width=250, height=250, crop="mfit")
cloudinary.image("sample.jpg", {width: 250, height: 250, crop: "mfit"})
cloudinary.url().transformation(new Transformation().width(250).height(250).crop("mfit")).imageTag("sample.jpg")
$.cloudinary.image("sample.jpg", {width: 250, height: 250, crop: "mfit"})
cloudinary.Api.UrlImgUp.Transform(new Transformation().Width(250).Height(250).Crop("mfit")).BuildImageTag("sample.jpg")
fill
Create an image with the exact given width and height while retaining the original aspect ratio, using only part of the image that fills the given dimensions if necessary (only part of the original image might be visible if the requested aspect ratio is different from the original aspect ratio). You can also specify which part of the original image to use for filling the required dimensions in case the proportions do not match by using the gravity parameter (set to center
by default).
Examples of fill used with the uploaded jpg image named sample
:
Filled to a width and height of 250 pixels while retaining the aspect ratio:
Ruby:cl_image_tag("sample.jpg", :width=>250, :height=>250, :crop=>"fill")
PHP:cl_image_tag("sample.jpg", array("width"=>250, "height"=>250, "crop"=>"fill"))
Python:CloudinaryImage("sample.jpg").image(width=250, height=250, crop="fill")
Node.js:cloudinary.image("sample.jpg", {width: 250, height: 250, crop: "fill"})
Java:cloudinary.url().transformation(new Transformation().width(250).height(250).crop("fill")).imageTag("sample.jpg")
jQuery:$.cloudinary.image("sample.jpg", {width: 250, height: 250, crop: "fill"})
.Net:cloudinary.Api.UrlImgUp.Transform(new Transformation().Width(250).Height(250).Crop("fill")).BuildImageTag("sample.jpg")
Filled to a width and height of 250 pixels with east gravity:
Ruby:cl_image_tag("sample.jpg", :width=>250, :height=>250, :gravity=>"east", :crop=>"fill")
PHP:cl_image_tag("sample.jpg", array("width"=>250, "height"=>250, "gravity"=>"east", "crop"=>"fill"))
Python:CloudinaryImage("sample.jpg").image(width=250, height=250, gravity="east", crop="fill")
Node.js:cloudinary.image("sample.jpg", {width: 250, height: 250, gravity: "east", crop: "fill"})
Java:cloudinary.url().transformation(new Transformation().width(250).height(250).gravity("east").crop("fill")).imageTag("sample.jpg")
jQuery:$.cloudinary.image("sample.jpg", {width: 250, height: 250, gravity: "east", crop: "fill"})
.Net:cloudinary.Api.UrlImgUp.Transform(new Transformation().Width(250).Height(250).Gravity("east").Crop("fill")).BuildImageTag("sample.jpg")
lfill (limit fill)
Same as the fill
mode but only if the original image is larger than the given limit (width and height), in which case the image is scaled down to fill the given width and height while retaining the original aspect ratio, using only part of the image that fills the given dimensions if necessary (only part of the original image might be visible if the requested aspect ratio is different from the original aspect ratio). You can also specify which part of the original image to use for filling the required dimensions in case the proportions do not match by using the gravity parameter. This mode doesn't scale up the image if your requested dimensions are bigger than the original image's.
For example, the uploaded image named sample
limit filled to a width of 150 pixels and a height of 200 pixels while retaining the aspect ratio and limiting the size to no larger than the original image:
cl_image_tag("sample.jpg", :width=>150, :height=>200, :crop=>"lfill")
cl_image_tag("sample.jpg", array("width"=>150, "height"=>200, "crop"=>"lfill"))
CloudinaryImage("sample.jpg").image(width=150, height=200, crop="lfill")
cloudinary.image("sample.jpg", {width: 150, height: 200, crop: "lfill"})
cloudinary.url().transformation(new Transformation().width(150).height(200).crop("lfill")).imageTag("sample.jpg")
$.cloudinary.image("sample.jpg", {width: 150, height: 200, crop: "lfill"})
cloudinary.Api.UrlImgUp.Transform(new Transformation().Width(150).Height(200).Crop("lfill")).BuildImageTag("sample.jpg")
pad
Resize the image to fill the given width and height while retaining the original aspect ratio and with all of the original image visible. If the proportions of the original image do not match the given width and height, padding is added to the image to reach the required size. You can also specify where the original image is placed by using the gravity parameter (set to center
by default), and specify the color of the background in the case that padding is added.
For example, the uploaded jpg image named sample
padded with a black background to a width and height of 250 pixels:
cl_image_tag("sample.jpg", :width=>250, :height=>250, :background=>"black", :crop=>"pad")
cl_image_tag("sample.jpg", array("width"=>250, "height"=>250, "background"=>"black", "crop"=>"pad"))
CloudinaryImage("sample.jpg").image(width=250, height=250, background="black", crop="pad")
cloudinary.image("sample.jpg", {width: 250, height: 250, background: "black", crop: "pad"})
cloudinary.url().transformation(new Transformation().width(250).height(250).background("black").crop("pad")).imageTag("sample.jpg")
$.cloudinary.image("sample.jpg", {width: 250, height: 250, background: "black", crop: "pad"})
cloudinary.Api.UrlImgUp.Transform(new Transformation().Width(250).Height(250).Background("black").Crop("pad")).BuildImageTag("sample.jpg")
lpad (limit pad)
Same as the pad
mode but only if the original image is larger than the given limit (width and height), in which case the image is scaled down to fill the given width and height while retaining the original aspect ratio and with all of the original image visible. This mode doesn't scale up the image if your requested dimensions are bigger than the original image's. If the proportions of the original image do not match the given width and height, padding is added to the image to reach the required size. You can also specify where the original image is placed by using the gravity parameter (set to center
by default), and specify the color of the background in the case that padding is added.
For example, the uploaded jpg image named sample
limit padded with a green background to a width of 400 pixels and a height of 150 pixels:
cl_image_tag("sample.jpg", :width=>400, :height=>150, :background=>"green", :crop=>"lpad")
cl_image_tag("sample.jpg", array("width"=>400, "height"=>150, "background"=>"green", "crop"=>"lpad"))
CloudinaryImage("sample.jpg").image(width=400, height=150, background="green", crop="lpad")
cloudinary.image("sample.jpg", {width: 400, height: 150, background: "green", crop: "lpad"})
cloudinary.url().transformation(new Transformation().width(400).height(150).background("green").crop("lpad")).imageTag("sample.jpg")
$.cloudinary.image("sample.jpg", {width: 400, height: 150, background: "green", crop: "lpad"})
cloudinary.Api.UrlImgUp.Transform(new Transformation().Width(400).Height(150).Background("green").Crop("lpad")).BuildImageTag("sample.jpg")
mpad (minimum pad)
Same as the pad
mode but only if the original image is smaller than the given minimum (width and height), in which case the image is scaled up to fill the given width and height while retaining the original aspect ratio and with all of the original image visible. This mode doesn't scale down the image if your requested dimensions are smaller than the original image's. If the proportions of the original image do not match the given width and height, padding is added to the image to reach the required size. You can also specify where the original image is placed by using the gravity parameter (set to center
by default), and specify the color of the background in the case that padding is added.
For example, attempting to minimum pad the uploaded image named sample
to a width and height of 250 pixels while retaining the aspect ratio, results in delivering the original larger image:
cl_image_tag("sample.jpg", :width=>250, :height=>250, :crop=>"mpad")
cl_image_tag("sample.jpg", array("width"=>250, "height"=>250, "crop"=>"mpad"))
CloudinaryImage("sample.jpg").image(width=250, height=250, crop="mpad")
cloudinary.image("sample.jpg", {width: 250, height: 250, crop: "mpad"})
cloudinary.url().transformation(new Transformation().width(250).height(250).crop("mpad")).imageTag("sample.jpg")
$.cloudinary.image("sample.jpg", {width: 250, height: 250, crop: "mpad"})
cloudinary.Api.UrlImgUp.Transform(new Transformation().Width(250).Height(250).Crop("mpad")).BuildImageTag("sample.jpg")
crop
Extract a region of the given width and height out of the original image. The original proportions are retained and so is the size of the graphics. You can specify the gravity parameter to select which part of the image to extract, or use fixed coordinates cropping.
For example, the uploaded jpg image named sample
cropped to a width of 200 pixels, a height of 150 pixels, with northwest gravity:
cl_image_tag("sample.jpg", :width=>200, :height=>150, :gravity=>"north_west", :crop=>"crop")
cl_image_tag("sample.jpg", array("width"=>200, "height"=>150, "gravity"=>"north_west", "crop"=>"crop"))
CloudinaryImage("sample.jpg").image(width=200, height=150, gravity="north_west", crop="crop")
cloudinary.image("sample.jpg", {width: 200, height: 150, gravity: "north_west", crop: "crop"})
cloudinary.url().transformation(new Transformation().width(200).height(150).gravity("north_west").crop("crop")).imageTag("sample.jpg")
$.cloudinary.image("sample.jpg", {width: 200, height: 150, gravity: "north_west", crop: "crop"})
cloudinary.Api.UrlImgUp.Transform(new Transformation().Width(200).Height(150).Gravity("north_west").Crop("crop")).BuildImageTag("sample.jpg")
Fixed coordinates cropping
You can specify a region of the original image to crop by giving the x
and y
coordinates of the top left corner of the region together with the width
and height
of the region. You can also use percentage based numbers instead of the exact coordinates for x
, y
, w
and h
(e.g., 0.5 for 50%) . Use this method when you know beforehand what the correct absolute cropping coordinates are, as in when your users manually select the region to crop out of the original image.
For example, the following image shows many white sheep and one brown sheep.
cl_image_tag("brown_sheep.jpg")
cl_image_tag("brown_sheep.jpg")
CloudinaryImage("brown_sheep.jpg").image()
cloudinary.image("brown_sheep.jpg")
cloudinary.url().imageTag("brown_sheep.jpg")
$.cloudinary.image("brown_sheep.jpg")
cloudinary.Api.UrlImgUp.BuildImageTag("brown_sheep.jpg")
To manipulate the picture so that only the brown sheep is visible, the image is cropped to a 300x200 region starting at the coordinate x = 355 and y = 410:
cl_image_tag("brown_sheep.jpg", :x=>355, :y=>410, :width=>300, :height=>200, :crop=>"crop")
cl_image_tag("brown_sheep.jpg", array("x"=>355, "y"=>410, "width"=>300, "height"=>200, "crop"=>"crop"))
CloudinaryImage("brown_sheep.jpg").image(x=355, y=410, width=300, height=200, crop="crop")
cloudinary.image("brown_sheep.jpg", {x: 355, y: 410, width: 300, height: 200, crop: "crop"})
cloudinary.url().transformation(new Transformation().x(355).y(410).width(300).height(200).crop("crop")).imageTag("brown_sheep.jpg")
$.cloudinary.image("brown_sheep.jpg", {x: 355, y: 410, width: 300, height: 200, crop: "crop"})
cloudinary.Api.UrlImgUp.Transform(new Transformation().X(355).Y(410).Width(300).Height(200).Crop("crop")).BuildImageTag("brown_sheep.jpg")
The image can be further manipulated with chained transformations. For example, the 300x200 cropped version above, also scaled down to 150x100:
cl_image_tag("brown_sheep.jpg", :transformation=>[ {:x=>355, :y=>410, :width=>300, :height=>200, :crop=>"crop"}, {:width=>150, :height=>100, :crop=>"scale"} ])
cl_image_tag("brown_sheep.jpg", array("transformation"=>array( array("x"=>355, "y"=>410, "width"=>300, "height"=>200, "crop"=>"crop"), array("width"=>150, "height"=>100, "crop"=>"scale") )))
CloudinaryImage("brown_sheep.jpg").image(transformation=[ {"x": 355, "y": 410, "width": 300, "height": 200, "crop": "crop"}, {"width": 150, "height": 100, "crop": "scale"} ])
cloudinary.image("brown_sheep.jpg", {transformation: [ {x: 355, y: 410, width: 300, height: 200, crop: "crop"}, {width: 150, height: 100, crop: "scale"} ]})
cloudinary.url().transformation(new Transformation() .x(355).y(410).width(300).height(200).crop("crop").chain() .width(150).height(100).crop("scale")).imageTag("brown_sheep.jpg")
$.cloudinary.image("brown_sheep.jpg", {transformation: [ {x: 355, y: 410, width: 300, height: 200, crop: "crop"}, {width: 150, height: 100, crop: "scale"} ]})
cloudinary.Api.UrlImgUp.Transform(new Transformation() .X(355).Y(410).Width(300).Height(200).Crop("crop").Chain() .Width(150).Height(100).Crop("scale")).BuildImageTag("brown_sheep.jpg")
thumb
The thumb
cropping mode is specifically used for creating image thumbnails from either face or custom coordinates, and must always be accompanied by the gravity parameter set to one of the face detection or custom values. This cropping mode generates a thumbnail of an image with the exact given width and height dimensions and with the original proportions retained, but the resulting image might be scaled to fit in the given dimensions. You can specify the zoom parameter to determine how much to scale the resulting image within the given width and height.
For example, creating a 150x150 thumbnail with face detection, of the uploaded image called woman
. Below you can see the original image as well as the face detection based thumbnail:
cl_image_tag("woman.jpg", :gravity=>"face", :width=>150, :height=>150, :crop=>"thumb")
cl_image_tag("woman.jpg", array("gravity"=>"face", "width"=>150, "height"=>150, "crop"=>"thumb"))
CloudinaryImage("woman.jpg").image(gravity="face", width=150, height=150, crop="thumb")
cloudinary.image("woman.jpg", {gravity: "face", width: 150, height: 150, crop: "thumb"})
cloudinary.url().transformation(new Transformation().gravity("face").width(150).height(150).crop("thumb")).imageTag("woman.jpg")
$.cloudinary.image("woman.jpg", {gravity: "face", width: 150, height: 150, crop: "thumb"})
cloudinary.Api.UrlImgUp.Transform(new Transformation().Gravity("face").Width(150).Height(150).Crop("thumb")).BuildImageTag("woman.jpg")
Imagga crop and scale
The Imagga Crop and Scale add-on can be used to smartly scale and crop your images based on automatically calculated areas of interest within each specific photo. See the Imagga Crop and Scale add-on documentation for more information.
For example, the original image:
cl_image_tag("family_bench.jpg")
cl_image_tag("family_bench.jpg")
CloudinaryImage("family_bench.jpg").image()
cloudinary.image("family_bench.jpg")
cloudinary.url().imageTag("family_bench.jpg")
$.cloudinary.image("family_bench.jpg")
cloudinary.Api.UrlImgUp.BuildImageTag("family_bench.jpg")
Image with Imagga cropping:
cl_image_tag("family_bench.jpg", :crop=>"imagga_crop")
cl_image_tag("family_bench.jpg", array("crop"=>"imagga_crop"))
CloudinaryImage("family_bench.jpg").image(crop="imagga_crop")
cloudinary.image("family_bench.jpg", {crop: "imagga_crop"})
cloudinary.url().transformation(new Transformation().crop("imagga_crop")).imageTag("family_bench.jpg")
$.cloudinary.image("family_bench.jpg", {crop: "imagga_crop"})
cloudinary.Api.UrlImgUp.Transform(new Transformation().Crop("imagga_crop")).BuildImageTag("family_bench.jpg")
Aspect ratio based cropping
Use the aspect_ratio
parameter (ar
in URLs) to resize or crop the image to a new aspect ratio. This parameter is used together with a specified crop mode (scale, fill, lfill, pad, lpad, mpad or crop), that determines how the image is adjusted to the new dimensions. This parameter can also be used when changing the dimensions of an image with only the width
or height
parameters (w
and h
in URLs) - the other dimension is then automatically updated to maintain the given aspect ratio.
The aspect_ratio
parameter accepts a value in one of the following forms:
a:b
wherea
signifies the relative width andb
the relative height (e.g., 4:3 or 16:9).- a decimal value representing the ratio of the width divided by the height (e.g., 1.33 or 2.5).
Examples with the uploaded image named sample
:
- Cropped to an aspect ratio of 2.5:
Ruby:
cl_image_tag("sample.jpg", :aspect_ratio=>"2.5", :crop=>"crop")
PHP:cl_image_tag("sample.jpg", array("aspect_ratio"=>"2.5", "crop"=>"crop"))
Python:CloudinaryImage("sample.jpg").image(aspect_ratio="2.5", crop="crop")
Node.js:cloudinary.image("sample.jpg", {aspect_ratio: "2.5", crop: "crop"})
Java:cloudinary.url().transformation(new Transformation().aspectRatio("2.5").crop("crop")).imageTag("sample.jpg")
jQuery:$.cloudinary.image("sample.jpg", {aspect_ratio: "2.5", crop: "crop"})
.Net:cloudinary.Api.UrlImgUp.Transform(new Transformation().AspectRatio("2.5").Crop("crop")).BuildImageTag("sample.jpg")
- Filled to an aspect ratio of 16:9:
Ruby:
cl_image_tag("sample.jpg", :aspect_ratio=>"16:9", :crop=>"fill")
PHP:cl_image_tag("sample.jpg", array("aspect_ratio"=>"16:9", "crop"=>"fill"))
Python:CloudinaryImage("sample.jpg").image(aspect_ratio="16:9", crop="fill")
Node.js:cloudinary.image("sample.jpg", {aspect_ratio: "16:9", crop: "fill"})
Java:cloudinary.url().transformation(new Transformation().aspectRatio("16:9").crop("fill")).imageTag("sample.jpg")
jQuery:$.cloudinary.image("sample.jpg", {aspect_ratio: "16:9", crop: "fill"})
.Net:cloudinary.Api.UrlImgUp.Transform(new Transformation().AspectRatio("16:9").Crop("fill")).BuildImageTag("sample.jpg")
- Filled to a width of 400 pixels with an aspect ratio of 4:3:
Ruby:
cl_image_tag("sample.jpg", :width=>400, :aspect_ratio=>"4:3", :crop=>"fill")
PHP:cl_image_tag("sample.jpg", array("width"=>400, "aspect_ratio"=>"4:3", "crop"=>"fill"))
Python:CloudinaryImage("sample.jpg").image(width=400, aspect_ratio="4:3", crop="fill")
Node.js:cloudinary.image("sample.jpg", {width: 400, aspect_ratio: "4:3", crop: "fill"})
Java:cloudinary.url().transformation(new Transformation().width(400).aspectRatio("4:3").crop("fill")).imageTag("sample.jpg")
jQuery:$.cloudinary.image("sample.jpg", {width: 400, aspect_ratio: "4:3", crop: "fill"})
.Net:cloudinary.Api.UrlImgUp.Transform(new Transformation().Width(400).AspectRatio("4:3").Crop("fill")).BuildImageTag("sample.jpg")
Control gravity
The gravity
parameter (g
in URLs) is used to specify a location in the image that is used as the focus for another transformation:
- For certain cropping modes, gravity specifies which part of the original image to focus on (include) when the resulting image is smaller than than the original or the proportions do not match.
- For placing underlays, overlays or text captions, gravity specifies where to place them in relation to the original image.
The basic gravity value is specified by giving a compass direction to focus on: north_east
, north
, north_west
, west
, south_west
, south
, south_east
, east
, or center
(the default value). The compass direction represents a location in the image, for example, north_east
represents the top right corner.
For example, the uploaded jpg image named sample
filled to a width and height of 250 pixels while retaining the aspect ratio:
- Original image: Ruby:
cl_image_tag("sample.jpg")
PHP:cl_image_tag("sample.jpg")
Python:CloudinaryImage("sample.jpg").image()
Node.js:cloudinary.image("sample.jpg")
Java:cloudinary.url().imageTag("sample.jpg")
jQuery:$.cloudinary.image("sample.jpg")
.Net:cloudinary.Api.UrlImgUp.BuildImageTag("sample.jpg")
- With gravity set to north: Ruby:
cl_image_tag("sample.jpg", :width=>250, :height=>250, :gravity=>"north", :crop=>"fill")
PHP:cl_image_tag("sample.jpg", array("width"=>250, "height"=>250, "gravity"=>"north", "crop"=>"fill"))
Python:CloudinaryImage("sample.jpg").image(width=250, height=250, gravity="north", crop="fill")
Node.js:cloudinary.image("sample.jpg", {width: 250, height: 250, gravity: "north", crop: "fill"})
Java:cloudinary.url().transformation(new Transformation().width(250).height(250).gravity("north").crop("fill")).imageTag("sample.jpg")
jQuery:$.cloudinary.image("sample.jpg", {width: 250, height: 250, gravity: "north", crop: "fill"})
.Net:cloudinary.Api.UrlImgUp.Transform(new Transformation().Width(250).Height(250).Gravity("north").Crop("fill")).BuildImageTag("sample.jpg")
- With gravity set to south_east: Ruby:
cl_image_tag("sample.jpg", :width=>250, :height=>250, :gravity=>"south_east", :crop=>"fill")
PHP:cl_image_tag("sample.jpg", array("width"=>250, "height"=>250, "gravity"=>"south_east", "crop"=>"fill"))
Python:CloudinaryImage("sample.jpg").image(width=250, height=250, gravity="south_east", crop="fill")
Node.js:cloudinary.image("sample.jpg", {width: 250, height: 250, gravity: "south_east", crop: "fill"})
Java:cloudinary.url().transformation(new Transformation().width(250).height(250).gravity("south_east").crop("fill")).imageTag("sample.jpg")
jQuery:$.cloudinary.image("sample.jpg", {width: 250, height: 250, gravity: "south_east", crop: "fill"})
.Net:cloudinary.Api.UrlImgUp.Transform(new Transformation().Width(250).Height(250).Gravity("south_east").Crop("fill")).BuildImageTag("sample.jpg")
More advanced gravity parameters include:
xy_center
- Set the center of gravity to the givenx
&y
coordinates.face
- Automatically detect the largest face in an image and make it the focus of the transformation. Any previously specified face coordinates (during upload, with the Admin API, or via the Management Console) override the automatically detected faces and are used instead. Defaults tonorth
gravity if no faces are detected or previously specified.faces
- Same asface
gravity, but detects all the faces in an image and makes them the focus of the transformation. Any previously specified face coordinates (during upload, with the Admin API, or via the Management Console) override the automatically detected faces and are used instead. Defaults tonorth
gravity if no faces are detected or previously specified.face:center
- Same asface
gravity, but defaults tocenter
gravity if no face is detected.faces:center
- Same asfaces
gravity, but defaults tocenter
gravity if no face is detected.adv_face
- Automatically detect the largest face in an image with the Advanced Facial Attribute Detection add-on and make it the focus of the transformation.adv_faces
- Automatically detect all faces in an image with the Advanced Facial Attribute Detection add-on and make them the focus of the transformation.adv_eyes
- Automatically detect all eyes in an image with the Advanced Facial Attribute Detection add-on and make them the focus of the transformation.custom
- Use custom coordinates that were previously specified (e.g., as part of the image upload method) and make them the focus of the transformation. Defaults to 'center' gravity if no custom coordinates have been specified.custom:face
- Same ascustom
gravity, but defaults toface
gravity if no custom coordinates have been specified.custom:faces
- Same ascustom
gravity, but defaults tofaces
gravity if no custom coordinates have been specified.custom:adv_face
- Same ascustom
gravity, but defaults toadv_face
gravity if no custom coordinates have been specified.custom:adv_faces
- Same ascustom
gravity, but defaults toadv_faces
gravity if no custom coordinates have been specified.
Note: The fallback (default) values are only relevant when setting gravity for cropping modes and not when setting gravity for placing overlays. For example, if gravity is set to 'face' for placing an overlay, and no face is detected in the image, then the overlay is ignored.
Automatic cropping
Cloudinary's intelligent cropping capabilities ensure that the most interesting areas of each image are included in the resulting derived image, not only for photos with faces, but for any content type. Each image is analyzed individually to find the optimal region to focus on while cropping, and automatically detected faces (or other elements) are given higher priority while analyzing the image content (note that any custom coordinates defined will override the detection algorithm).
The Cloudinary content-aware cropping algorithm uses a combination of heuristics to automatically detect the region of interest in every image and then crop them on the fly. Automatic cropping is supported by setting the gravity
transformation parameter to auto
(g_auto
in URLs):
g_auto
1 - The default mode that gives higher priority to automatically detected faces (the same asg_auto:faces
).g_auto:[focal_gravity]
1 - (e.g.,g_auto:adv_face
). Specific focal gravities can be specified in order to give higher priority to other auto detected regions rather than the default of giving priority to detected faces. Supported options for focal_gravity:adv_face
,adv_faces
,adv_eyes
,body
,face
, andfaces
(default).g_auto:no_faces
1 - the algorithm will process the image without giving higher priority to any detected elements (e.g., auto detected faces).g_auto:custom_no_override
- Don't override the algorithm with the custom coordinates but give higher priority to the custom coordinates when determining the region of interest.g_auto:none
- Perform analysis of the image content without giving precedence to custom coordinates or higher priority to any detected element.g_auto:[level]
1 - (Only relevant for the thumb cropping mode). The level of aggressiveness of the cropping algorithm between 0 and 100, where 100 tries to keep more of the original image, and 0 crops more aggressively and then zooms in to image. e.g.,g_auto:50
,g_auto:adv_faces:0
. The default is 100.
1 If custom coordinates have been specified for an image (using the Upload API or the Management Console), the cropping will be done according to them, taking the custom coordinates as-is and overriding the detection algorithm (the same as g_custom
). This applies to all the g_auto
options above except for g_auto:custom_no_override
and g_auto:none
.
Automatic cropping is supported for the fill, lfill, thumb and crop modes.
Automatic cropping with the fill mode
Keeping the most of the original image according to the requested dimensions of the derived image. Ensuring that as much as possible of the most interesting regions of the original image is included in the resulting image.
Example of portrait aspect ratio cropping, regular vs. automatic:
cl_image_tag("basketball_in_net.jpg", :width=>200, :height=>300, :gravity=>"auto", :crop=>"fill")
cl_image_tag("basketball_in_net.jpg", array("width"=>200, "height"=>300, "gravity"=>"auto", "crop"=>"fill"))
CloudinaryImage("basketball_in_net.jpg").image(width=200, height=300, gravity="auto", crop="fill")
cloudinary.image("basketball_in_net.jpg", {width: 200, height: 300, gravity: "auto", crop: "fill"})
cloudinary.url().transformation(new Transformation().width(200).height(300).gravity("auto").crop("fill")).imageTag("basketball_in_net.jpg")
$.cloudinary.image("basketball_in_net.jpg", {width: 200, height: 300, gravity: "auto", crop: "fill"})
cloudinary.Api.UrlImgUp.Transform(new Transformation().Width(200).Height(300).Gravity("auto").Crop("fill")).BuildImageTag("basketball_in_net.jpg")
Example of square aspect ratio cropping, regular vs. automatic:
cl_image_tag("face_left.jpg", :width=>200, :height=>200, :gravity=>"auto", :crop=>"fill")
cl_image_tag("face_left.jpg", array("width"=>200, "height"=>200, "gravity"=>"auto", "crop"=>"fill"))
CloudinaryImage("face_left.jpg").image(width=200, height=200, gravity="auto", crop="fill")
cloudinary.image("face_left.jpg", {width: 200, height: 200, gravity: "auto", crop: "fill"})
cloudinary.url().transformation(new Transformation().width(200).height(200).gravity("auto").crop("fill")).imageTag("face_left.jpg")
$.cloudinary.image("face_left.jpg", {width: 200, height: 200, gravity: "auto", crop: "fill"})
cloudinary.Api.UrlImgUp.Transform(new Transformation().Width(200).Height(200).Gravity("auto").Crop("fill")).BuildImageTag("face_left.jpg")
Automatic cropping with the lfill mode
Same as the fill mode, but only if the original image is larger than the given limit (width and height). This mode doesn't scale up the image if your requested dimensions are bigger than the original image's.
Automatic cropping with the thumb mode
Makes possible more aggressive cropping than the fill mode. This mode attempts to further zoom in and crop out less interesting image regions when relevant in order to include the most interesting objects in the resulting derived image. The automatic cropping algorithm decides whether and how aggressively to zoom-in and crop according to the content and cropping ratio of each image individually. A numerical value between 0 and 100 can be added to the g_auto
parameter in order to advise the algorithm regarding the desired aggressiveness level (e.g., g_auto:0
for the most aggressive thumb cropping).
Example of a square thumbnail, regular vs. automatic cropping:
cl_image_tag("sunset_shoes.jpg", :width=>150, :height=>150, :gravity=>"auto:0", :crop=>"thumb")
cl_image_tag("sunset_shoes.jpg", array("width"=>150, "height"=>150, "gravity"=>"auto:0", "crop"=>"thumb"))
CloudinaryImage("sunset_shoes.jpg").image(width=150, height=150, gravity="auto:0", crop="thumb")
cloudinary.image("sunset_shoes.jpg", {width: 150, height: 150, gravity: "auto:0", crop: "thumb"})
cloudinary.url().transformation(new Transformation().width(150).height(150).gravity("auto:0").crop("thumb")).imageTag("sunset_shoes.jpg")
$.cloudinary.image("sunset_shoes.jpg", {width: 150, height: 150, gravity: "auto:0", crop: "thumb"})
cloudinary.Api.UrlImgUp.Transform(new Transformation().Width(150).Height(150).Gravity("auto:0").Crop("thumb")).BuildImageTag("sunset_shoes.jpg")
Automatic cropping with the crop mode
Crop a region of exactly the given width and height out of the original image while automatically focusing on the most interesting region of the original image that fits within the required dimensions. The portion of the interesting area depends on the resolution of the original image. The crop
mode is less useful than the fill, lfill, and thumb modes, as it is only practical to use when both the dimensions of the original image and the size of the interesting region are already known.
Example of a square crop, regular vs. auto cropping:
cl_image_tag("fat_cat.jpg", :width=>200, :height=>200, :gravity=>"auto", :crop=>"crop")
cl_image_tag("fat_cat.jpg", array("width"=>200, "height"=>200, "gravity"=>"auto", "crop"=>"crop"))
CloudinaryImage("fat_cat.jpg").image(width=200, height=200, gravity="auto", crop="crop")
cloudinary.image("fat_cat.jpg", {width: 200, height: 200, gravity: "auto", crop: "crop"})
cloudinary.url().transformation(new Transformation().width(200).height(200).gravity("auto").crop("crop")).imageTag("fat_cat.jpg")
$.cloudinary.image("fat_cat.jpg", {width: 200, height: 200, gravity: "auto", crop: "crop"})
cloudinary.Api.UrlImgUp.Transform(new Transformation().Width(200).Height(200).Gravity("auto").Crop("crop")).BuildImageTag("fat_cat.jpg")
Face detection based transformations
Cloudinary provides face detection algorithms for automatically applying transformations according to the detected faces within an image. This section consists of the following topics:
- Face detection based cropping
- Position overlays on detected faces
- Effects with face detection
- Advanced facial attributes detection
- Changing the default zoom level
Face detection based cropping
Cloudinary supports built-in face detection capabilities that allow you to intelligently crop your images. To automatically crop an image so that the detected face(s) is used as the center of the derived picture, set the gravity
parameter to one of the following values:
face
- the region of the image that includes the single largest face (g_face
for URLs).faces
- the region of the image that includes all the faces detected (g_faces
for URLs).
For example, the image below of a nice woman with a Blue Morpho butterfly was uploaded to Cloudinary:
cl_image_tag("butterfly.jpg")
cl_image_tag("butterfly.jpg")
CloudinaryImage("butterfly.jpg").image()
cloudinary.image("butterfly.jpg")
cloudinary.url().imageTag("butterfly.jpg")
$.cloudinary.image("butterfly.jpg")
cloudinary.Api.UrlImgUp.BuildImageTag("butterfly.jpg")
To create a 200x200 version with the fill cropping mode to keep as much as possible of the original image, and using the default center
gravity without face detection (for comparison):
cl_image_tag("butterfly.jpg", :width=>200, :height=>200, :crop=>"fill")
cl_image_tag("butterfly.jpg", array("width"=>200, "height"=>200, "crop"=>"fill"))
CloudinaryImage("butterfly.jpg").image(width=200, height=200, crop="fill")
cloudinary.image("butterfly.jpg", {width: 200, height: 200, crop: "fill"})
cloudinary.url().transformation(new Transformation().width(200).height(200).crop("fill")).imageTag("butterfly.jpg")
$.cloudinary.image("butterfly.jpg", {width: 200, height: 200, crop: "fill"})
cloudinary.Api.UrlImgUp.Transform(new Transformation().Width(200).Height(200).Crop("fill")).BuildImageTag("butterfly.jpg")
Now adding the face
gravity parameter to correctly fill the requested dimensions:
cl_image_tag("butterfly.jpg", :width=>200, :height=>200, :gravity=>"face", :crop=>"fill")
cl_image_tag("butterfly.jpg", array("width"=>200, "height"=>200, "gravity"=>"face", "crop"=>"fill"))
CloudinaryImage("butterfly.jpg").image(width=200, height=200, gravity="face", crop="fill")
cloudinary.image("butterfly.jpg", {width: 200, height: 200, gravity: "face", crop: "fill"})
cloudinary.url().transformation(new Transformation().width(200).height(200).gravity("face").crop("fill")).imageTag("butterfly.jpg")
$.cloudinary.image("butterfly.jpg", {width: 200, height: 200, gravity: "face", crop: "fill"})
cloudinary.Api.UrlImgUp.Transform(new Transformation().Width(200).Height(200).Gravity("face").Crop("fill")).BuildImageTag("butterfly.jpg")
In order to create a 200x200 thumbnail focused on the face of the woman, simply select the thumb
crop mode and face
gravity:
cl_image_tag("butterfly.jpg", :width=>200, :height=>200, :gravity=>"face", :crop=>"thumb")
cl_image_tag("butterfly.jpg", array("width"=>200, "height"=>200, "gravity"=>"face", "crop"=>"thumb"))
CloudinaryImage("butterfly.jpg").image(width=200, height=200, gravity="face", crop="thumb")
cloudinary.image("butterfly.jpg", {width: 200, height: 200, gravity: "face", crop: "thumb"})
cloudinary.url().transformation(new Transformation().width(200).height(200).gravity("face").crop("thumb")).imageTag("butterfly.jpg")
$.cloudinary.image("butterfly.jpg", {width: 200, height: 200, gravity: "face", crop: "thumb"})
cloudinary.Api.UrlImgUp.Transform(new Transformation().Width(200).Height(200).Gravity("face").Crop("thumb")).BuildImageTag("butterfly.jpg")
You can also automatically crop to the region defined by face detection without resizing the original image. The following example uses the crop
mode together with face
gravity for cropping the original image to the face of the woman:
cl_image_tag("butterfly.jpg", :gravity=>"face", :crop=>"crop")
cl_image_tag("butterfly.jpg", array("gravity"=>"face", "crop"=>"crop"))
CloudinaryImage("butterfly.jpg").image(gravity="face", crop="crop")
cloudinary.image("butterfly.jpg", {gravity: "face", crop: "crop"})
cloudinary.url().transformation(new Transformation().gravity("face").crop("crop")).imageTag("butterfly.jpg")
$.cloudinary.image("butterfly.jpg", {gravity: "face", crop: "crop"})
cloudinary.Api.UrlImgUp.Transform(new Transformation().Gravity("face").Crop("crop")).BuildImageTag("butterfly.jpg")
For examples with multiple faces, the following image, showing a nice couple, was uploaded to Cloudinary:
cl_image_tag("couple.jpg")
cl_image_tag("couple.jpg")
CloudinaryImage("couple.jpg").image()
cloudinary.image("couple.jpg")
cloudinary.url().imageTag("couple.jpg")
$.cloudinary.image("couple.jpg")
cloudinary.Api.UrlImgUp.BuildImageTag("couple.jpg")
You can specify the thumb
crop mode and face
gravity to create a 150x150 thumbnail centered on the face of only the biggest face in the image:
cl_image_tag("couple.jpg", :width=>150, :height=>150, :gravity=>"face", :crop=>"thumb")
cl_image_tag("couple.jpg", array("width"=>150, "height"=>150, "gravity"=>"face", "crop"=>"thumb"))
CloudinaryImage("couple.jpg").image(width=150, height=150, gravity="face", crop="thumb")
cloudinary.image("couple.jpg", {width: 150, height: 150, gravity: "face", crop: "thumb"})
cloudinary.url().transformation(new Transformation().width(150).height(150).gravity("face").crop("thumb")).imageTag("couple.jpg")
$.cloudinary.image("couple.jpg", {width: 150, height: 150, gravity: "face", crop: "thumb"})
cloudinary.Api.UrlImgUp.Transform(new Transformation().Width(150).Height(150).Gravity("face").Crop("thumb")).BuildImageTag("couple.jpg")
In order to create a thumbnail focusing on the faces of both of them, simply specify faces
as the gravity:
cl_image_tag("couple.jpg", :width=>115, :height=>135, :gravity=>"faces", :crop=>"thumb")
cl_image_tag("couple.jpg", array("width"=>115, "height"=>135, "gravity"=>"faces", "crop"=>"thumb"))
CloudinaryImage("couple.jpg").image(width=115, height=135, gravity="faces", crop="thumb")
cloudinary.image("couple.jpg", {width: 115, height: 135, gravity: "faces", crop: "thumb"})
cloudinary.url().transformation(new Transformation().width(115).height(135).gravity("faces").crop("thumb")).imageTag("couple.jpg")
$.cloudinary.image("couple.jpg", {width: 115, height: 135, gravity: "faces", crop: "thumb"})
cloudinary.Api.UrlImgUp.Transform(new Transformation().Width(115).Height(135).Gravity("faces").Crop("thumb")).BuildImageTag("couple.jpg")
You can also use the fill
cropping mode together with faces
gravity to correctly fill an image with your desired dimensions:
cl_image_tag("couple.jpg", :width=>100, :height=>150, :gravity=>"faces", :crop=>"fill")
cl_image_tag("couple.jpg", array("width"=>100, "height"=>150, "gravity"=>"faces", "crop"=>"fill"))
CloudinaryImage("couple.jpg").image(width=100, height=150, gravity="faces", crop="fill")
cloudinary.image("couple.jpg", {width: 100, height: 150, gravity: "faces", crop: "fill"})
cloudinary.url().transformation(new Transformation().width(100).height(150).gravity("faces").crop("fill")).imageTag("couple.jpg")
$.cloudinary.image("couple.jpg", {width: 100, height: 150, gravity: "faces", crop: "fill"})
cloudinary.Api.UrlImgUp.Transform(new Transformation().Width(100).Height(150).Gravity("faces").Crop("fill")).BuildImageTag("couple.jpg")
Position overlays on detected faces
To automatically position an overlay over the detected face(s) in an image, set the gravity
parameter to one of the following values:
face
- places an overlay over the single largest face in the image (g_face
for URLs).faces
- places an overlay over each of the faces in the image (g_faces
for URLs).
For example, adding an overlay of the golden_star
image over both of the faces detected in the young_couples
image, where each star is resized to the same width as the detected face with the region_relative
flag:
cl_image_tag("young_couple.jpg", :overlay=>"golden_star", :gravity=>"faces", :width=>1.0, :flags=>"region_relative")
cl_image_tag("young_couple.jpg", array("overlay"=>"golden_star", "gravity"=>"faces", "width"=>1.0, "flags"=>"region_relative"))
CloudinaryImage("young_couple.jpg").image(overlay="golden_star", gravity="faces", width=1.0, flags="region_relative")
cloudinary.image("young_couple.jpg", {overlay: "golden_star", gravity: "faces", width: 1.0, flags: "region_relative"})
cloudinary.url().transformation(new Transformation().overlay("golden_star").gravity("faces").width(1.0).flags("region_relative")).imageTag("young_couple.jpg")
$.cloudinary.image("young_couple.jpg", {overlay: "golden_star", gravity: "faces", width: 1.0, flags: "region_relative"})
cloudinary.Api.UrlImgUp.Transform(new Transformation().Overlay("golden_star").Gravity("faces").Width(1.0).Flags("region_relative")).BuildImageTag("young_couple.jpg")
Note: When gravity is set to one of the facial detection values and no face is detected in the image, then no overlay is placed at all.
Effects with face detection
To apply a blur or pixelation effect to the automatically detected faces in an image, use the effect
parameter and set it to one of the following values:
blur_faces
- Automatically blur all detected faces in the image: the strength of the blur effect is determined by an optional extra value (Range: 1 to 2000, Default: 500). For example,e_blur_faces:100
uses a mild blur effect with a strength of 100.pixelate_faces
- Automatically pixelate all detected faces in the image. The width of the pixelation squares is determined by an optional extra value (Range: 1 to 200, Default: 5). For example,e_pixelate_faces:3
uses pixelation squares 3 pixels wide.
For example, to automatically pixelate both of the faces detected in the young_couples
image with pixelation squares 9 pixels wide:
cl_image_tag("young_couple.jpg", :effect=>"pixelate_faces:9")
cl_image_tag("young_couple.jpg", array("effect"=>"pixelate_faces:9"))
CloudinaryImage("young_couple.jpg").image(effect="pixelate_faces:9")
cloudinary.image("young_couple.jpg", {effect: "pixelate_faces:9"})
cloudinary.url().transformation(new Transformation().effect("pixelate_faces:9")).imageTag("young_couple.jpg")
$.cloudinary.image("young_couple.jpg", {effect: "pixelate_faces:9"})
cloudinary.Api.UrlImgUp.Transform(new Transformation().Effect("pixelate_faces:9")).BuildImageTag("young_couple.jpg")
Advanced facial attributes detection
With the Advanced Facial Attributes Detection add-on, you can extend the Cloudinary built-in features that involve semantic photo data extraction, image cropping and the positioning of image overlays. When using the add-on, your images are further processed and additional advanced face attributes are automatically extracted. Cloudinary can then use these additional details to smartly crop, position, rotate and overlay images according to the position of the detected faces or eyes.
The advanced facial detection is applied by setting the gravity
parameter to one of the following values:
adv_face
- detects the single largest face in the image (g_adv_face
for URLs).adv_faces
- detects all of the faces in the image (g_adv_faces
for URLs).adv_eyes
- detects all the pairs of eyes in the image (g_adv_eyes
for URLs).
For example, to automatically overlay the image glasses
over the detected eyes in the couples
image. The glasses are resized to 170% the width of the detected eyes by adding the region_relative
flag:
cl_image_tag("coupled.jpg", :flags=>"region_relative", :gravity=>"adv_eyes", :overlay=>"glasses", :width=>1.7)
cl_image_tag("coupled.jpg", array("flags"=>"region_relative", "gravity"=>"adv_eyes", "overlay"=>"glasses", "width"=>1.7))
CloudinaryImage("coupled.jpg").image(flags="region_relative", gravity="adv_eyes", overlay="glasses", width=1.7)
cloudinary.image("coupled.jpg", {flags: "region_relative", gravity: "adv_eyes", overlay: "glasses", width: 1.7})
cloudinary.url().transformation(new Transformation().flags("region_relative").gravity("adv_eyes").overlay("glasses").width(1.7)).imageTag("coupled.jpg")
$.cloudinary.image("coupled.jpg", {flags: "region_relative", gravity: "adv_eyes", overlay: "glasses", width: 1.7})
cloudinary.Api.UrlImgUp.Transform(new Transformation().Flags("region_relative").Gravity("adv_eyes").Overlay("glasses").Width(1.7)).BuildImageTag("coupled.jpg")
See the Advanced Facial Attributes Detection documentation for more information and examples on using the add-on.
Zoom level
When using either the crop or thumb cropping modes and setting the gravity parameter to one of the face detection values, the resulting image is delivered at a default zoom level. To control how much of the original image surrounding the face to keep, use the zoom
parameter (z
for URLs). This parameter accepts a decimal value that sets the new zoom level as a multiplier of the default zoom setting: a value less than 1.0 zooms out and a value greater than 1.0 zooms in. For example, z_0.5
halves the default zoom to 50% and zooms out to include more of the background around the face, while z_2.0
doubles the default zoom to 200% and zooms in to include less of the background around the face.
Examples with the uploaded image called woman
:
- Original image (scaled down): Ruby:
cl_image_tag("woman.jpg")
PHP:cl_image_tag("woman.jpg")
Python:CloudinaryImage("woman.jpg").image()
Node.js:cloudinary.image("woman.jpg")
Java:cloudinary.url().imageTag("woman.jpg")
jQuery:$.cloudinary.image("woman.jpg")
.Net:cloudinary.Api.UrlImgUp.BuildImageTag("woman.jpg")
- Cropped with face detection and default zoom: Ruby:
cl_image_tag("woman.jpg", :gravity=>"face", :crop=>"crop")
PHP:cl_image_tag("woman.jpg", array("gravity"=>"face", "crop"=>"crop"))
Python:CloudinaryImage("woman.jpg").image(gravity="face", crop="crop")
Node.js:cloudinary.image("woman.jpg", {gravity: "face", crop: "crop"})
Java:cloudinary.url().transformation(new Transformation().gravity("face").crop("crop")).imageTag("woman.jpg")
jQuery:$.cloudinary.image("woman.jpg", {gravity: "face", crop: "crop"})
.Net:cloudinary.Api.UrlImgUp.Transform(new Transformation().Gravity("face").Crop("crop")).BuildImageTag("woman.jpg")
- Cropped with face detection and zoom set to 130%: Ruby:
cl_image_tag("woman.jpg", :gravity=>"face", :zoom=>1.3, :crop=>"crop")
PHP:cl_image_tag("woman.jpg", array("gravity"=>"face", "zoom"=>1.3, "crop"=>"crop"))
Python:CloudinaryImage("woman.jpg").image(gravity="face", zoom=1.3, crop="crop")
Node.js:cloudinary.image("woman.jpg", {gravity: "face", zoom: 1.3, crop: "crop"})
Java:cloudinary.url().transformation(new Transformation().gravity("face").zoom(1.3).crop("crop")).imageTag("woman.jpg")
jQuery:$.cloudinary.image("woman.jpg", {gravity: "face", zoom: 1.3, crop: "crop"})
.Net:cloudinary.Api.UrlImgUp.Transform(new Transformation().Gravity("face").Zoom(1.3).Crop("crop")).BuildImageTag("woman.jpg")
- 150x150 thumbnail with face detection and default zoom: Ruby:
cl_image_tag("woman.jpg", :gravity=>"face", :width=>150, :height=>150, :crop=>"thumb")
PHP:cl_image_tag("woman.jpg", array("gravity"=>"face", "width"=>150, "height"=>150, "crop"=>"thumb"))
Python:CloudinaryImage("woman.jpg").image(gravity="face", width=150, height=150, crop="thumb")
Node.js:cloudinary.image("woman.jpg", {gravity: "face", width: 150, height: 150, crop: "thumb"})
Java:cloudinary.url().transformation(new Transformation().gravity("face").width(150).height(150).crop("thumb")).imageTag("woman.jpg")
jQuery:$.cloudinary.image("woman.jpg", {gravity: "face", width: 150, height: 150, crop: "thumb"})
.Net:cloudinary.Api.UrlImgUp.Transform(new Transformation().Gravity("face").Width(150).Height(150).Crop("thumb")).BuildImageTag("woman.jpg")
- 150x150 thumbnail with face detection and zoom set to 70%: Ruby:
cl_image_tag("woman.jpg", :gravity=>"face", :width=>150, :height=>150, :zoom=>0.7, :crop=>"thumb")
PHP:cl_image_tag("woman.jpg", array("gravity"=>"face", "width"=>150, "height"=>150, "zoom"=>0.7, "crop"=>"thumb"))
Python:CloudinaryImage("woman.jpg").image(gravity="face", width=150, height=150, zoom=0.7, crop="thumb")
Node.js:cloudinary.image("woman.jpg", {gravity: "face", width: 150, height: 150, zoom: 0.7, crop: "thumb"})
Java:cloudinary.url().transformation(new Transformation().gravity("face").width(150).height(150).zoom(0.7).crop("thumb")).imageTag("woman.jpg")
jQuery:$.cloudinary.image("woman.jpg", {gravity: "face", width: 150, height: 150, zoom: 0.7, crop: "thumb"})
.Net:cloudinary.Api.UrlImgUp.Transform(new Transformation().Gravity("face").Width(150).Height(150).Zoom(0.7).Crop("thumb")).BuildImageTag("woman.jpg")
For more examples on using the zoom parameter see the article on How to control the zoom level with automatic face detection based image cropping.
Image format conversion
Images can be uploaded to Cloudinary in various formats, and you can easily convert these images to other formats for displaying in your web site or application. Examples of situations where you might want to change the delivered image format:
- Delivering JPEGs for photos that you want to load quickly (or WebP if your users are on a Chrome browser or on a mobile app you control).
- Delivering a GIF if the image contains a drawing with only a few colors.
- Delivering a PNG (24 bit) for high quality illustrations with a transparent background.
You can dynamically convert images to your desired format. Cloudinary currently supports the following image formats:
Format | Extensions | Supported for Upload | Supported for Delivery |
---|---|---|---|
JPEG (Joint Photographic Experts Group) | .jpg, .jpe, .jpeg | Yes | Yes |
JPEG 2000 (JPEG 2000) | .jpc, .jp2, .j2k | Yes | Yes |
JPEG XR (JPEG eXtended Range) | .wdp, .jxr, .hdp | Yes | Yes |
PNG (Portable Network Graphics) | .png | Yes | Yes |
GIF (Graphics Interchange Format) | .gif | Yes | Yes |
WebP | .webp | Yes | Yes |
BMP (BitMaP image format) | .bmp | Yes | No |
TIFF (Tagged Image File Format) | .tif, .tiff | Yes | No |
ICO (ICOn image format) | .ico | Yes | No |
PDF (Portable Document Format) | Yes | Yes | |
EPS (Encapsulated PostScript) | .ps, .ept, .eps, .eps3 | Yes | No |
PSD (PhotoShop Document) | .psd | Yes | No |
SVG (Scalable Vector Graphics) | .svg | Yes | No |
AI (Adobe Illustrator) | .ai | Yes | No |
DjVu | .djvu | Yes | No |
FLIF (Free Lossless Image Format) | .flif | Yes | No |
TARGA (Truevision TGA) | .tga | Yes | No |
To deliver images in a different format simply specify the new format as the file extension of the delivery URL. When using our SDKs you can either specify the new format as an extension to the resource name or use the format
parameter.
For example, to display a GIF version of the uploaded sample
JPEG file:
cl_image_tag("sample.gif")
cl_image_tag("sample.gif")
CloudinaryImage("sample.gif").image()
cloudinary.image("sample.gif")
cloudinary.url().imageTag("sample.gif")
$.cloudinary.image("sample.gif")
cloudinary.Api.UrlImgUp.BuildImageTag("sample.gif")
You can easily combine other image transformations with format conversion. For example, to deliver a scaled down 150x100 GIF version of the sample
image:
cl_image_tag("sample.gif", :width=>150, :height=>100, :crop=>"scale")
cl_image_tag("sample.gif", array("width"=>150, "height"=>100, "crop"=>"scale"))
CloudinaryImage("sample.gif").image(width=150, height=100, crop="scale")
cloudinary.image("sample.gif", {width: 150, height: 100, crop: "scale"})
cloudinary.url().transformation(new Transformation().width(150).height(100).crop("scale")).imageTag("sample.gif")
$.cloudinary.image("sample.gif", {width: 150, height: 100, crop: "scale"})
cloudinary.Api.UrlImgUp.Transform(new Transformation().Width(150).Height(100).Crop("scale")).BuildImageTag("sample.gif")
Note: If the file extension is omitted from the delivery URL then the file is delivered in the originally uploaded format.
Fetch format
Another option for changing the format is to explicitly call the fetch_format
parameter (f
in URLs). This can be useful in situations where you cannot change the file extension, for example, when fetching remote images that already have a different file extension (format) as part of their URLs.
For example, to fetch a remote image from Wikimedia in JPEG format, and deliver the image in PNG format (also scaled down to a width of 400 pixels):
cl_image_tag("http://upload.wikimedia.org/wikipedia/commons/4/46/Jennifer_Lawrence_at_the_83rd_Academy_Awards.jpg", :width=>400, :format=>"png", :type=>"fetch")
cl_image_tag("http://upload.wikimedia.org/wikipedia/commons/4/46/Jennifer_Lawrence_at_the_83rd_Academy_Awards.jpg", array("width"=>400, "format"=>"png", "type"=>"fetch"))
CloudinaryImage("http://upload.wikimedia.org/wikipedia/commons/4/46/Jennifer_Lawrence_at_the_83rd_Academy_Awards.jpg").image(width=400, format="png", type="fetch")
cloudinary.image("http://upload.wikimedia.org/wikipedia/commons/4/46/Jennifer_Lawrence_at_the_83rd_Academy_Awards.jpg", {width: 400, format: "png", type: "fetch"})
cloudinary.url().transformation(new Transformation().width(400)).format("png").type("fetch").imageTag("http://upload.wikimedia.org/wikipedia/commons/4/46/Jennifer_Lawrence_at_the_83rd_Academy_Awards.jpg")
$.cloudinary.image("http://upload.wikimedia.org/wikipedia/commons/4/46/Jennifer_Lawrence_at_the_83rd_Academy_Awards.jpg", {width: 400, format: "png", type: "fetch"})
cloudinary.Api.UrlImgUp.Transform(new Transformation().Width(400)).Format("png").Type("fetch").BuildImageTag("http://upload.wikimedia.org/wikipedia/commons/4/46/Jennifer_Lawrence_at_the_83rd_Academy_Awards.jpg")
Automatic format selection
You can also use the fetch_format
feature to save bandwidth and optimize delivery time by automatically delivering images as WebP to Chrome browsers or JPEG-XR to Internet Explorer browsers. Simply set the value to auto
and the best format will be delivered to the supported browser. If a browser does not support either of these formats then the image is delivered in the format specified by the file extension.
For example, the uploaded jpg image named sample
scaled down to a width of 500 pixels and delivered as WebP to Chrome browsers (22.4 KB), JPEG-XR to Internet Explorer browsers (48 KB), or as a regular JPEG (57.5 KB) to browsers that support neither format:
cl_image_tag("sample.jpg", :width=>500, :fetch_format=>:auto)
cl_image_tag("sample.jpg", array("width"=>500, "fetch_format"=>"auto"))
CloudinaryImage("sample.jpg").image(width=500, fetch_format="auto")
cloudinary.image("sample.jpg", {width: 500, fetch_format: "auto"})
cloudinary.url().transformation(new Transformation().width(500).fetchFormat("auto")).imageTag("sample.jpg")
$.cloudinary.image("sample.jpg", {width: 500, fetch_format: "auto"})
cloudinary.Api.UrlImgUp.Transform(new Transformation().Width(500).FetchFormat("auto")).BuildImageTag("sample.jpg")
Notes:
- When automatic format (
f_auto
) is used together with automatic quality (q_auto
), the PNG format may be selected when the automatic quality algorithm decides that it better fits the specific image. This allows delivering better looking and economical image files. - When
f_auto
is used together withq_auto
for JPEG images and the automatic quality algorithm decides that no chroma subsampling should be performed, the JPEG format is selected instead of WebP. This behavior is needed because the lossy WebP format always performs chroma subsampling, which might result in a lower visual quality for some images. - Setting the
any_format
flag together with automatic quality (q_auto,fl_any_format
) but without settingf_auto
, will also allow switching to PNG8 encoding if the quality algorithm decides that it's more efficient. - To ensure that a PNG will always be delivered for images that include a transparent element, add the
preserve_transparency
flag together withf_auto
.
Adjusting image quality
Control the visual quality and compression level of JPEG, JPEG 2000, JPEG XR, WebP and GIF images with the quality
parameter (q
in URLs). This parameter represents the compression level to apply to an image as a value between 1 (smallest file size possible) and 100 (best visual quality). Reducing the quality is a tradeoff between visual quality and file size: the lower the quality value, the more the file is compressed to a smaller file size, the more data is lost in the process, and the result is a loss of visual quality. The loss of visual quality is barely noticeable to the human eye at the higher quality levels, and final visual quality also depends on other factors such as the size of the image and the resolution of the user's monitor or mobile screen.
For example, reducing the quality of the uploaded JPEG image named sample
to 60 results in a file size of 73 KB compared to the original file size of 245 KB with a barely noticeable reduction in visual quality:
cl_image_tag("sample.jpg", :quality=>60)
cl_image_tag("sample.jpg", array("quality"=>60))
CloudinaryImage("sample.jpg").image(quality=60)
cloudinary.image("sample.jpg", {quality: 60})
cloudinary.url().transformation(new Transformation().quality(60)).imageTag("sample.jpg")
$.cloudinary.image("sample.jpg", {quality: 60})
cloudinary.Api.UrlImgUp.Transform(new Transformation().Quality(60)).BuildImageTag("sample.jpg")
The quality parameter is also automatically applied when delivering images with any other transformation applied. That is, unless the original uploaded image is requested, then a default quality* value of 80 is also automatically applied to the transformed image.
* The default values were updated in June 2016. Cloudinary customers that opened an account before that date will initially have the following default values for each format if the quality parameter is not specified: JPEG: 90, WebP: 75, JPEG XR and JPEG 2000: 80
The default quality setting for your Cloudinary account can be customized via the Settings page in the Management Console. We recommend setting the default value to one of the automatic quality values.
Notes:
- Images in the WebP format are lossless when specifying a quality of 100, and lossy when specifying a quality less than 100. See the How to support WebP images, save bandwidth and improve user experience article for more information on the WebP format.
- Images in the WebP format are lossless if the quality isn't specified and the original image's format is lossless (e.g., PNG).
- Animated GIFs ignore the quality setting unless the
lossy
flag is added. See the Lossy compression for optimizing animated GIFs article for more information. - The JPEGmini add-on automatically applies the best compression possible to JPEG images while maintaining a high visual quality.
Automatic quality and encoding settings
Cloudinary's intelligent quality and encoding algorithm analyzes an image to find the best quality compression level and optimal encoding settings based on the image content and the viewing browser, in order to produce an image with good visual quality while minimizing the file size. Cloudinary automates the file size versus quality trade-off decision, on the fly, by using perceptual metrics and heuristics that tune the quality settings based on the specific image content and format. Analyzing every image individually to find the optimal compression level and image encoding settings allows for precise adjustment of the compression level complemented by fine tuning of the encoding settings, and can significantly reduce the file size without any degradation noticeable to the human eye.
The quality
transformation parameter can be set to auto
(q_auto
in URLs) in order to perform automatic quality selection and image encoding adjustments. Further control of the automatic quality selection is supported as follows:
q_auto
- The optimal balance between file size and visual quality. By default, this is the same asq_auto:good
, while it can automatically switch to the more aggressiveq_auto:eco
mode (see the note on Save-data support below).q_auto:best
- Less aggressive algorithm. Generates bigger files with potentially better visual quality. Example of a target audience: photography sites that display images with a high visual quality.q_auto:good
- Ensuring a relatively small file size with good visual quality.q_auto:eco
- More aggressive algorithm, which results in smaller files of slightly lower visual quality. Example of a target audience: popular sites and social networks with a huge amount of traffic.q_auto:low
- Most aggressive algorithm, which results in the smallest files of low visual quality. Example of a target audience: sites using thumbnail images that link to higher quality images.
Examples of the resulting file size when encoding a photograph, using various regular and automatic quality parameter values:
cl_image_tag("woman.jpg", :quality=>"auto")
cl_image_tag("woman.jpg", array("quality"=>"auto"))
CloudinaryImage("woman.jpg").image(quality="auto")
cloudinary.image("woman.jpg", {quality: "auto"})
cloudinary.url().transformation(new Transformation().quality("auto")).imageTag("woman.jpg")
$.cloudinary.image("woman.jpg", {quality: "auto"})
cloudinary.Api.UrlImgUp.Transform(new Transformation().Quality("auto")).BuildImageTag("woman.jpg")
Examples of the resulting file size when encoding a drawing, using regular and automatic quality values:
cl_image_tag("robot.jpg", :quality=>"auto")
cl_image_tag("robot.jpg", array("quality"=>"auto"))
CloudinaryImage("robot.jpg").image(quality="auto")
cloudinary.image("robot.jpg", {quality: "auto"})
cloudinary.url().transformation(new Transformation().quality("auto")).imageTag("robot.jpg")
$.cloudinary.image("robot.jpg", {quality: "auto"})
cloudinary.Api.UrlImgUp.Transform(new Transformation().Quality("auto")).BuildImageTag("robot.jpg")
Notes:
q_auto
cannot be used within named transformations, howeverq_auto:[Mode]
(e.g.,q_auto:good
) is supported within named transformations.- Save-Data support is a feature included in the Client-Hints standard, which is already supported by Chrome and Opera browsers. The browsers send a special request header named 'Save-Data' if the user has enabled data saving mode. When
q_auto
is specified and the 'Save-Data: on' header reaches the CDN layer of Cloudinary, image compression and encoding will automatically switch to theeco
mode (q_auto:eco
) instead of the defaultgood
quality mode (q_auto:good
). - Override automatic quality: you can override the automatic quality algorithm and set a fixed quality value for a specific image in the media library.
Toggling chroma subsampling
Chroma subsampling is a method of encoding images by implementing less resolution for chroma information (colors) than for luma information (luminance), taking advantage of the human visual system's lower acuity for color differences than for luminance. To override the default behavior of whether to perform chroma subsampling, a separate value can be added to the quality parameter as follows:
444
can be added to prevent subsampling. For example:q_80:444
420
can be added to force subsampling. For example:q_95:420
.
Modify image shape and style
Cloudinary supports various transformations for modifying the shape and style of images. This section contains information on the following topics:
- Round corners and create circular images.
- Rotate an image.
- Control the image opacity.
- Add borders to images.
- Set the background color.
Rounding corners and creating circular images
Many website designs need images with rounded corners, while some websites require images with a complete circular or oval (ellipse) crop. Twitter, for example, uses rounded corners for its users' profile pictures.
Programmatically, rounded corners can be achieved using the original rectangular images combined with modern CSS properties or image masking overlays. However, it is sometimes useful to generate images with rounded corners in the first place. This is particularly helpful when you want to embed images inside an email (most mail clients can't add CSS based rounded corners), a PDF or a mobile application. Having images with rounded corners is also great if you want to simplify your CSS and markup or when you need to support older browsers.
Transforming an image to a rounded version is done using the radius
parameter (r
in URLs) set to the number of pixels the radius of all four corners should be.
The following example transforms an uploaded JPEG to a 150x100 PNG with rounded corners of 20 pixels. Note that the conversion to PNG is needed for supporting a transparent background (the PNG format produces larger files than the JPEG format: see the article on PNG optimization - saving bandwidth on transparent PNGs with dynamic underlay for more information).
cl_image_tag("sample.png", :width=>150, :height=>100, :radius=>20, :crop=>"fill")
cl_image_tag("sample.png", array("width"=>150, "height"=>100, "radius"=>20, "crop"=>"fill"))
CloudinaryImage("sample.png").image(width=150, height=100, radius=20, crop="fill")
cloudinary.image("sample.png", {width: 150, height: 100, radius: 20, crop: "fill"})
cloudinary.url().transformation(new Transformation().width(150).height(100).radius(20).crop("fill")).imageTag("sample.png")
$.cloudinary.image("sample.png", {width: 150, height: 100, radius: 20, crop: "fill"})
cloudinary.Api.UrlImgUp.Transform(new Transformation().Width(150).Height(100).Radius(20).Crop("fill")).BuildImageTag("sample.png")
Cloudinary supports cropping images to the shape of an ellipse or a circle (if the requested width and height are the same). Simply pass max
as the value of the radius
parameter.
The following example transforms an uploaded JPEG to a 150x100 PNG with maximum radius cropping, which generates the ellipse shape with a transparent background:
cl_image_tag("sample.png", :width=>250, :height=>150, :radius=>"max", :crop=>"fill")
cl_image_tag("sample.png", array("width"=>250, "height"=>150, "radius"=>"max", "crop"=>"fill"))
CloudinaryImage("sample.png").image(width=250, height=150, radius="max", crop="fill")
cloudinary.image("sample.png", {width: 250, height: 150, radius: "max", crop: "fill"})
cloudinary.url().transformation(new Transformation().width(250).height(150).radius("max").crop("fill")).imageTag("sample.png")
$.cloudinary.image("sample.png", {width: 250, height: 150, radius: "max", crop: "fill"})
cloudinary.Api.UrlImgUp.Transform(new Transformation().Width(250).Height(150).Radius("max").Crop("fill")).BuildImageTag("sample.png")
As the following example shows, displaying pictures of your web site's users as nice looking circles is very easy to achieve with Cloudinary using face
gravity with max
radius:
cl_image_tag("face_left.png", :width=>200, :height=>200, :gravity=>"face", :radius=>"max", :crop=>"thumb")
cl_image_tag("face_left.png", array("width"=>200, "height"=>200, "gravity"=>"face", "radius"=>"max", "crop"=>"thumb"))
CloudinaryImage("face_left.png").image(width=200, height=200, gravity="face", radius="max", crop="thumb")
cloudinary.image("face_left.png", {width: 200, height: 200, gravity: "face", radius: "max", crop: "thumb"})
cloudinary.url().transformation(new Transformation().width(200).height(200).gravity("face").radius("max").crop("thumb")).imageTag("face_left.png")
$.cloudinary.image("face_left.png", {width: 200, height: 200, gravity: "face", radius: "max", crop: "thumb"})
cloudinary.Api.UrlImgUp.Transform(new Transformation().Width(200).Height(200).Gravity("face").Radius("max").Crop("thumb")).BuildImageTag("face_left.png")
Displaying overlay pictures of your web site's users as nice looking circles on other images is made possible with the layer_apply
flag that tells Cloudinary to apply the transformations to the overlay image and not the base image:
cl_image_tag("flower.jpg", :transformation=>[ {:width=>200, :height=>200, :gravity=>"face", :radius=>"max", :overlay=>"face_left", :crop=>"thumb"}, {:flags=>"layer_apply", :gravity=>"north_east"} ])
cl_image_tag("flower.jpg", array("transformation"=>array( array("width"=>200, "height"=>200, "gravity"=>"face", "radius"=>"max", "overlay"=>"face_left", "crop"=>"thumb"), array("flags"=>"layer_apply", "gravity"=>"north_east") )))
CloudinaryImage("flower.jpg").image(transformation=[ {"width": 200, "height": 200, "gravity": "face", "radius": "max", "overlay": "face_left", "crop": "thumb"}, {"flags": "layer_apply", "gravity": "north_east"} ])
cloudinary.image("flower.jpg", {transformation: [ {width: 200, height: 200, gravity: "face", radius: "max", overlay: "face_left", crop: "thumb"}, {flags: "layer_apply", gravity: "north_east"} ]})
cloudinary.url().transformation(new Transformation() .width(200).height(200).gravity("face").radius("max").overlay("face_left").crop("thumb").chain() .flags("layer_apply").gravity("north_east")).imageTag("flower.jpg")
$.cloudinary.image("flower.jpg", {transformation: [ {width: 200, height: 200, gravity: "face", radius: "max", overlay: "face_left", crop: "thumb"}, {flags: "layer_apply", gravity: "north_east"} ]})
cloudinary.Api.UrlImgUp.Transform(new Transformation() .Width(200).Height(200).Gravity("face").Radius("max").Overlay("face_left").Crop("thumb").Chain() .Flags("layer_apply").Gravity("north_east")).BuildImageTag("flower.jpg")
Rotating images
Rotate an image by any arbitrary angle in degrees with the angle
parameter (a
in URLs). A positive integer value rotates the image clockwise, and a negative integer value rotates the image counterclockwise. If the angle is not a multiple of 90 then a rectangular bounding box is added containing the rotated image and empty space.
Other possible rotation values instead of an integer value include:
auto_right
- Rotate the image 90 degrees clockwise only if the requested aspect ratio does not match the image's aspect ratio.auto_left
- Rotate the image 90 degrees counterclockwise only if the requested aspect ratio does not match the image's aspect ratio.vflip
- Vertical mirror flip of the image.hflip
- Horizontal mirror flip of the image.ignore
- By default, the image is automatically rotated according to the EXIF data stored by the camera when the image was taken. Set the rotation to 'ignore' if you do not want the image to be automatically rotated.
Note that you can apply multiple values when each value is separated with a dot (.
). For example to horizontally flip the image and rotate it by 45 degrees: angle: hflip.45
Examples with the uploaded image named sample
(all images are also scaled down to a width of 100 pixels):
- Rotate the image by 90 degrees:
Ruby:cl_image_tag("sample.jpg", :transformation=>[ {:width=>100}, {:angle=>90} ])
PHP:cl_image_tag("sample.jpg", array("transformation"=>array( array("width"=>100), array("angle"=>90) )))
Python:CloudinaryImage("sample.jpg").image(transformation=[ {"width": 100}, {"angle": 90} ])
Node.js:cloudinary.image("sample.jpg", {transformation: [ {width: 100}, {angle: 90} ]})
Java:cloudinary.url().transformation(new Transformation() .width(100).chain() .angle(90)).imageTag("sample.jpg")
jQuery:$.cloudinary.image("sample.jpg", {transformation: [ {width: 100}, {angle: 90} ]})
.Net:cloudinary.Api.UrlImgUp.Transform(new Transformation() .Width(100).Chain() .Angle(90)).BuildImageTag("sample.jpg")
- Rotate the image by -20 degrees (automatically adds a bounding box):
Ruby:cl_image_tag("sample.jpg", :transformation=>[ {:width=>100}, {:angle=>-20} ])
PHP:cl_image_tag("sample.jpg", array("transformation"=>array( array("width"=>100), array("angle"=>-20) )))
Python:CloudinaryImage("sample.jpg").image(transformation=[ {"width": 100}, {"angle": -20} ])
Node.js:cloudinary.image("sample.jpg", {transformation: [ {width: 100}, {angle: -20} ]})
Java:cloudinary.url().transformation(new Transformation() .width(100).chain() .angle(-20)).imageTag("sample.jpg")
jQuery:$.cloudinary.image("sample.jpg", {transformation: [ {width: 100}, {angle: -20} ]})
.Net:cloudinary.Api.UrlImgUp.Transform(new Transformation() .Width(100).Chain() .Angle(-20)).BuildImageTag("sample.jpg")
- Vertically mirror flip the image and rotate by 70 degrees (automatically adds a bounding box):
Ruby:cl_image_tag("sample.jpg", :transformation=>[ {:width=>100}, {:angle=>["vflip", 45]} ])
PHP:cl_image_tag("sample.jpg", array("transformation"=>array( array("width"=>100), array("angle"=>array("vflip", 45)) )))
Python:CloudinaryImage("sample.jpg").image(transformation=[ {"width": 100}, {"angle": ["vflip", 45]} ])
Node.js:cloudinary.image("sample.jpg", {transformation: [ {width: 100}, {angle: ["vflip", 45]} ]})
Java:cloudinary.url().transformation(new Transformation() .width(100).chain() .angle("vflip", "45")).imageTag("sample.jpg")
jQuery:$.cloudinary.image("sample.jpg", {transformation: [ {width: 100}, {angle: ["vflip", 45]} ]})
.Net:cloudinary.Api.UrlImgUp.Transform(new Transformation() .Width(100).Chain() .Angle("vflip", "45")).BuildImageTag("sample.jpg")
- Crop the image to a 200x200 circle, then rotate the image by 30 degrees (automatically adds a bounding box) and finally trim the extra whitespace added:
Ruby:
cl_image_tag("sample.jpg", :transformation=>[ {:width=>200, :height=>200, :radius=>"max", :crop=>"fill"}, {:angle=>30}, {:effect=>"trim"} ])
PHP:cl_image_tag("sample.jpg", array("transformation"=>array( array("width"=>200, "height"=>200, "radius"=>"max", "crop"=>"fill"), array("angle"=>30), array("effect"=>"trim") )))
Python:CloudinaryImage("sample.jpg").image(transformation=[ {"width": 200, "height": 200, "radius": "max", "crop": "fill"}, {"angle": 30}, {"effect": "trim"} ])
Node.js:cloudinary.image("sample.jpg", {transformation: [ {width: 200, height: 200, radius: "max", crop: "fill"}, {angle: 30}, {effect: "trim"} ]})
Java:cloudinary.url().transformation(new Transformation() .width(200).height(200).radius("max").crop("fill").chain() .angle(30).chain() .effect("trim")).imageTag("sample.jpg")
jQuery:$.cloudinary.image("sample.jpg", {transformation: [ {width: 200, height: 200, radius: "max", crop: "fill"}, {angle: 30}, {effect: "trim"} ]})
.Net:cloudinary.Api.UrlImgUp.Transform(new Transformation() .Width(200).Height(200).Radius("max").Crop("fill").Chain() .Angle(30).Chain() .Effect("trim")).BuildImageTag("sample.jpg")
Controlling image opacity
Adjust the opacity of an image with the opacity
parameter (o
in URLs). The parameter accepts a value between 0-100 representing the percentage of transparency, where 100 means completely opaque and 0 is completely transparent.
Note: If the image format does not support transparency, the background color is used instead as a base (white by default). The color can be changed with the background parameter.
For example, the uploaded image named sample
delivered with 30% opacity:
cl_image_tag("sample.jpg", :opacity=>30)
cl_image_tag("sample.jpg", array("opacity"=>30))
CloudinaryImage("sample.jpg").image(opacity=30)
cloudinary.image("sample.jpg", {opacity: 30})
cloudinary.url().transformation(new Transformation().opacity(30)).imageTag("sample.jpg")
$.cloudinary.image("sample.jpg", {opacity: 30})
cloudinary.Api.UrlImgUp.Transform(new Transformation().Opacity(30)).BuildImageTag("sample.jpg")
Controlling the opacity is especially useful when placing other images as overlays. For example, an overlay of cloudinary_icon
added with 60% opacity:
cl_image_tag("sample.jpg", :overlay=>"cloudinary_icon", :width=>300, :gravity=>"north_east", :opacity=>60)
cl_image_tag("sample.jpg", array("overlay"=>"cloudinary_icon", "width"=>300, "gravity"=>"north_east", "opacity"=>60))
CloudinaryImage("sample.jpg").image(overlay="cloudinary_icon", width=300, gravity="north_east", opacity=60)
cloudinary.image("sample.jpg", {overlay: "cloudinary_icon", width: 300, gravity: "north_east", opacity: 60})
cloudinary.url().transformation(new Transformation().overlay("cloudinary_icon").width(300).gravity("north_east").opacity(60)).imageTag("sample.jpg")
$.cloudinary.image("sample.jpg", {overlay: "cloudinary_icon", width: 300, gravity: "north_east", opacity: 60})
cloudinary.Api.UrlImgUp.Transform(new Transformation().Overlay("cloudinary_icon").Width(300).Gravity("north_east").Opacity(60)).BuildImageTag("sample.jpg")
Adding image borders
Add a solid border around the image with the border
parameter (bo
in URLs). The parameter accepts a value with a CSS-like format: width_style_color
(e.g., 3px_solid_black
).
An opaque color can be set as an RGB hex triplet (e.g., rgb:3e2222
), a 3-digit RGB hex (e.g., rgb:777
) or a named color (e.g., green
).
You can also use a 4-digit or 8-digit RGBA hex quadruplet for the color, where the 4th hex value represents the alpha (opacity) value (e.g. co_rgb:3e222240
results in 25% opacity).
Additionally, Cloudinary's client libraries also support a #
shortcut for RGB (e.g., setting color to #3e2222
which is then translated to rgb:3e2222
), and when using Cloudinary's client libraries, you can optionally set the border values programmatically instead of as a single string (e.g., :border => { :width => 4, :color => 'black' }).
Note: currently only the 'solid' border style is supported.
For example, the uploaded jpg image named sample
delivered with a 5 pixel red border:
cl_image_tag("sample.jpg", :border=>"5px_solid_red")
cl_image_tag("sample.jpg", array("border"=>"5px_solid_red"))
CloudinaryImage("sample.jpg").image(border="5px_solid_red")
cloudinary.image("sample.jpg", {border: "5px_solid_red"})
cloudinary.url().transformation(new Transformation().border("5px_solid_red")).imageTag("sample.jpg")
$.cloudinary.image("sample.jpg", {border: "5px_solid_red"})
cloudinary.Api.UrlImgUp.Transform(new Transformation().Border("5px_solid_red")).BuildImageTag("sample.jpg")
Borders are also useful for adding to overlays to clearly define the overlaying image, and also automatically adapt to any rounded corner transformations. For example, an image of lady
cropped with face detection and given rounded corners with a 10 pixel grey border, and an overlay of the image of young_couple
resized to a 150x150 circular thumbnail with face detection and a black 3 pixel border, added to the northeast corner:
cl_image_tag("lady.jpg", :transformation=>[ {:gravity=>"face", :radius=>75, :border=>"10px_solid_grey", :crop=>"crop"}, {:overlay=>"young_couple", :width=>150, :height=>150, :radius=>"max", :gravity=>"faces", :border=>"3px_solid_black", :crop=>"thumb"}, {:flags=>"layer_apply", :gravity=>"north_east"} ])
cl_image_tag("lady.jpg", array("transformation"=>array( array("gravity"=>"face", "radius"=>75, "border"=>"10px_solid_grey", "crop"=>"crop"), array("overlay"=>"young_couple", "width"=>150, "height"=>150, "radius"=>"max", "gravity"=>"faces", "border"=>"3px_solid_black", "crop"=>"thumb"), array("flags"=>"layer_apply", "gravity"=>"north_east") )))
CloudinaryImage("lady.jpg").image(transformation=[ {"gravity": "face", "radius": 75, "border": "10px_solid_grey", "crop": "crop"}, {"overlay": "young_couple", "width": 150, "height": 150, "radius": "max", "gravity": "faces", "border": "3px_solid_black", "crop": "thumb"}, {"flags": "layer_apply", "gravity": "north_east"} ])
cloudinary.image("lady.jpg", {transformation: [ {gravity: "face", radius: 75, border: "10px_solid_grey", crop: "crop"}, {overlay: "young_couple", width: 150, height: 150, radius: "max", gravity: "faces", border: "3px_solid_black", crop: "thumb"}, {flags: "layer_apply", gravity: "north_east"} ]})
cloudinary.url().transformation(new Transformation() .gravity("face").radius(75).border("10px_solid_grey").crop("crop").chain() .overlay("young_couple").width(150).height(150).radius("max").gravity("faces").border("3px_solid_black").crop("thumb").chain() .flags("layer_apply").gravity("north_east")).imageTag("lady.jpg")
$.cloudinary.image("lady.jpg", {transformation: [ {gravity: "face", radius: 75, border: "10px_solid_grey", crop: "crop"}, {overlay: "young_couple", width: 150, height: 150, radius: "max", gravity: "faces", border: "3px_solid_black", crop: "thumb"}, {flags: "layer_apply", gravity: "north_east"} ]})
cloudinary.Api.UrlImgUp.Transform(new Transformation() .Gravity("face").Radius(75).Border("10px_solid_grey").Crop("crop").Chain() .Overlay("young_couple").Width(150).Height(150).Radius("max").Gravity("faces").Border("3px_solid_black").Crop("thumb").Chain() .Flags("layer_apply").Gravity("north_east")).BuildImageTag("lady.jpg")
Setting background color
Use the background
parameter (b
in URLs) to set the background color of the image. The image background is visible when padding is added with the “pad” crop mode, when rounding corners, when adding overlays, and with semi-transparent PNGs and GIFs.
An opaque color can be set as an RGB hex triplet (e.g. b_rgb:3e2222
), a 3-digit RGB hex (e.g. b_rgb:777
) or a named color (e.g. b_green
). Cloudinary's client libraries also support a #
shortcut for RGB (e.g. setting background
to #3e2222
which is then translated to rgb:3e2222
).
For example, the uploaded image named sample
padded to a width and height of 300 pixels with a green background:
cl_image_tag("sample.jpg", :width=>300, :height=>300, :background=>"green", :crop=>"pad")
cl_image_tag("sample.jpg", array("width"=>300, "height"=>300, "background"=>"green", "crop"=>"pad"))
CloudinaryImage("sample.jpg").image(width=300, height=300, background="green", crop="pad")
cloudinary.image("sample.jpg", {width: 300, height: 300, background: "green", crop: "pad"})
cloudinary.url().transformation(new Transformation().width(300).height(300).background("green").crop("pad")).imageTag("sample.jpg")
$.cloudinary.image("sample.jpg", {width: 300, height: 300, background: "green", crop: "pad"})
cloudinary.Api.UrlImgUp.Transform(new Transformation().Width(300).Height(300).Background("green").Crop("pad")).BuildImageTag("sample.jpg")
You can also use a 4-digit or 8-digit RGBA hex quadruplet for the background color, where the 4th hex value represents the alpha (opacity) value (e.g. co_rgb:3e222240
results in 25% opacity).
Applying image effects and filters
Apply a filter or an effect on an image with the effect
parameter (e
in URLs). The value of the parameter includes the name of the effect and sometimes an additional value that controls the behavior of the specific effect. Cloudinary supports a large number of effects that can be applied to change the visual appearance of delivered images. You can also apply multiple effects to an image by applying each effect as a separate chained transformation.
There are a large number of effects and filters available, which can be roughly divided into the following type of effects:
- Color balance and level effects
- Tint effects
- Blurring, pixelating and sharpening effects
- Overlay blending effects
- Image shape changes and distortion effects
- Image improvement effects
- Artistic filter effects
- Miscellaneous image effects
For a full list of all the supported effects, see the Image transformations reference table. For more information on using effects see the following articles:
- Cloud-based API for applying effects on images
- Automatic cloud-based image improvements and effects
- Automatic image sharpening and blurring in the cloud
Tip: In addition to the various image effects and filters described here, you can also apply a 3D LUT file as an image overlay to achieve desired effects.
Color balance and level effects
Effects: hue
, red
, blue
, green
, negate
, brightness
, brightness_hsb
, colorize
, grayscale
, blackwhite
, sepia
, saturation
These effects are useful for changing the intensities of colors in an image, correcting color imbalance, applying colorization filters, and removing colors.
Examples:
- Converting the
sample
image to grayscale:Ruby:cl_image_tag("sample.jpg", :effect=>"grayscale")
PHP:cl_image_tag("sample.jpg", array("effect"=>"grayscale"))
Python:CloudinaryImage("sample.jpg").image(effect="grayscale")
Node.js:cloudinary.image("sample.jpg", {effect: "grayscale"})
Java:cloudinary.url().transformation(new Transformation().effect("grayscale")).imageTag("sample.jpg")
jQuery:$.cloudinary.image("sample.jpg", {effect: "grayscale"})
.Net:cloudinary.Api.UrlImgUp.Transform(new Transformation().Effect("grayscale")).BuildImageTag("sample.jpg")
- Increasing saturation of the
sample
image to 50:Ruby:cl_image_tag("sample.jpg", :effect=>"saturation:50")
PHP:cl_image_tag("sample.jpg", array("effect"=>"saturation:50"))
Python:CloudinaryImage("sample.jpg").image(effect="saturation:50")
Node.js:cloudinary.image("sample.jpg", {effect: "saturation:50"})
Java:cloudinary.url().transformation(new Transformation().effect("saturation:50")).imageTag("sample.jpg")
jQuery:$.cloudinary.image("sample.jpg", {effect: "saturation:50"})
.Net:cloudinary.Api.UrlImgUp.Transform(new Transformation().Effect("saturation:50")).BuildImageTag("sample.jpg")
Tint effects
The tint:<options>
effect enables you to blend your images with one or more colors and specify the blend strength. Advanced users can also equalize the image for increased contrast and specify the positioning of the gradient blend for each color.
By default,
e_tint
applies a red color at 60% blend strength.Specify the colors and blend strength amount in the format:
e_tint:[amount]:[color1]:[color2]:...:[color10].
amount
is a value from 0-100, where 0 keeps the original color and 100 blends the specified colors completely.The
color
can be specified as an RGB hex triplet (e.g. rgb:3e2222), a 3-digit RGB hex (e.g. rgb:777) or a named color (e.g. green).For example:
Ruby:cl_image_tag("greece_landscape.jpg", :effect=>"tint:100:red:blue:yellow")
PHP:cl_image_tag("greece_landscape.jpg", array("effect"=>"tint:100:red:blue:yellow"))
Python:CloudinaryImage("greece_landscape.jpg").image(effect="tint:100:red:blue:yellow")
Node.js:cloudinary.image("greece_landscape.jpg", {effect: "tint:100:red:blue:yellow"})
Java:cloudinary.url().transformation(new Transformation().effect("tint:100:red:blue:yellow")).imageTag("greece_landscape.jpg")
jQuery:$.cloudinary.image("greece_landscape.jpg", {effect: "tint:100:red:blue:yellow"})
.Net:cloudinary.Api.UrlImgUp.Transform(new Transformation().Effect("tint:100:red:blue:yellow")).BuildImageTag("greece_landscape.jpg")
To equalize the colors in your image before tinting, set
equalize
to true (false by default). For example:URL:Ruby:cl_image_tag("greece_landscape.jpg", :effect=>"tint:equalize:80:red:blue:yellow")
PHP:cl_image_tag("greece_landscape.jpg", array("effect"=>"tint:equalize:80:red:blue:yellow"))
Python:CloudinaryImage("greece_landscape.jpg").image(effect="tint:equalize:80:red:blue:yellow")
Node.js:cloudinary.image("greece_landscape.jpg", {effect: "tint:equalize:80:red:blue:yellow"})
Java:cloudinary.url().transformation(new Transformation().effect("tint:equalize:80:red:blue:yellow")).imageTag("greece_landscape.jpg")
jQuery:$.cloudinary.image("greece_landscape.jpg", {effect: "tint:equalize:80:red:blue:yellow"})
.Net:cloudinary.Api.UrlImgUp.Transform(new Transformation().Effect("tint:equalize:80:red:blue:yellow")).BuildImageTag("greece_landscape.jpg")
By default, the specified colors are distributed evenly. To adjust the positioning of the gradient blend, specify a
position
value between 0p-100p. If specifying positioning, you must specify a position value for all colors. For example:Ruby:cl_image_tag("greece_landscape.jpg", :effect=>"tint:equalize:80:red:50p:blue:60p:yellow:40p")
PHP:cl_image_tag("greece_landscape.jpg", array("effect"=>"tint:equalize:80:red:50p:blue:60p:yellow:40p"))
Python:CloudinaryImage("greece_landscape.jpg").image(effect="tint:equalize:80:red:50p:blue:60p:yellow:40p")
Node.js:cloudinary.image("greece_landscape.jpg", {effect: "tint:equalize:80:red:50p:blue:60p:yellow:40p"})
Java:cloudinary.url().transformation(new Transformation().effect("tint:equalize:80:red:50p:blue:60p:yellow:40p")).imageTag("greece_landscape.jpg")
jQuery:$.cloudinary.image("greece_landscape.jpg", {effect: "tint:equalize:80:red:50p:blue:60p:yellow:40p"})
.Net:cloudinary.Api.UrlImgUp.Transform(new Transformation().Effect("tint:equalize:80:red:50p:blue:60p:yellow:40p")).BuildImageTag("greece_landscape.jpg")
1Equalizing colors redistributes the pixels in your image so that they are equally balanced across the entire range of brightness values, which increases the overall contrast in the image. The lightest area is remapped to pure white, and the darkest area is remapped to pure black.
Blurring, pixelating and sharpening effects
Effects: blur
, sharpen
, unsharp_mask
, blur_region
, blur_faces
, pixelate
, pixelate_faces
, ordered_dither
, noise
, vignette
, gradient_fade
, tilt_shift
These effects are used to either visually distort or visually enhance an image.
Examples:
- To apply a strong blurring filter (300) to the
sample
image:Ruby:cl_image_tag("sample.jpg", :effect=>"blur:300")
PHP:cl_image_tag("sample.jpg", array("effect"=>"blur:300"))
Python:CloudinaryImage("sample.jpg").image(effect="blur:300")
Node.js:cloudinary.image("sample.jpg", {effect: "blur:300"})
Java:cloudinary.url().transformation(new Transformation().effect("blur:300")).imageTag("sample.jpg")
jQuery:$.cloudinary.image("sample.jpg", {effect: "blur:300"})
.Net:cloudinary.Api.UrlImgUp.Transform(new Transformation().Effect("blur:300")).BuildImageTag("sample.jpg")
- To apply a sharpen filter to the
sample
image:Ruby:cl_image_tag("sample.jpg", :effect=>"sharpen")
PHP:cl_image_tag("sample.jpg", array("effect"=>"sharpen"))
Python:CloudinaryImage("sample.jpg").image(effect="sharpen")
Node.js:cloudinary.image("sample.jpg", {effect: "sharpen"})
Java:cloudinary.url().transformation(new Transformation().effect("sharpen")).imageTag("sample.jpg")
jQuery:$.cloudinary.image("sample.jpg", {effect: "sharpen"})
.Net:cloudinary.Api.UrlImgUp.Transform(new Transformation().Effect("sharpen")).BuildImageTag("sample.jpg")
Overlay blending effects
Effects: screen
, multiply
, overlay
, mask
These effects are used for blending an overlay with an image.
For example, to make each pixel of the sample
image brighter according to the pixel value of the overlaid cloudinary_icon
image:
cl_image_tag("sample.jpg", :effect=>"screen", :overlay=>"cloudinary_icon")
cl_image_tag("sample.jpg", array("effect"=>"screen", "overlay"=>"cloudinary_icon"))
CloudinaryImage("sample.jpg").image(effect="screen", overlay="cloudinary_icon")
cloudinary.image("sample.jpg", {effect: "screen", overlay: "cloudinary_icon"})
cloudinary.url().transformation(new Transformation().effect("screen").overlay("cloudinary_icon")).imageTag("sample.jpg")
$.cloudinary.image("sample.jpg", {effect: "screen", overlay: "cloudinary_icon"})
cloudinary.Api.UrlImgUp.Transform(new Transformation().Effect("screen").Overlay("cloudinary_icon")).BuildImageTag("sample.jpg")
Image shape changes and distortion effects
Effects: shadow
, make_transparent
, trim
, distort
, shear
, displace
These effects are used to morph an image's visual dimensions.
Examples:
- To distort the
sample
image to a new shape (see the article on How to dynamically distort images to fit your graphic design for more info:URL:Ruby:cl_image_tag("sample.jpg", :width=>300, :effect=>"distort:40:25:280:60:260:155:35:165")
PHP:cl_image_tag("sample.jpg", array("width"=>300, "effect"=>"distort:40:25:280:60:260:155:35:165"))
Python:CloudinaryImage("sample.jpg").image(width=300, effect="distort:40:25:280:60:260:155:35:165")
Node.js:cloudinary.image("sample.jpg", {width: 300, effect: "distort:40:25:280:60:260:155:35:165"})
Java:cloudinary.url().transformation(new Transformation().width(300).effect("distort:40:25:280:60:260:155:35:165")).imageTag("sample.jpg")
jQuery:$.cloudinary.image("sample.jpg", {width: 300, effect: "distort:40:25:280:60:260:155:35:165"})
.Net:cloudinary.Api.UrlImgUp.Transform(new Transformation().Width(300).Effect("distort:40:25:280:60:260:155:35:165")).BuildImageTag("sample.jpg")
- To add a custom green shadow to the
sample
image:Ruby:cl_image_tag("sample.jpg", :color=>"#009900", :effect=>"shadow:50", :x=>10, :y=>10)
PHP:cl_image_tag("sample.jpg", array("color"=>"#009900", "effect"=>"shadow:50", "x"=>10, "y"=>10))
Python:CloudinaryImage("sample.jpg").image(color="#009900", effect="shadow:50", x=10, y=10)
Node.js:cloudinary.image("sample.jpg", {color: "#009900", effect: "shadow:50", x: 10, y: 10})
Java:cloudinary.url().transformation(new Transformation().color("#009900").effect("shadow:50").x(10).y(10)).imageTag("sample.jpg")
jQuery:$.cloudinary.image("sample.jpg", {color: "#009900", effect: "shadow:50", x: 10, y: 10})
.Net:cloudinary.Api.UrlImgUp.Transform(new Transformation().Color("#009900").Effect("shadow:50").X(10).Y(10)).BuildImageTag("sample.jpg")
Image improvement effects
Effects: improve
, gamma
, auto_brightness
, auto_contrast
, auto_color
, fill_light
, vibrance
, contrast
, viesus_correct
These effects are used for manually adjusting the visual quality of an image, or applying automatic visual enhancements.
Examples:
- To
improve
an image by automatically adjusting image colors, contrast and lightness:Ruby:cl_image_tag("sample.jpg", :effect=>"improve")
PHP:cl_image_tag("sample.jpg", array("effect"=>"improve"))
Python:CloudinaryImage("sample.jpg").image(effect="improve")
Node.js:cloudinary.image("sample.jpg", {effect: "improve"})
Java:cloudinary.url().transformation(new Transformation().effect("improve")).imageTag("sample.jpg")
jQuery:$.cloudinary.image("sample.jpg", {effect: "improve"})
.Net:cloudinary.Api.UrlImgUp.Transform(new Transformation().Effect("improve")).BuildImageTag("sample.jpg")
- To automatically enhance an image using the Viesus automatic enhancement add-on:
Ruby:
cl_image_tag("beach.jpg", :effect=>"viesus_correct")
PHP:cl_image_tag("beach.jpg", array("effect"=>"viesus_correct"))
Python:CloudinaryImage("beach.jpg").image(effect="viesus_correct")
Node.js:cloudinary.image("beach.jpg", {effect: "viesus_correct"})
Java:cloudinary.url().transformation(new Transformation().effect("viesus_correct")).imageTag("beach.jpg")
jQuery:$.cloudinary.image("beach.jpg", {effect: "viesus_correct"})
.Net:cloudinary.Api.UrlImgUp.Transform(new Transformation().Effect("viesus_correct")).BuildImageTag("beach.jpg")
Artistic filter effects
The art:<filter>
effects brighten highlights, intensify shadows, apply sepia-like filters, add vignetting, and more.
For the list of available artistic filter values, see the art effect in the Image Transformation Reference.
Examples:
cl_image_tag("horses.jpg", :effect=>"art:incognito")
cl_image_tag("horses.jpg", array("effect"=>"art:incognito"))
CloudinaryImage("horses.jpg").image(effect="art:incognito")
cloudinary.image("horses.jpg", {effect: "art:incognito"})
cloudinary.url().transformation(new Transformation().effect("art:incognito")).imageTag("horses.jpg")
$.cloudinary.image("horses.jpg", {effect: "art:incognito"})
cloudinary.Api.UrlImgUp.Transform(new Transformation().Effect("art:incognito")).BuildImageTag("horses.jpg")
Miscellaneous image effects
Effects: oil_paint
, red_eye
, adv_redeye
This category includes other effects that don't fall under one of the other categories.
For example, to apply an oil-painting filter to the sample
image:
cl_image_tag("sample.jpg", :effect=>"oil_paint:70")
cl_image_tag("sample.jpg", array("effect"=>"oil_paint:70"))
CloudinaryImage("sample.jpg").image(effect="oil_paint:70")
cloudinary.image("sample.jpg", {effect: "oil_paint:70"})
cloudinary.url().transformation(new Transformation().effect("oil_paint:70")).imageTag("sample.jpg")
$.cloudinary.image("sample.jpg", {effect: "oil_paint:70"})
cloudinary.Api.UrlImgUp.Transform(new Transformation().Effect("oil_paint:70")).BuildImageTag("sample.jpg")
Image and text overlays
You can dynamically add overlays, underlays and text captions to specific locations within your images, while easily manipulating and transforming them to suit your needs. This section is divided into the following topics:
- Adding image overlays
- Manipulating overlays
- Placing overlays
- Applying chained transformations to overlays
- Adding image underlays
- Adding text captions
- Applying 3D LUTs to images
- Adding Multiple overlays
Adding image overlays
Add an image over the base image with the overlay
parameter (l
in URLs) and the public ID of a previously uploaded image (e.g. l_watermark
for an image with the public ID of watermark
). For example, adding an overlay of the image called cloudinary_icon
to the jpg image named sample
.
cl_image_tag("sample.jpg", :overlay=>"cloudinary_icon")
cl_image_tag("sample.jpg", array("overlay"=>"cloudinary_icon"))
CloudinaryImage("sample.jpg").image(overlay="cloudinary_icon")
cloudinary.image("sample.jpg", {overlay: "cloudinary_icon"})
cloudinary.url().transformation(new Transformation().overlay("cloudinary_icon")).imageTag("sample.jpg")
$.cloudinary.image("sample.jpg", {overlay: "cloudinary_icon"})
cloudinary.Api.UrlImgUp.Transform(new Transformation().Overlay("cloudinary_icon")).BuildImageTag("sample.jpg")
Manipulating overlays
The overlay can be resized and manipulated like any other image uploaded to Cloudinary. For example, adding an overlay of the image called cloudinary_icon
to the top right corner of the sample
image, where the overlay is also scaled down to 90% of its original width and made into a watermark by reducing the opacity to 70% and increasing the brightness to 50% using the brightness
effect:
cl_image_tag("sample.jpg", :overlay=>"cloudinary_icon", :width=>0.9, :gravity=>"north_east", :opacity=>70, :effect=>"brightness:50", :crop=>"scale")
cl_image_tag("sample.jpg", array("overlay"=>"cloudinary_icon", "width"=>0.9, "gravity"=>"north_east", "opacity"=>70, "effect"=>"brightness:50", "crop"=>"scale"))
CloudinaryImage("sample.jpg").image(overlay="cloudinary_icon", width=0.9, gravity="north_east", opacity=70, effect="brightness:50", crop="scale")
cloudinary.image("sample.jpg", {overlay: "cloudinary_icon", width: 0.9, gravity: "north_east", opacity: 70, effect: "brightness:50", crop: "scale"})
cloudinary.url().transformation(new Transformation().overlay("cloudinary_icon").width(0.9).gravity("north_east").opacity(70).effect("brightness:50").crop("scale")).imageTag("sample.jpg")
$.cloudinary.image("sample.jpg", {overlay: "cloudinary_icon", width: 0.9, gravity: "north_east", opacity: 70, effect: "brightness:50", crop: "scale"})
cloudinary.Api.UrlImgUp.Transform(new Transformation().Overlay("cloudinary_icon").Width(0.9).Gravity("north_east").Opacity(70).Effect("brightness:50").Crop("scale")).BuildImageTag("sample.jpg")
You can also add the relative
flag (fl_relative
in URLs) to specify that percentage-based width & height parameters of overlays (e.g., w_0.5) are relative to the size of the base image instead of the original size of the overlaying image itself. For example, adding an overlay of the image called cloudinary_icon
to the jpg image named sample
, where the overlay is resized to 80% of the width of the base image:
cl_image_tag("sample.jpg", :overlay=>"cloudinary_icon", :width=>0.8, :flags=>"relative")
cl_image_tag("sample.jpg", array("overlay"=>"cloudinary_icon", "width"=>0.8, "flags"=>"relative"))
CloudinaryImage("sample.jpg").image(overlay="cloudinary_icon", width=0.8, flags="relative")
cloudinary.image("sample.jpg", {overlay: "cloudinary_icon", width: 0.8, flags: "relative"})
cloudinary.url().transformation(new Transformation().overlay("cloudinary_icon").width(0.8).flags("relative")).imageTag("sample.jpg")
$.cloudinary.image("sample.jpg", {overlay: "cloudinary_icon", width: 0.8, flags: "relative"})
cloudinary.Api.UrlImgUp.Transform(new Transformation().Overlay("cloudinary_icon").Width(0.8).Flags("relative")).BuildImageTag("sample.jpg")
Placing overlays
To determine the position of an overlay, add the gravity parameter to define a location within the base image ('center' by default). For fine tuning the exact location of the overlay, you can offset the overlay from the focus of gravity by also adding the x
and y
coordinate parameters. These parameters accept either integer values representing the number of pixels to displace the overlay in the horizontal or vertical directions, or real values representing a percentage-based offset relative to the containing image (e.g., 0.2 for an offset of 20%). For example, adding an overlay of the image called cloudinary_icon
to the jpg image named sample
with gravity set to northwest but with a vertical offset of 20 pixels:
cl_image_tag("sample.jpg", :overlay=>"cloudinary_icon", :gravity=>"north_west", :y=>20)
cl_image_tag("sample.jpg", array("overlay"=>"cloudinary_icon", "gravity"=>"north_west", "y"=>20))
CloudinaryImage("sample.jpg").image(overlay="cloudinary_icon", gravity="north_west", y=20)
cloudinary.image("sample.jpg", {overlay: "cloudinary_icon", gravity: "north_west", y: 20})
cloudinary.url().transformation(new Transformation().overlay("cloudinary_icon").gravity("north_west").y(20)).imageTag("sample.jpg")
$.cloudinary.image("sample.jpg", {overlay: "cloudinary_icon", gravity: "north_west", y: 20})
cloudinary.Api.UrlImgUp.Transform(new Transformation().Overlay("cloudinary_icon").Gravity("north_west").Y(20)).BuildImageTag("sample.jpg")
The gravity parameter can also be set to one of the facial detection modes, and the detected facial coordinates become the focus when placing the overlay. If there are multiple faces in an image, setting the gravity parameter to 'faces' will result in the overlay being placed multiple times, once for each face detected. For example, adding an overlay of the golden_star
image over all faces detected in the couple
image. The star image is also resized to 110% of the detected width of each face by adding the region_relative
flag:
cl_image_tag("couple.jpg", :overlay=>"golden_star", :gravity=>"faces", :width=>1.1, :flags=>"region_relative")
cl_image_tag("couple.jpg", array("overlay"=>"golden_star", "gravity"=>"faces", "width"=>1.1, "flags"=>"region_relative"))
CloudinaryImage("couple.jpg").image(overlay="golden_star", gravity="faces", width=1.1, flags="region_relative")
cloudinary.image("couple.jpg", {overlay: "golden_star", gravity: "faces", width: 1.1, flags: "region_relative"})
cloudinary.url().transformation(new Transformation().overlay("golden_star").gravity("faces").width(1.1).flags("region_relative")).imageTag("couple.jpg")
$.cloudinary.image("couple.jpg", {overlay: "golden_star", gravity: "faces", width: 1.1, flags: "region_relative"})
cloudinary.Api.UrlImgUp.Transform(new Transformation().Overlay("golden_star").Gravity("faces").Width(1.1).Flags("region_relative")).BuildImageTag("couple.jpg")
Note: When gravity is set to one of the facial detection values and no face is detected in the image, then no overlay is placed at all.
Tiling overlays
Instead of adding the overlay to a single specific location, you can tile the image within the entire image by adding the tiled
flag (fl_tiled
in URLs). For example, tiling an overlay of the image called cloudinary_icon
on to the jpg image named flowers
, with the overlay's opacity set to 50% and scaled to a width of 100 pixels:
cl_image_tag("flowers.jpg", :transformation=>[ {:width=>500}, {:overlay=>"cloudinary_icon", :opacity=>50, :width=>100, :effect=>"brightness:200", :flags=>"tiled"} ])
cl_image_tag("flowers.jpg", array("transformation"=>array( array("width"=>500), array("overlay"=>"cloudinary_icon", "opacity"=>50, "width"=>100, "effect"=>"brightness:200", "flags"=>"tiled") )))
CloudinaryImage("flowers.jpg").image(transformation=[ {"width": 500}, {"overlay": "cloudinary_icon", "opacity": 50, "width": 100, "effect": "brightness:200", "flags": "tiled"} ])
cloudinary.image("flowers.jpg", {transformation: [ {width: 500}, {overlay: "cloudinary_icon", opacity: 50, width: 100, effect: "brightness:200", flags: "tiled"} ]})
cloudinary.url().transformation(new Transformation() .width(500).chain() .overlay("cloudinary_icon").opacity(50).width(100).effect("brightness:200").flags("tiled")).imageTag("flowers.jpg")
$.cloudinary.image("flowers.jpg", {transformation: [ {width: 500}, {overlay: "cloudinary_icon", opacity: 50, width: 100, effect: "brightness:200", flags: "tiled"} ]})
cloudinary.Api.UrlImgUp.Transform(new Transformation() .Width(500).Chain() .Overlay("cloudinary_icon").Opacity(50).Width(100).Effect("brightness:200").Flags("tiled")).BuildImageTag("flowers.jpg")
Applying chained transformations to overlays
You can apply multiple transformations to overlays by adding the layer_apply
flag to the 'last' transformation in the series. That is, the flag tells Cloudinary to apply all chained transformations, until a transformation component that includes this flag, on the last added overlay or underlay instead of applying them on the base image.
For example, the sample
image scaled to a width of 500 pixels before adding the woman
image as an overlay, where the overlay image is automatically cropped to only include the detected faces and then scaled to a width of 150 pixels:
cl_image_tag("sample.jpg", :transformation=>[ {:width=>500}, {:effect=>"brightness:70"}, {:overlay=>"woman", :gravity=>"face", :crop=>"crop"}, {:width=>150}, {:effect=>"saturation:50"}, {:effect=>"shadow"}, {:flags=>"layer_apply"} ])
cl_image_tag("sample.jpg", array("transformation"=>array( array("width"=>500), array("effect"=>"brightness:70"), array("overlay"=>"woman", "gravity"=>"face", "crop"=>"crop"), array("width"=>150), array("effect"=>"saturation:50"), array("effect"=>"shadow"), array("flags"=>"layer_apply") )))
CloudinaryImage("sample.jpg").image(transformation=[ {"width": 500}, {"effect": "brightness:70"}, {"overlay": "woman", "gravity": "face", "crop": "crop"}, {"width": 150}, {"effect": "saturation:50"}, {"effect": "shadow"}, {"flags": "layer_apply"} ])
cloudinary.image("sample.jpg", {transformation: [ {width: 500}, {effect: "brightness:70"}, {overlay: "woman", gravity: "face", crop: "crop"}, {width: 150}, {effect: "saturation:50"}, {effect: "shadow"}, {flags: "layer_apply"} ]})
cloudinary.url().transformation(new Transformation() .width(500).chain() .effect("brightness:70").chain() .overlay("woman").gravity("face").crop("crop").chain() .width(150).chain() .effect("saturation:50").chain() .effect("shadow").chain() .flags("layer_apply")).imageTag("sample.jpg")
$.cloudinary.image("sample.jpg", {transformation: [ {width: 500}, {effect: "brightness:70"}, {overlay: "woman", gravity: "face", crop: "crop"}, {width: 150}, {effect: "saturation:50"}, {effect: "shadow"}, {flags: "layer_apply"} ]})
cloudinary.Api.UrlImgUp.Transform(new Transformation() .Width(500).Chain() .Effect("brightness:70").Chain() .Overlay("woman").Gravity("face").Crop("crop").Chain() .Width(150).Chain() .Effect("saturation:50").Chain() .Effect("shadow").Chain() .Flags("layer_apply")).BuildImageTag("sample.jpg")
Note how the transformations were applied in the last example as chained transformations. The first width adjustment to 500 pixels was made to the base image, and the second width adjustment to 150 pixels was made to the overlay (as was the face detection based cropping) because of the layer_apply
flag.
Adding image underlays
Add an underlay image under a base partially-transparent image with the underlay
parameter (u
in URLs) and the public ID of a previously uploaded PNG image (e.g. u_background
for an image with the public ID of background
). You can determine the dimension and position of the underlay using the width, height, x, y and gravity parameters. The underlay can also be further manipulated like any other image uploaded to Cloudinary, and the underlay parameter supports the same features as for overlays.
For example, adding an underlay of an image called site_bg
to the image named smartphone
. The underlay and base image are both resized to the same width and height, and the brightness is increased to 100 using the brightness effect:
cl_image_tag("smartphone.png", :transformation=>[ {:height=>200, :width=>200, :crop=>"fill"}, {:effect=>"brightness:100", :height=>200, :underlay=>"site_bg", :width=>200} ])
cl_image_tag("smartphone.png", array("transformation"=>array( array("height"=>200, "width"=>200, "crop"=>"fill"), array("effect"=>"brightness:100", "height"=>200, "underlay"=>"site_bg", "width"=>200) )))
CloudinaryImage("smartphone.png").image(transformation=[ {"height": 200, "width": 200, "crop": "fill"}, {"effect": "brightness:100", "height": 200, "underlay": "site_bg", "width": 200} ])
cloudinary.image("smartphone.png", {transformation: [ {height: 200, width: 200, crop: "fill"}, {effect: "brightness:100", height: 200, underlay: "site_bg", width: 200} ]})
cloudinary.url().transformation(new Transformation() .height(200).width(200).crop("fill").chain() .effect("brightness:100").height(200).underlay("site_bg").width(200)).imageTag("smartphone.png")
$.cloudinary.image("smartphone.png", {transformation: [ {height: 200, width: 200, crop: "fill"}, {effect: "brightness:100", height: 200, underlay: "site_bg", width: 200} ]})
cloudinary.Api.UrlImgUp.Transform(new Transformation() .Height(200).Width(200).Crop("fill").Chain() .Effect("brightness:100").Height(200).Underlay("site_bg").Width(200)).BuildImageTag("smartphone.png")
Adding text captions
Add a text caption over the base image with the text:
property of the overlay
parameter ( l_text:
in URLs). The parameter also requires styling parameters such as font family and size (separated with an underscore and followed by a colon), and the text string to display. For example, to overlay the text string "Flowers" in the Arial font with a size of 80 pixels: l_text:Arial_80:Flowers
.
cl_image_tag("flowers.jpg", :transformation=>[ {:width=>500}, {:overlay=>"text:Arial_80:Flowers"} ])
cl_image_tag("flowers.jpg", array("transformation"=>array( array("width"=>500), array("overlay"=>"text:Arial_80:Flowers") )))
CloudinaryImage("flowers.jpg").image(transformation=[ {"width": 500}, {"overlay": "text:Arial_80:Flowers"} ])
cloudinary.image("flowers.jpg", {transformation: [ {width: 500}, {overlay: "text:Arial_80:Flowers"} ]})
cloudinary.url().transformation(new Transformation() .width(500).chain() .overlay("text:Arial_80:Flowers")).imageTag("flowers.jpg")
$.cloudinary.image("flowers.jpg", {transformation: [ {width: 500}, {overlay: "text:Arial_80:Flowers"} ]})
cloudinary.Api.UrlImgUp.Transform(new Transformation() .Width(500).Chain() .Overlay("text:Arial_80:Flowers")).BuildImageTag("flowers.jpg")
Notes: Text strings containing special characters need to be modified (escaped) for use with the text overlay feature. This is relevant for any special characters that would not be allowed “as is” in a valid URL path, as well as other special unicode characters. These text strings should be escaped using % based encoding to ensure the text string is valid (for example, replacing ?
with %3F
and using %20
for spacing between words). This encoding is done automatically when embedding images using the Cloudinary SDK helper methods and only needs to be done when manually adding the image delivery URL.
Possible styling parameters include:
font_family
- Required name of a font family. e.g.,arial
font_size
- Required font size in pixels. e.g.,12
font_weight
- Optional text weight. Possible values: normal (default value) or bold. e.g.,bold
font_style
- Optional font style. Possible values: normal (default value) or italic. e.g.,italic
text_decoration
- Optional text decoration. Possible values: none (default value), underline or strikethrough. e.g.,underline
text_align
- Optional text alignment. Possible values: left (default value), center, right, end, start or justify. e.g.,justify
stroke
- Optional font stroke (border). Possible values: none (default value) or stroke. e.g.,stroke
. Set the color and weight of the stroke with theborder
parameter (bo
in URLs).letter_spacing
- Optional spacing between the letters in pixels. Can be a positive or negative, integer or decimal value. The parameter name must also be included with the value to differentiate it from the font size value. e.g.,letter_spacing_3.3
line_spacing
- Optional spacing between the lines in pixels (only relevant for multi-line text). Can be a positive or negative, integer or decimal value. The parameter name must also be included with the value to differentiate it from the font size value. e.g.,line_spacing_2.8
The Cloudinary SDK helper methods support supplying the values as an array of mapped values or as a serialized string of values. For example in Ruby (other frameworks use similar syntax):
overlay: { text: 'Hello World', font_family: 'Arial', font_size: 18, font_weight: 'bold', font_style: 'italic', letter_spacing: 4 }
For example, to overlay the text string "Flowers" in Verdana bold with a size of 75 pixels, underlined, and with 14 pixels spacing between the letters: l_text:verdana_75_bold_underline_letter_spacing_14:Flowers
.
cl_image_tag("flowers.jpg", :transformation=>[ {:width=>500}, {:overlay=>"text:Verdana_75_bold_underline_letter_spacing_14:Flowers"} ])
cl_image_tag("flowers.jpg", array("transformation"=>array( array("width"=>500), array("overlay"=>"text:Verdana_75_bold_underline_letter_spacing_14:Flowers") )))
CloudinaryImage("flowers.jpg").image(transformation=[ {"width": 500}, {"overlay": "text:Verdana_75_bold_underline_letter_spacing_14:Flowers"} ])
cloudinary.image("flowers.jpg", {transformation: [ {width: 500}, {overlay: "text:Verdana_75_bold_underline_letter_spacing_14:Flowers"} ]})
cloudinary.url().transformation(new Transformation() .width(500).chain() .overlay("text:Verdana_75_bold_underline_letter_spacing_14:Flowers")).imageTag("flowers.jpg")
$.cloudinary.image("flowers.jpg", {transformation: [ {width: 500}, {overlay: "text:Verdana_75_bold_underline_letter_spacing_14:Flowers"} ]})
cloudinary.Api.UrlImgUp.Transform(new Transformation() .Width(500).Chain() .Overlay("text:Verdana_75_bold_underline_letter_spacing_14:Flowers")).BuildImageTag("flowers.jpg")
As for displaying image overlays, you can also determine the dimension and position of the text caption using the width, height, x, y and gravity parameters. The resulting caption is actually an image created on the fly and can be further manipulated like any other image uploaded to Cloudinary.
For example, adding the text string "Cool image" in Roboto font with a size of 60 pixels at a distance of 80 pixels from the bottom of the image named flowers
:
cl_image_tag("flowers.jpg", :transformation=>[ {:width=>500}, {:overlay=>"text:Roboto_60:Cool%20image", :gravity=>"south", :y=>80} ])
cl_image_tag("flowers.jpg", array("transformation"=>array( array("width"=>500), array("overlay"=>"text:Roboto_60:Cool%20image", "gravity"=>"south", "y"=>80) )))
CloudinaryImage("flowers.jpg").image(transformation=[ {"width": 500}, {"overlay": "text:Roboto_60:Cool%20image", "gravity": "south", "y": 80} ])
cloudinary.image("flowers.jpg", {transformation: [ {width: 500}, {overlay: "text:Roboto_60:Cool%20image", gravity: "south", y: 80} ]})
cloudinary.url().transformation(new Transformation() .width(500).chain() .overlay("text:Roboto_60:Cool%20image").gravity("south").y(80)).imageTag("flowers.jpg")
$.cloudinary.image("flowers.jpg", {transformation: [ {width: 500}, {overlay: "text:Roboto_60:Cool%20image", gravity: "south", y: 80} ]})
cloudinary.Api.UrlImgUp.Transform(new Transformation() .Width(500).Chain() .Overlay("text:Roboto_60:Cool%20image").Gravity("south").Y(80)).BuildImageTag("flowers.jpg")
Set text color
You can control the color of the text overlay by adding the color
property (co
in URLs).
Opaque colors can be set as an RGB hex triplet (e.g. co_rgb:3e2222
), a 3-digit RGB hex (e.g. co_rgb:777
) or a named color (e.g. co_green
). Cloudinary's client libraries also support a #
shortcut for RGB (e.g. setting the color to #3e2222
which is then translated to co_rgb:3e2222
). By default, if the color property is omitted then the text has a black color.
For example, adding the text string "Cool image" in Times bold with a size of 90 pixels at a distance of 80 pixels from the bottom of the image named flowers
, in yellow text (FFFF00):
cl_image_tag("flowers.jpg", :transformation=>[ {:width=>500}, {:overlay=>"text:Times_90_bold:Cool%20image", :gravity=>"south", :y=>80, :color=>"#FFFF00"} ])
cl_image_tag("flowers.jpg", array("transformation"=>array( array("width"=>500), array("overlay"=>"text:Times_90_bold:Cool%20image", "gravity"=>"south", "y"=>80, "color"=>"#FFFF00") )))
CloudinaryImage("flowers.jpg").image(transformation=[ {"width": 500}, {"overlay": "text:Times_90_bold:Cool%20image", "gravity": "south", "y": 80, "color": "#FFFF00"} ])
cloudinary.image("flowers.jpg", {transformation: [ {width: 500}, {overlay: "text:Times_90_bold:Cool%20image", gravity: "south", y: 80, color: "#FFFF00"} ]})
cloudinary.url().transformation(new Transformation() .width(500).chain() .overlay("text:Times_90_bold:Cool%20image").gravity("south").y(80).color("#FFFF00")).imageTag("flowers.jpg")
$.cloudinary.image("flowers.jpg", {transformation: [ {width: 500}, {overlay: "text:Times_90_bold:Cool%20image", gravity: "south", y: 80, color: "#FFFF00"} ]})
cloudinary.Api.UrlImgUp.Transform(new Transformation() .Width(500).Chain() .Overlay("text:Times_90_bold:Cool%20image").Gravity("south").Y(80).Color("#FFFF00")).BuildImageTag("flowers.jpg")
You can also use a 4-digit or 8-digit RGBA hex quadruplet for the color, where the 4th hex value represents the alpha (opacity) value (e.g. co_rgb:3e222240
results in 25% opacity).
The example below uses the same text string "Cool image" in Times bold with a size of 90 pixels at a distance of 80 pixels from the bottom of the image named sample
, in yellow text, but this time with an opacity of 50% (FFFF0080):
cl_image_tag("flowers.jpg", :transformation=>[ {:width=>500}, {:overlay=>"text:Times_90_bold:Cool%20image", :gravity=>"south", :y=>80, :color=>"#FFFF0080"} ])
cl_image_tag("flowers.jpg", array("transformation"=>array( array("width"=>500), array("overlay"=>"text:Times_90_bold:Cool%20image", "gravity"=>"south", "y"=>80, "color"=>"#FFFF0080") )))
CloudinaryImage("flowers.jpg").image(transformation=[ {"width": 500}, {"overlay": "text:Times_90_bold:Cool%20image", "gravity": "south", "y": 80, "color": "#FFFF0080"} ])
cloudinary.image("flowers.jpg", {transformation: [ {width: 500}, {overlay: "text:Times_90_bold:Cool%20image", gravity: "south", y: 80, color: "#FFFF0080"} ]})
cloudinary.url().transformation(new Transformation() .width(500).chain() .overlay("text:Times_90_bold:Cool%20image").gravity("south").y(80).color("#FFFF0080")).imageTag("flowers.jpg")
$.cloudinary.image("flowers.jpg", {transformation: [ {width: 500}, {overlay: "text:Times_90_bold:Cool%20image", gravity: "south", y: 80, color: "#FFFF0080"} ]})
cloudinary.Api.UrlImgUp.Transform(new Transformation() .Width(500).Chain() .Overlay("text:Times_90_bold:Cool%20image").Gravity("south").Y(80).Color("#FFFF0080")).BuildImageTag("flowers.jpg")
Adding multi-line text
You can manually add multiple lines of text by separating each line of text with the newline character (%0A). For example, adding the text string "Cool image" in Verdana bold with a size of 50 pixels at a distance of 10 pixels from the left border of the image named flowers
, where each word appears on a new line:
cl_image_tag("flowers.jpg", :transformation=>[ {:width=>500}, {:overlay=>"text:Verdana_50_bold:Cool%0Aimage", :gravity=>"west", :x=>10} ])
cl_image_tag("flowers.jpg", array("transformation"=>array( array("width"=>500), array("overlay"=>"text:Verdana_50_bold:Cool%0Aimage", "gravity"=>"west", "x"=>10) )))
CloudinaryImage("flowers.jpg").image(transformation=[ {"width": 500}, {"overlay": "text:Verdana_50_bold:Cool%0Aimage", "gravity": "west", "x": 10} ])
cloudinary.image("flowers.jpg", {transformation: [ {width: 500}, {overlay: "text:Verdana_50_bold:Cool%0Aimage", gravity: "west", x: 10} ]})
cloudinary.url().transformation(new Transformation() .width(500).chain() .overlay("text:Verdana_50_bold:Cool%0Aimage").gravity("west").x(10)).imageTag("flowers.jpg")
$.cloudinary.image("flowers.jpg", {transformation: [ {width: 500}, {overlay: "text:Verdana_50_bold:Cool%0Aimage", gravity: "west", x: 10} ]})
cloudinary.Api.UrlImgUp.Transform(new Transformation() .Width(500).Chain() .Overlay("text:Verdana_50_bold:Cool%0Aimage").Gravity("west").X(10)).BuildImageTag("flowers.jpg")
Cloudinary also supports automatic multi-line text by defining a maximum width
for the text string and adding the fit
crop mode, which tells Cloudinary to automatically wrap the actual text content onto a new line once the width is reached. For example, to add a long text string in bold Neucha font with a size of 26 pixels to the flowers
image, that wraps at a width of 400 pixels:
cl_image_tag("flowers.jpg", :transformation=>[ {:width=>500}, {:width=>400, :overlay=>"text:Neucha_26_bold:Lorem%20ipsum%20dolor%20sit%20amet%20consectetur%20adipisicing%20elit%20sed%20do%20eiusmod%20tempor%20incididunt%20ut%20labore%20et%20dolore%20magna%20aliqua.%20Ut%20enim%20ad%20minim%20veniam%20quis%20nostrud%20exercitation%20ullamco%20laboris%20nisi%20ut%20aliquip%20ex%20ea%20commodo%20consequat.", :crop=>"fit"} ])
cl_image_tag("flowers.jpg", array("transformation"=>array( array("width"=>500), array("width"=>400, "overlay"=>"text:Neucha_26_bold:Lorem%20ipsum%20dolor%20sit%20amet%20consectetur%20adipisicing%20elit%20sed%20do%20eiusmod%20tempor%20incididunt%20ut%20labore%20et%20dolore%20magna%20aliqua.%20Ut%20enim%20ad%20minim%20veniam%20quis%20nostrud%20exercitation%20ullamco%20laboris%20nisi%20ut%20aliquip%20ex%20ea%20commodo%20consequat.", "crop"=>"fit") )))
CloudinaryImage("flowers.jpg").image(transformation=[ {"width": 500}, {"width": 400, "overlay": "text:Neucha_26_bold:Lorem%20ipsum%20dolor%20sit%20amet%20consectetur%20adipisicing%20elit%20sed%20do%20eiusmod%20tempor%20incididunt%20ut%20labore%20et%20dolore%20magna%20aliqua.%20Ut%20enim%20ad%20minim%20veniam%20quis%20nostrud%20exercitation%20ullamco%20laboris%20nisi%20ut%20aliquip%20ex%20ea%20commodo%20consequat.", "crop": "fit"} ])
cloudinary.image("flowers.jpg", {transformation: [ {width: 500}, {width: 400, overlay: "text:Neucha_26_bold:Lorem%20ipsum%20dolor%20sit%20amet%20consectetur%20adipisicing%20elit%20sed%20do%20eiusmod%20tempor%20incididunt%20ut%20labore%20et%20dolore%20magna%20aliqua.%20Ut%20enim%20ad%20minim%20veniam%20quis%20nostrud%20exercitation%20ullamco%20laboris%20nisi%20ut%20aliquip%20ex%20ea%20commodo%20consequat.", crop: "fit"} ]})
cloudinary.url().transformation(new Transformation() .width(500).chain() .width(400).overlay("text:Neucha_26_bold:Lorem%20ipsum%20dolor%20sit%20amet%20consectetur%20adipisicing%20elit%20sed%20do%20eiusmod%20tempor%20incididunt%20ut%20labore%20et%20dolore%20magna%20aliqua.%20Ut%20enim%20ad%20minim%20veniam%20quis%20nostrud%20exercitation%20ullamco%20laboris%20nisi%20ut%20aliquip%20ex%20ea%20commodo%20consequat.").crop("fit")).imageTag("flowers.jpg")
$.cloudinary.image("flowers.jpg", {transformation: [ {width: 500}, {width: 400, overlay: "text:Neucha_26_bold:Lorem%20ipsum%20dolor%20sit%20amet%20consectetur%20adipisicing%20elit%20sed%20do%20eiusmod%20tempor%20incididunt%20ut%20labore%20et%20dolore%20magna%20aliqua.%20Ut%20enim%20ad%20minim%20veniam%20quis%20nostrud%20exercitation%20ullamco%20laboris%20nisi%20ut%20aliquip%20ex%20ea%20commodo%20consequat.", crop: "fit"} ]})
cloudinary.Api.UrlImgUp.Transform(new Transformation() .Width(500).Chain() .Width(400).Overlay("text:Neucha_26_bold:Lorem%20ipsum%20dolor%20sit%20amet%20consectetur%20adipisicing%20elit%20sed%20do%20eiusmod%20tempor%20incididunt%20ut%20labore%20et%20dolore%20magna%20aliqua.%20Ut%20enim%20ad%20minim%20veniam%20quis%20nostrud%20exercitation%20ullamco%20laboris%20nisi%20ut%20aliquip%20ex%20ea%20commodo%20consequat.").Crop("fit")).BuildImageTag("flowers.jpg")
To define a maximum height for the multi-line text add the height
parameter: any text that does not fit within the space defined is cut and an ellipsis (...
) is added to the end of the text string to indicate that the text was truncated. You can also set the text alignment and line spacing values to further control the text's appearance.
For example, to add a long text string in center aligned bold Times font with a size of 14 pixels to the envelope
image, that wraps at a width of 200 pixels and is limited to a height of 350 pixels. The text is also rotated by 9 degrees and set 30 pixels from the north border to better align with the underlying image:
cl_image_tag("envelope.jpg", :transformation=>[ {:width=>300}, {:width=>200, :y=>30, :angle=>9, :height=>150, :gravity=>"north", :overlay=>"text:Times_18_bold_center:Lorem%20ipsum%20dolor%20sit%20amet%20consectetur%20adipisicing%20elit%20sed%20do%20eiusmod%20tempor%20incididunt%20ut%20labore%20et%20dolore%20magna%20aliqua.%20Ut%20enim%20ad%20minim%20veniam%20quis%20nostrud%20exercitation%20ullamco%20laboris%20nisi%20ut%20aliquip%20ex%20ea%20commodo%20consequat.", :crop=>"fit"} ])
cl_image_tag("envelope.jpg", array("transformation"=>array( array("width"=>300), array("width"=>200, "y"=>30, "angle"=>9, "height"=>150, "gravity"=>"north", "overlay"=>"text:Times_18_bold_center:Lorem%20ipsum%20dolor%20sit%20amet%20consectetur%20adipisicing%20elit%20sed%20do%20eiusmod%20tempor%20incididunt%20ut%20labore%20et%20dolore%20magna%20aliqua.%20Ut%20enim%20ad%20minim%20veniam%20quis%20nostrud%20exercitation%20ullamco%20laboris%20nisi%20ut%20aliquip%20ex%20ea%20commodo%20consequat.", "crop"=>"fit") )))
CloudinaryImage("envelope.jpg").image(transformation=[ {"width": 300}, {"width": 200, "y": 30, "angle": 9, "height": 150, "gravity": "north", "overlay": "text:Times_18_bold_center:Lorem%20ipsum%20dolor%20sit%20amet%20consectetur%20adipisicing%20elit%20sed%20do%20eiusmod%20tempor%20incididunt%20ut%20labore%20et%20dolore%20magna%20aliqua.%20Ut%20enim%20ad%20minim%20veniam%20quis%20nostrud%20exercitation%20ullamco%20laboris%20nisi%20ut%20aliquip%20ex%20ea%20commodo%20consequat.", "crop": "fit"} ])
cloudinary.image("envelope.jpg", {transformation: [ {width: 300}, {width: 200, y: 30, angle: 9, height: 150, gravity: "north", overlay: "text:Times_18_bold_center:Lorem%20ipsum%20dolor%20sit%20amet%20consectetur%20adipisicing%20elit%20sed%20do%20eiusmod%20tempor%20incididunt%20ut%20labore%20et%20dolore%20magna%20aliqua.%20Ut%20enim%20ad%20minim%20veniam%20quis%20nostrud%20exercitation%20ullamco%20laboris%20nisi%20ut%20aliquip%20ex%20ea%20commodo%20consequat.", crop: "fit"} ]})
cloudinary.url().transformation(new Transformation() .width(300).chain() .width(200).y(30).angle(9).height(150).gravity("north").overlay("text:Times_18_bold_center:Lorem%20ipsum%20dolor%20sit%20amet%20consectetur%20adipisicing%20elit%20sed%20do%20eiusmod%20tempor%20incididunt%20ut%20labore%20et%20dolore%20magna%20aliqua.%20Ut%20enim%20ad%20minim%20veniam%20quis%20nostrud%20exercitation%20ullamco%20laboris%20nisi%20ut%20aliquip%20ex%20ea%20commodo%20consequat.").crop("fit")).imageTag("envelope.jpg")
$.cloudinary.image("envelope.jpg", {transformation: [ {width: 300}, {width: 200, y: 30, angle: 9, height: 150, gravity: "north", overlay: "text:Times_18_bold_center:Lorem%20ipsum%20dolor%20sit%20amet%20consectetur%20adipisicing%20elit%20sed%20do%20eiusmod%20tempor%20incididunt%20ut%20labore%20et%20dolore%20magna%20aliqua.%20Ut%20enim%20ad%20minim%20veniam%20quis%20nostrud%20exercitation%20ullamco%20laboris%20nisi%20ut%20aliquip%20ex%20ea%20commodo%20consequat.", crop: "fit"} ]})
cloudinary.Api.UrlImgUp.Transform(new Transformation() .Width(300).Chain() .Width(200).Y(30).Angle(9).Height(150).Gravity("north").Overlay("text:Times_18_bold_center:Lorem%20ipsum%20dolor%20sit%20amet%20consectetur%20adipisicing%20elit%20sed%20do%20eiusmod%20tempor%20incididunt%20ut%20labore%20et%20dolore%20magna%20aliqua.%20Ut%20enim%20ad%20minim%20veniam%20quis%20nostrud%20exercitation%20ullamco%20laboris%20nisi%20ut%20aliquip%20ex%20ea%20commodo%20consequat.").Crop("fit")).BuildImageTag("envelope.jpg")
Using predefined text images
Instead of specifying the styling parameters every time you need to dynamically add a text caption to an image, you can use the Public ID of a text image created with the text
method of the upload API. The same styles that were used to create the text image will also be dynamically applied to the text caption. The default text string of the text image is also used unless you provide a new text string, which can be useful if you don't want the text string to appear in the URL, or if the text string is very long.
For example, adding the text string "Stylish text" using the same styling applied in creating the text image named sample_text_style
(Roboto font, 82 size, bold and red):
cl_image_tag("flowers.jpg", :transformation=>[ {:width=>500}, {:overlay=>"text:sample_text_style:Stylish%20text", :gravity=>"south"} ])
cl_image_tag("flowers.jpg", array("transformation"=>array( array("width"=>500), array("overlay"=>"text:sample_text_style:Stylish%20text", "gravity"=>"south") )))
CloudinaryImage("flowers.jpg").image(transformation=[ {"width": 500}, {"overlay": "text:sample_text_style:Stylish%20text", "gravity": "south"} ])
cloudinary.image("flowers.jpg", {transformation: [ {width: 500}, {overlay: "text:sample_text_style:Stylish%20text", gravity: "south"} ]})
cloudinary.url().transformation(new Transformation() .width(500).chain() .overlay("text:sample_text_style:Stylish%20text").gravity("south")).imageTag("flowers.jpg")
$.cloudinary.image("flowers.jpg", {transformation: [ {width: 500}, {overlay: "text:sample_text_style:Stylish%20text", gravity: "south"} ]})
cloudinary.Api.UrlImgUp.Transform(new Transformation() .Width(500).Chain() .Overlay("text:sample_text_style:Stylish%20text").Gravity("south")).BuildImageTag("flowers.jpg")
Applying 3D LUTs to images
3D lookup tables (3D LUTs) are used to map one color space to another. They can be used to adjust colors, contrast, and/or saturation, so that you can correct contrast, fix a camera’s inability to see a particular color shade, or give a final finished look or a particular style to your image.
After uploading a .3dl
file to your account as a raw file, you can apply it to any image using the lut:
property of the overlay
parameter ( l_lut:
in URLs), followed by the LUT file name (including the .3dl
extension).
Below you can see the laydybug_top.jpg
image file in it's original color, compared to the video with different LUT files applied. Below these is the code for applying one of the LUTs.
cl_image_tag("ladybug_top.jpg", :overlay=>"lut:iwltbap_aspen.3dl")
cl_image_tag("ladybug_top.jpg", array("overlay"=>"lut:iwltbap_aspen.3dl"))
CloudinaryImage("ladybug_top.jpg").image(overlay="lut:iwltbap_aspen.3dl")
cloudinary.image("ladybug_top.jpg", {overlay: "lut:iwltbap_aspen.3dl"})
cloudinary.url().transformation(new Transformation().overlay("lut:iwltbap_aspen.3dl")).imageTag("ladybug_top.jpg")
$.cloudinary.image("ladybug_top.jpg", {overlay: "lut:iwltbap_aspen.3dl"})
cloudinary.Api.UrlImgUp.Transform(new Transformation().Overlay("lut:iwltbap_aspen.3dl")).BuildImageTag("ladybug_top.jpg")
Adding multiple overlays
Multiple overlays, text captions and underlays can be added as chained transformations to an image. The following example adds both an image overlay and a text caption to the image named sample
as follows:
- An overlay of an image called
couple
, cropped to an ellipse that only includes the detected faces. - An overlay of an image called
cloudinary_icon
with a relative width of 80% of the base image and an opacity of 50% and a brightness of 100. - The text string "Sample image" in Impact bold font with a size of 40 pixels at a distance of 20 pixels from the bottom of the base image.
cl_image_tag("sample.jpg", :transformation=>[ {:overlay=>"couple"}, {:gravity=>"faces", :crop=>"crop"}, {:width=>1.5, :radius=>"max"}, {:flags=>"layer_apply", :gravity=>"north_east"}, {:overlay=>"cloudinary_icon", :width=>0.8, :flags=>"relative", :opacity=>50, :effect=>"brightness:100"}, {:overlay=>"text:impact_40_bold:Sample%20image", :gravity=>"south", :y=>20} ])
cl_image_tag("sample.jpg", array("transformation"=>array( array("overlay"=>"couple"), array("gravity"=>"faces", "crop"=>"crop"), array("width"=>1.5, "radius"=>"max"), array("flags"=>"layer_apply", "gravity"=>"north_east"), array("overlay"=>"cloudinary_icon", "width"=>0.8, "flags"=>"relative", "opacity"=>50, "effect"=>"brightness:100"), array("overlay"=>"text:impact_40_bold:Sample%20image", "gravity"=>"south", "y"=>20) )))
CloudinaryImage("sample.jpg").image(transformation=[ {"overlay": "couple"}, {"gravity": "faces", "crop": "crop"}, {"width": 1.5, "radius": "max"}, {"flags": "layer_apply", "gravity": "north_east"}, {"overlay": "cloudinary_icon", "width": 0.8, "flags": "relative", "opacity": 50, "effect": "brightness:100"}, {"overlay": "text:impact_40_bold:Sample%20image", "gravity": "south", "y": 20} ])
cloudinary.image("sample.jpg", {transformation: [ {overlay: "couple"}, {gravity: "faces", crop: "crop"}, {width: 1.5, radius: "max"}, {flags: "layer_apply", gravity: "north_east"}, {overlay: "cloudinary_icon", width: 0.8, flags: "relative", opacity: 50, effect: "brightness:100"}, {overlay: "text:impact_40_bold:Sample%20image", gravity: "south", y: 20} ]})
cloudinary.url().transformation(new Transformation() .overlay("couple").chain() .gravity("faces").crop("crop").chain() .width(1.5).radius("max").chain() .flags("layer_apply").gravity("north_east").chain() .overlay("cloudinary_icon").width(0.8).flags("relative").opacity(50).effect("brightness:100").chain() .overlay("text:impact_40_bold:Sample%20image").gravity("south").y(20)).imageTag("sample.jpg")
$.cloudinary.image("sample.jpg", {transformation: [ {overlay: "couple"}, {gravity: "faces", crop: "crop"}, {width: 1.5, radius: "max"}, {flags: "layer_apply", gravity: "north_east"}, {overlay: "cloudinary_icon", width: 0.8, flags: "relative", opacity: 50, effect: "brightness:100"}, {overlay: "text:impact_40_bold:Sample%20image", gravity: "south", y: 20} ]})
cloudinary.Api.UrlImgUp.Transform(new Transformation() .Overlay("couple").Chain() .Gravity("faces").Crop("crop").Chain() .Width(1.5).Radius("max").Chain() .Flags("layer_apply").Gravity("north_east").Chain() .Overlay("cloudinary_icon").Width(0.8).Flags("relative").Opacity(50).Effect("brightness:100").Chain() .Overlay("text:impact_40_bold:Sample%20image").Gravity("south").Y(20)).BuildImageTag("sample.jpg")
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 a single 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")
jQuery:$.cloudinary.image("flower.jpg", {transformation: [ {width: 300, height: 300, crop: "crop"}, {width: 150, radius: "max", crop: "scale"} ]})
.Net:cloudinary.Api.UrlImgUp.Transform(new Transformation() .Width(300).Height(300).Crop("crop").Chain() .Width(150).Radius("max").Crop("scale")).BuildImageTag("flower.jpg")
Four chained transformations: custom crop to 150x100, fill to 130x100, rotate by 20 degrees and scale to 80%:
Ruby:cl_image_tag("flower.jpg", :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("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(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", {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")).imageTag("flower.jpg")
jQuery:$.cloudinary.image("flower.jpg", {transformation: [ {height: 100, width: 150, x: 380, y: 250, crop: "crop"}, {height: 100, width: 130, crop: "fill"}, {angle: 20}, {width: 0.8, crop: "scale"} ]})
.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")).BuildImageTag("flower.jpg")
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:
cl_image_tag("sample.jpg", :transformation=>["fit_100x150"])
cl_image_tag("sample.jpg", array("transformation"=>array("fit_100x150")))
CloudinaryImage("sample.jpg").image(transformation=["fit_100x150"])
cloudinary.image("sample.jpg", {transformation: ["fit_100x150"]})
cloudinary.url().transformation(new Transformation().named("fit_100x150")).imageTag("sample.jpg")
$.cloudinary.image("sample.jpg", {transformation: ["fit_100x150"]})
cloudinary.Api.UrlImgUp.Transform(new Transformation().Named("fit_100x150")).BuildImageTag("sample.jpg")
To chain transformations that include the jpg_with_quality_30
named transformation, as well as fitting it to a 100 pixel width and a 50 pixel height:
cl_image_tag("sample.jpg", :transformation=>["jpg_with_quality_30"], :width=>100, :height=>50, :crop=>"fit")
cl_image_tag("sample.jpg", array("transformation"=>array("jpg_with_quality_30"), "width"=>100, "height"=>50, "crop"=>"fit"))
CloudinaryImage("sample.jpg").image(transformation=["jpg_with_quality_30"], width=100, height=50, crop="fit")
cloudinary.image("sample.jpg", {transformation: ["jpg_with_quality_30"], width: 100, height: 50, crop: "fit"})
cloudinary.url().transformation(new Transformation().named("jpg_with_quality_30").width(100).height(50).crop("fit")).imageTag("sample.jpg")
$.cloudinary.image("sample.jpg", {transformation: ["jpg_with_quality_30"], width: 100, height: 50, crop: "fit"})
cloudinary.Api.UrlImgUp.Transform(new Transformation().Named("jpg_with_quality_30").Width(100).Height(50).Crop("fit")).BuildImageTag("sample.jpg")
To chain named transformations, simply separate them with a slash (/
). For example, chaining the three named transformations we defined above:
cl_image_tag("sample.jpg", :transformation=>[ {:transformation=>["jpg_with_quality_30"]}, {:transformation=>["crop_400x400"]}, {:transformation=>["fit_100x150"]} ])
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")) )))
CloudinaryImage("sample.jpg").image(transformation=[ {"transformation": ["jpg_with_quality_30"]}, {"transformation": ["crop_400x400"]}, {"transformation": ["fit_100x150"]} ])
cloudinary.image("sample.jpg", {transformation: [ {transformation: ["jpg_with_quality_30"]}, {transformation: ["crop_400x400"]}, {transformation: ["fit_100x150"]} ]})
cloudinary.url().transformation(new Transformation() .named("jpg_with_quality_30").chain() .named("crop_400x400").chain() .named("fit_100x150")).imageTag("sample.jpg")
$.cloudinary.image("sample.jpg", {transformation: [ {transformation: ["jpg_with_quality_30"]}, {transformation: ["crop_400x400"]}, {transformation: ["fit_100x150"]} ]})
cloudinary.Api.UrlImgUp.Transform(new Transformation() .Named("jpg_with_quality_30").Chain() .Named("crop_400x400").Chain() .Named("fit_100x150")).BuildImageTag("sample.jpg")
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:
cl_image_tag("sample.jpg", :transformation=>["demo_combined"])
cl_image_tag("sample.jpg", array("transformation"=>array("demo_combined")))
CloudinaryImage("sample.jpg").image(transformation=["demo_combined"])
cloudinary.image("sample.jpg", {transformation: ["demo_combined"]})
cloudinary.url().transformation(new Transformation().named("demo_combined")).imageTag("sample.jpg")
$.cloudinary.image("sample.jpg", {transformation: ["demo_combined"]})
cloudinary.Api.UrlImgUp.Transform(new Transformation().Named("demo_combined")).BuildImageTag("sample.jpg")
Notes:
- The automatic format selection parameter (
f_auto
) must be specifically added as part of the URL and not within named transformations. - Updating a named transformation via the Management Console or the Admin API does not automatically update any images already derived by the named transformation, unless there are less than 1000 of them to update. You can also use the Update transformation method of the Admin API with the
unsafe_edit
option to update an existing named transformation.
Image optimization
Image optimization involves delivering images with the smallest possible file size while maintaining visual quality. Optimizing images means saving bytes and improving performance for your website: the fewer bytes the browser has to download, the faster the browser can download and render the content on the user's screen. Selecting the optimal image to deliver to your users involves understanding all the various factors that influence the image's file size and quality, as well as considering other details that can utilize unnecessary bandwidth, such as:
- Wasteful browser-side resizing
- Delivering static icons one by one
- Using a single image size across all delivery mediums
- Not using a Content Delivery Network.
For more information on avoiding mistakes when optimizing images, see the following articles:
- Top 10 mistakes in handling website images and how to solve them
- How to analyze your website's images, improve loading speed and reduce bandwidth costs
One of the major factors in image optimization is selecting the correct format to deliver to your users, and avoid delivering unnecessarily high quality images. Certain browsers also support newer image formats that reduce the file size even further.
For more information on selecting the best image format, see the following articles:
- Automatic WebP format CDN delivery based on visitors browsers
- JPEG-XR conversion with auto browser detection, optimize images for IE users
- Reduce size of animated GIFs, automatically convert to WebM and MP4
- Animated WebP - how to convert animated GIF to WebP and save up to 90% bandwidth
- PNG optimization - saving bandwidth on transparent PNGs with dynamic underlay
- How to support WebP images, save bandwidth and improve user experience
- FLIF, the new lossless image format that outperforms PNG, WebP and BPG
Cloudinary offers many features for optimizing the images you deliver to your users. The following optimizations are implemented automatically:
- Running optimization algorithms to minimize the file size without impairing the visual quality when generating images in the PNG, JPEG or GIF format.
- Stripping all associated metadata from the image file unless the
keep_iptc
flag is included. - Automatically adjusting the quality when generating images in the WebP, GIF, JPEG and JPEG-XR formats. The automatic default adjustments can be controlled with the quality parameter.
Further image optimizations supported by Cloudinary:
- Use the PNG8 format for delivering PNG files with the
png8
flag. - Use lossy compression when delivering animated GIF files with the
lossy
flag. See the Lossy compression for optimizing animated GIFs article for more information. - Use the
f_auto
parameter to automatically detect a user's browser and then deliver the file in the best format for that browser: WebP to Chrome, JPEG-XR to Internet Explorer and the requested file format to all other browsers. - Use the JPEGmini add-on to automatically select the best visual quality for a JPEG image while keeping the file size to a minimum. For more information, see the JPEGmini image optimization documentation and the Optimize your JPEG images without compromising quality with JPEGmini and Cloudinary article.
Responsive images
Responsive web design is a method of designing websites to provide an optimal viewing experience to users, irrespective of the device, window size, orientation, or resolution used to view the website. A site designed responsively adapts its layout to the viewing environment, resizing and moving elements dynamically and based on the properties of the browser or device the site is being displayed on.
When it comes to images, a responsively designed website should not just send the highest resolution image and then use browser resizing to display the image on various devices: that would be a huge waste of bandwidth for users on small, low-resolution displays. The best solution is to prepare an image in various resolutions and sizes, and then deliver the best possible resolution image, based on the device's resolution and the width available, without needlessly wasting bandwidth or loading time. This can turn out to be a complex solution to implement and maintain when considering the number of images needed, and the time to create all the different resolutions and image dimensions.
Cloudinary can help reduce the complexity with dynamic image transformations. You can simply build image URLs with any image width or height based on the specific device resolution and window size. This means you don't have to pre-create the images, with dynamic resizing taking place on-the-fly as needed.
Cloudinary also provides an open source tool for automatically generating the optimal responsive image dimensions: the Responsive Image Breakpoints Generator.
See the following articles on responsive image solutions for more information:
- How to automatically adapt website images to Retina and HiDPI devices shows how to automatically deliver the correct resolution image to a device according to the Device Pixel Ratio (DPR) it supports, with the
dpr_auto
parameter. - How to automatically create images for Responsive design describes an automated solution for responsive images using the
w_auto
parameter and the jQuery plug-in. - Responsive images with 'srcset', 'sizes' and Cloudinary gives information on correctly using the HTML
<img>
tag and its parameters to deliver responsive images. - Automatically art-directed responsive images shows how to use the HTML
<picture>
tag to create art-directed responsive images. - Introducing intelligent responsive image breakpoints solutions introduces an open source tool for automatically generating the optimal responsive image dimensions.
Automatic responsive images
Developers of responsive websites need a solution for displaying images in different sizes, different aspect ratios and different styles. This involves both scaling down images and cropping them to match the art-direction of the responsive design of the website.
Cloudinary provides an automatic solution for handling dynamic on-the-fly generation of images in order to match any required dimensions and graphic design: deliver different image resolutions according to the available image width and the DPR (Device Pixel Ratio) of every device, and avoid generating and delivering too many image versions for the various resolutions or too few versions that might result in wasting bandwidth and degrading user experience.
Automatic responsive images is based on Client-Hints, a technology that allows web browsers to inform servers (or CDN layers) with the required dimensions and pixel densities of each specific image download request. This allows a single URL to return different image sizes according to the specific needs of the responsive website in every user's device and browser. Browsers that support Client-Hints (already supported by Chrome, Android Browser and Opera) will send hints as HTTP request headers if this behavior is enabled for their websites. The relevant hints are the DPR (Device Pixel Ratio) value, the Width available for the specific image in the responsive layout, and the Viewport-Width of the browser's window.
The HTML page must also have Client-Hints enabled, which can be easily accomplished by using Cloudinary's SDKs and adding the client_hints_meta_tag
to the page or by manually adding the following line to your HTML page:
<meta http-equiv="Accept-CH" content="DPR, Viewport-Width, Width">
Using Client Hints, Cloudinary’s solution is able to determine the layout width of an image on a user’s device and the pixel density of their screen. Cloudinary can then decide on the size of the image the browser needs for displaying to the user, and select and deliver an optimal resource – all at the CDN level. Alternate, re-sized versions of images are generated with the help of Cloudinary’s Responsive Images Breakpoint algorithms, ensuring that the set of available resources has sensible gaps in file size and resolution. These alternate versions are cached on the CDN and selected-from on the fly — all from a single URL.
For example, to deliver the sample
image filled to an aspect ratio of 16:9 and then automatically scaled to the width available for the image in the responsive layout, and with a DPR value suitable for the user's device:
cl_image_tag("sample.jpg", :client_hints=>true, :transformation=>[ {:aspect_ratio=>"16:9", :crop=>"fill"}, {:width=>"auto", :dpr=>"auto", :crop=>"scale"} ])
cl_image_tag("sample.jpg", array("client_hints"=>true, "transformation"=>array( array("aspect_ratio"=>"16:9", "crop"=>"fill"), array("width"=>"auto", "dpr"=>"auto", "crop"=>"scale") )))
CloudinaryImage("sample.jpg").image(client_hints=True, transformation=[ {"aspect_ratio": "16:9", "crop": "fill"}, {"width": "auto", "dpr": "auto", "crop": "scale"} ])
cloudinary.image("sample.jpg", {client_hints: true, transformation: [ {aspect_ratio: "16:9", crop: "fill"}, {width: "auto", dpr: "auto", crop: "scale"} ]})
cloudinary.url().transformation(new Transformation() .aspectRatio("16:9").crop("fill").chain() .width("auto").dpr("auto").crop("scale")).clientHints(true).imageTag("sample.jpg")
$.cloudinary.image("sample.jpg", {client_hints: true, transformation: [ {aspect_ratio: "16:9", crop: "fill"}, {width: "auto", dpr: "auto", crop: "scale"} ]})
cloudinary.Api.UrlImgUp.Transform(new Transformation() .AspectRatio("16:9").Crop("fill").Chain() .Width("auto").Dpr("auto").Crop("scale")).ClientHints(true).BuildImageTag("sample.jpg")
Cloudinary automatically adapts the image to fit the viewport, layout and resolution on any device, ensuring a visually-seamless user experience while improving performance:
- Automatically deliver images matching the DPR setting of the user's device, rounded up to the nearest integer.
- Automatically scale the image to match the width available for the image in the responsive layout, rounded up to the closest multiple of 100 pixels (by default).
- Automatically scale the image to match the width available for the image in the responsive layout using optimal responsive breakpoints
Note with regards to the JavaScript responsive images solution:
Cloudinary has a JavaScript based solution that dynamically replaces dpr_auto
and w_auto
with the actual values on the client side based on the actual browser settings and window width. The new automatic features documented here allow you to simplify your code and perform the dynamic decisions on the server-side (CDN level) based on Client-Hints, but only for supported browsers. To ensure that Cloudinary uses the new Client-Hints solution, add the client_hints
boolean parameter (set to true) to the Cloudinary image_tag
helper methods.
Automatic pixel density detection
To deliver an image in a resolution that automatically matches the DPR (Device Pixel Ratio) setting of the user's device, set the dpr
transformation parameter to auto
(dpr_auto
in URLs). The device's DPR value is received at the CDN level and rounded up to the nearest integer in order to avoid creating extra derived images and consuming extra transformations (e.g., a DPR value of 1.5 will be rounded up to 2.0).
For example, to deliver the sample
image filled to a width of 300 pixels, a height of 200 pixels, and with a DPR value suitable for the user's device:
cl_image_tag("sample.jpg", :width=>300, :height=>200, :dpr=>"auto", :crop=>"fill")
cl_image_tag("sample.jpg", array("width"=>300, "height"=>200, "dpr"=>"auto", "crop"=>"fill"))
CloudinaryImage("sample.jpg").image(width=300, height=200, dpr="auto", crop="fill")
cloudinary.image("sample.jpg", {width: 300, height: 200, dpr: "auto", crop: "fill"})
cloudinary.url().transformation(new Transformation().width(300).height(200).dpr("auto").crop("fill")).imageTag("sample.jpg")
$.cloudinary.image("sample.jpg", {width: 300, height: 200, dpr: "auto", crop: "fill"})
cloudinary.Api.UrlImgUp.Transform(new Transformation().Width(300).Height(200).Dpr("auto").Crop("fill")).BuildImageTag("sample.jpg")
Notes:
- The CDN returns a
Vary
response header set toDPR
in order to allow the same URL to be cached differently for each DPR value. - If Client-Hints are not supported by the user's browser or if they are not available, a URL with
dpr_auto
will be treated asdpr_1.0
.
Automatic image width
(Note: For customers with a custom domain name or private CDN distribution: Contact us to setup this feature).
To deliver an image automatically scaled to a width that matches the width available for the image in the responsive layout, set the width
transformation parameter to auto
(w_auto
in URLs). The width of the image is received at the CDN level and then rounded up in order to avoid creating extra derived images and consuming too extra transformations. By default, the rounding up is made in steps of 100 pixels (e.g., 347 will be rounded up to 400 and w_auto
in this case will be treated as w_400
). To round up in steps of a different number of pixels, a numeric value can be appended to the auto
value, separated with a colon. For example, w_auto:50
means rounding up in steps of 50 pixels: 347 will be rounded up to 350 and w_auto:50
in this case will be treated as w_350
.
For example, to deliver the sample
image filled to an aspect ratio of 16:9 and then automatically scaled to the width available for the image in the responsive layout:
cl_image_tag("sample.jpg", :client_hints=>true, :transformation=>[ {:aspect_ratio=>"16:9", :crop=>"fill"}, {:width=>"auto", :crop=>"scale"} ])
cl_image_tag("sample.jpg", array("client_hints"=>true, "transformation"=>array( array("aspect_ratio"=>"16:9", "crop"=>"fill"), array("width"=>"auto", "crop"=>"scale") )))
CloudinaryImage("sample.jpg").image(client_hints=True, transformation=[ {"aspect_ratio": "16:9", "crop": "fill"}, {"width": "auto", "crop": "scale"} ])
cloudinary.image("sample.jpg", {client_hints: true, transformation: [ {aspect_ratio: "16:9", crop: "fill"}, {width: "auto", crop: "scale"} ]})
cloudinary.url().transformation(new Transformation() .aspectRatio("16:9").crop("fill").chain() .width("auto").crop("scale")).clientHints(true).imageTag("sample.jpg")
$.cloudinary.image("sample.jpg", {client_hints: true, transformation: [ {aspect_ratio: "16:9", crop: "fill"}, {width: "auto", crop: "scale"} ]})
cloudinary.Api.UrlImgUp.Transform(new Transformation() .AspectRatio("16:9").Crop("fill").Chain() .Width("auto").Crop("scale")).ClientHints(true).BuildImageTag("sample.jpg")
In order to avoid delivering large images, no matter what the width available for the image, a limit transformation can be chained with the w_auto transformation. For example, to deliver the sample
image filled to an aspect ratio of 16:9 and then automatically scaled to the width available for the image in the responsive layout (up to a maximum width of 1000 pixels):
cl_image_tag("sample.jpg", :client_hints=>true, :transformation=>[ {:aspect_ratio=>"16:9", :crop=>"fill"}, {:width=>"auto", :crop=>"scale"}, {:width=>1000, :crop=>"limit"} ])
cl_image_tag("sample.jpg", array("client_hints"=>true, "transformation"=>array( array("aspect_ratio"=>"16:9", "crop"=>"fill"), array("width"=>"auto", "crop"=>"scale"), array("width"=>1000, "crop"=>"limit") )))
CloudinaryImage("sample.jpg").image(client_hints=True, transformation=[ {"aspect_ratio": "16:9", "crop": "fill"}, {"width": "auto", "crop": "scale"}, {"width": 1000, "crop": "limit"} ])
cloudinary.image("sample.jpg", {client_hints: true, transformation: [ {aspect_ratio: "16:9", crop: "fill"}, {width: "auto", crop: "scale"}, {width: 1000, crop: "limit"} ]})
cloudinary.url().transformation(new Transformation() .aspectRatio("16:9").crop("fill").chain() .width("auto").crop("scale").chain() .width(1000).crop("limit")).clientHints(true).imageTag("sample.jpg")
$.cloudinary.image("sample.jpg", {client_hints: true, transformation: [ {aspect_ratio: "16:9", crop: "fill"}, {width: "auto", crop: "scale"}, {width: 1000, crop: "limit"} ]})
cloudinary.Api.UrlImgUp.Transform(new Transformation() .AspectRatio("16:9").Crop("fill").Chain() .Width("auto").Crop("scale").Chain() .Width(1000).Crop("limit")).ClientHints(true).BuildImageTag("sample.jpg")
Notes:
- The CDN returns a
Vary
response header set toWidth, DPR
in order to allow the same URL to be cached differently for each Width and DPR value. - If Client-Hints are not supported by the user's browser or if they are not available, by default
w_auto
will be treated as if no scaling is requested. This might mean delivering the original hi-res image dimensions: it is equivalent to omitting the width parameter altogether. You can bypass this default behavior by specifying a default (fallback) value for the width that is only used if the information cannot be retrieved from a Client-Hints header. This default width value can be concatenated to the transformation value: e.g.,w_auto:40:360
means to round up in steps of 40 pixels, based on a width of 360 pixels if the actual available width cannot be retrieved from a Client-Hints header.
Strict transformations and signed URLs
To support strict transformations and signed URLs, the explicit pixels step value needs to be specified and included in the signed value of the width parameter. e.g., w_auto:100
. The CDN layer will send the original requested path (e.g., /w_auto:100/sample.jpg
) together with the actual required rounded up width (e.g., w_400
). Cloudinary's service will validate the signature according to original requested width rather than according to the actual required image width (e.g., w_auto:100
instead of w_400
).
Automatic image width using optimal responsive breakpoints
(Note: This feature is currently being rolled out and requires a private CDN distribution or CNAME, which is available for Cloudinary's Advanced plan and above. Contact us to setup this feature.)
The automatic width feature can be further enhanced by using Cloudinary's intelligent responsive breakpoints generation. Instead of rounding up the width value in constant steps (e.g., 100 pixels), Cloudinary selects image-specific breakpoints by determining the required number of versions of every image in order to balance the optimal dimensions vs. bandwidth reduction trade-off. To automatically determine the optimal width values of each image individually set the width
transformation parameter to auto:breakpoints
(w_auto:breakpoints
in URLs). Cloudinary performs the breakpoints calculation and rounds up the required image width to the closest optimal breakpoint.
For example, to deliver the bike
image filled to an aspect ratio of 16:9 and then automatically scaled to the closest optimal breakpoint that is larger than the width available for the image in the responsive layout, where the optimal breakpoints are calculated using the default breakpoint request values:
cl_image_tag("bike.jpg", :use_root_path=>true, :client_hints=>true, :transformation=>[ {:aspect_ratio=>"16:9", :crop=>"fill"}, {:width=>"auto:breakpoints", :crop=>"scale"} ])
cl_image_tag("bike.jpg", array("use_root_path"=>true, "client_hints"=>true, "transformation"=>array( array("aspect_ratio"=>"16:9", "crop"=>"fill"), array("width"=>"auto:breakpoints", "crop"=>"scale") )))
CloudinaryImage("bike.jpg").image(use_root_path=True, client_hints=True, transformation=[ {"aspect_ratio": "16:9", "crop": "fill"}, {"width": "auto:breakpoints", "crop": "scale"} ])
cloudinary.image("bike.jpg", {use_root_path: true, client_hints: true, transformation: [ {aspect_ratio: "16:9", crop: "fill"}, {width: "auto:breakpoints", crop: "scale"} ]})
cloudinary.url().transformation(new Transformation() .aspectRatio("16:9").crop("fill").chain() .width("auto:breakpoints").crop("scale")).clientHints(true).useRootPath(true).imageTag("bike.jpg")
$.cloudinary.image("bike.jpg", {use_root_path: true, client_hints: true, transformation: [ {aspect_ratio: "16:9", crop: "fill"}, {width: "auto:breakpoints", crop: "scale"} ]})
cloudinary.Api.UrlImgUp.Transform(new Transformation() .AspectRatio("16:9").Crop("fill").Chain() .Width("auto:breakpoints").Crop("scale")).ClientHints(true).UseRootPath(true).BuildImageTag("bike.jpg")
Assuming (for the example above) that the Client-Hints Width request header returns 347, and the calculated optimal breakpoints of a 16:9 aspect ratio cropped version of the bike
image are as follows: 50, 238, 356, 450, 542, 621, 692, 764, 834, 901, 955, 1000.
Then the selected width will be 356 pixels (the first breakpoint bigger than 347), so the URL will be treated as ar_16:9,c_fill/c_scale,w_356
.
Breakpoints generation settings:
- Global breakpoints settings are applied with their default values as follows:
min_width=50
,max_width=1000
,bytes_step=20KB
,max_images=20
. For more information on these settings and possible values, see the responsive breakpoint request settings documentation. - The default settings can be overridden using a dynamic URL that includes the new values:
auto:breakpoints_[min_width]_[max_width]_[bytes_step_in_KBs]_[max_images]
e.g.,w_auto:breakpoints_200_1920_30_15
. - All the breakpoint request settings parameters must be included if you need to override any of them.
For example, to deliver the bike
image filled to an aspect ratio of 16:9 and then automatically scaled to the closest optimal breakpoint that is larger than the width available for the image in the responsive layout, where the optimal breakpoints are calculated using the following breakpoint request values - min_width=200
, max_width=1920
, bytes_step=30
, max_images=15
:
cl_image_tag("bike.jpg", :use_root_path=>true, :client_hints=>true, :transformation=>[ {:aspect_ratio=>"16:9", :crop=>"fill"}, {:width=>"auto:breakpoints_200_1920_30_15", :crop=>"scale"} ])
cl_image_tag("bike.jpg", array("use_root_path"=>true, "client_hints"=>true, "transformation"=>array( array("aspect_ratio"=>"16:9", "crop"=>"fill"), array("width"=>"auto:breakpoints_200_1920_30_15", "crop"=>"scale") )))
CloudinaryImage("bike.jpg").image(use_root_path=True, client_hints=True, transformation=[ {"aspect_ratio": "16:9", "crop": "fill"}, {"width": "auto:breakpoints_200_1920_30_15", "crop": "scale"} ])
cloudinary.image("bike.jpg", {use_root_path: true, client_hints: true, transformation: [ {aspect_ratio: "16:9", crop: "fill"}, {width: "auto:breakpoints_200_1920_30_15", crop: "scale"} ]})
cloudinary.url().transformation(new Transformation() .aspectRatio("16:9").crop("fill").chain() .width("auto:breakpoints_200_1920_30_15").crop("scale")).clientHints(true).useRootPath(true).imageTag("bike.jpg")
$.cloudinary.image("bike.jpg", {use_root_path: true, client_hints: true, transformation: [ {aspect_ratio: "16:9", crop: "fill"}, {width: "auto:breakpoints_200_1920_30_15", crop: "scale"} ]})
cloudinary.Api.UrlImgUp.Transform(new Transformation() .AspectRatio("16:9").Crop("fill").Chain() .Width("auto:breakpoints_200_1920_30_15").Crop("scale")).ClientHints(true).UseRootPath(true).BuildImageTag("bike.jpg")
Note: If Client-Hints are not supported by the user's browser or if they are not available, by default w_auto:breakpoints
will be treated as if no scaling is requested. This might mean delivering the original hi-res image dimensions: it is equivalent to omitting the width parameter altogether. You can bypass this default behavior by specifying a default value for the width that is only used if the information cannot be retrieved from a Client-Hints header. This default width value can be concatenated to the transformation value: e.g., w_auto:breakpoints:500
means to scale the image to the closest calculated breakpoint, based on a width of 500 pixels if the actual available width cannot be retrieved from a Client-Hints header.
Breakpoints generation delivery URL
Dynamic applications (e.g., Javascript based) can leverage the calculated breakpoints by accessing the breakpoints generation URLs directly. To return a JSON response with the generated breakpoints, set the width
transformation parameter to auto:breakpoints:json
. The breakpoints' JSON URLs are regular derived resources and are cached at the CDN layer like any derived image or file.
For example, to return the generated breakpoints for the bike
image filled to an aspect ratio of 16:9:
cl_image_tag("bike.jpg", :use_root_path=>true, :client_hints=>true, :transformation=>[ {:aspect_ratio=>"16:9", :crop=>"fill"}, {:width=>"auto:breakpoints:json", :crop=>"scale"} ])
cl_image_tag("bike.jpg", array("use_root_path"=>true, "client_hints"=>true, "transformation"=>array( array("aspect_ratio"=>"16:9", "crop"=>"fill"), array("width"=>"auto:breakpoints:json", "crop"=>"scale") )))
CloudinaryImage("bike.jpg").image(use_root_path=True, client_hints=True, transformation=[ {"aspect_ratio": "16:9", "crop": "fill"}, {"width": "auto:breakpoints:json", "crop": "scale"} ])
cloudinary.image("bike.jpg", {use_root_path: true, client_hints: true, transformation: [ {aspect_ratio: "16:9", crop: "fill"}, {width: "auto:breakpoints:json", crop: "scale"} ]})
cloudinary.url().transformation(new Transformation() .aspectRatio("16:9").crop("fill").chain() .width("auto:breakpoints:json").crop("scale")).clientHints(true).useRootPath(true).imageTag("bike.jpg")
$.cloudinary.image("bike.jpg", {use_root_path: true, client_hints: true, transformation: [ {aspect_ratio: "16:9", crop: "fill"}, {width: "auto:breakpoints:json", crop: "scale"} ]})
cloudinary.Api.UrlImgUp.Transform(new Transformation() .AspectRatio("16:9").Crop("fill").Chain() .Width("auto:breakpoints:json").Crop("scale")).ClientHints(true).UseRootPath(true).BuildImageTag("bike.jpg")
Returned JSON example:
{"breakpoints":[50,238,356,450,542,621,692,764,834,901,955,1000]}
Fetching images from remote locations
Most of the examples on this page discussed how you can show and manipulate images uploaded to Cloudinary, but you can also manipulate the following images:
- Images that already exist elsewhere online using the Auto Upload and Fetch features, given their public HTTP, HTTPS or FTP URLs.
- Profile photos on social networks (e.g., FB, Twitter, Google+, Instagram) given their identifiers.
- Thumbnails of videos on public video sites (e.g., YouTube).
Auto upload and fetch
Auto Upload and Fetch are two similar features for automatically fetching (retrieving) images from existing remote locations using dynamic URLs. The images are delivered through a powerful CDN network, greatly improving your users’ browsing experience, reducing load on your servers and lowering hosting costs, while you also benefit from on-the-fly image transformation and optimization, and all of this with minimum changes on your side.
- Fetch enables on-the-fly transformation of existing remote images and optimized delivery via a CDN. Fetched images are cached on your Cloudinary account for performance reasons.
- Auto Upload also enables on-the-fly transformation of existing remote images and optimized delivery via a CDN, while simultaneously uploading the image to your Cloudinary account for further management, and thus benefiting from a variety of additional features (just like any other image uploaded to your Cloudinary account).
To create a Fetch URL, simply prepend the following prefix to the URL of the image:
http://res.cloudinary.com/<cloud_name>/image/fetch/
For example, to fetch the following image from Wikimedia:
http://upload.wikimedia.org/wikipedia/commons/4/46/Jennifer_Lawrence_at_the_83rd_Academy_Awards.jpg
Access the following Cloudinary fetch URL (this example uses Cloudinary's demo account):
cl_image_tag("http://upload.wikimedia.org/wikipedia/commons/4/46/Jennifer_Lawrence_at_the_83rd_Academy_Awards.jpg", :type=>"fetch")
cl_image_tag("http://upload.wikimedia.org/wikipedia/commons/4/46/Jennifer_Lawrence_at_the_83rd_Academy_Awards.jpg", array("type"=>"fetch"))
CloudinaryImage("http://upload.wikimedia.org/wikipedia/commons/4/46/Jennifer_Lawrence_at_the_83rd_Academy_Awards.jpg").image(type="fetch")
cloudinary.image("http://upload.wikimedia.org/wikipedia/commons/4/46/Jennifer_Lawrence_at_the_83rd_Academy_Awards.jpg", {type: "fetch"})
cloudinary.url().type("fetch").imageTag("http://upload.wikimedia.org/wikipedia/commons/4/46/Jennifer_Lawrence_at_the_83rd_Academy_Awards.jpg")
$.cloudinary.image("http://upload.wikimedia.org/wikipedia/commons/4/46/Jennifer_Lawrence_at_the_83rd_Academy_Awards.jpg", {type: "fetch"})
cloudinary.Api.UrlImgUp.Type("fetch").BuildImageTag("http://upload.wikimedia.org/wikipedia/commons/4/46/Jennifer_Lawrence_at_the_83rd_Academy_Awards.jpg")
You can also fetch remote images and deliver them after applying any of Cloudinary’s image transformations. Simply add the transformation parameters to the URL directly after the Fetch prefix and before the URL of the image. For example, the same remote image of Jennifer Lawrence delivered as a 150x150 face detection based thumbnail with rounded corners:
cl_image_tag("http://upload.wikimedia.org/wikipedia/commons/4/46/Jennifer_Lawrence_at_the_83rd_Academy_Awards.jpg", :width=>150, :height=>150, :gravity=>"face", :radius=>20, :crop=>"thumb", :type=>"fetch")
cl_image_tag("http://upload.wikimedia.org/wikipedia/commons/4/46/Jennifer_Lawrence_at_the_83rd_Academy_Awards.jpg", array("width"=>150, "height"=>150, "gravity"=>"face", "radius"=>20, "crop"=>"thumb", "type"=>"fetch"))
CloudinaryImage("http://upload.wikimedia.org/wikipedia/commons/4/46/Jennifer_Lawrence_at_the_83rd_Academy_Awards.jpg").image(width=150, height=150, gravity="face", radius=20, crop="thumb", type="fetch")
cloudinary.image("http://upload.wikimedia.org/wikipedia/commons/4/46/Jennifer_Lawrence_at_the_83rd_Academy_Awards.jpg", {width: 150, height: 150, gravity: "face", radius: 20, crop: "thumb", type: "fetch"})
cloudinary.url().transformation(new Transformation().width(150).height(150).gravity("face").radius(20).crop("thumb")).type("fetch").imageTag("http://upload.wikimedia.org/wikipedia/commons/4/46/Jennifer_Lawrence_at_the_83rd_Academy_Awards.jpg")
$.cloudinary.image("http://upload.wikimedia.org/wikipedia/commons/4/46/Jennifer_Lawrence_at_the_83rd_Academy_Awards.jpg", {width: 150, height: 150, gravity: "face", radius: 20, crop: "thumb", type: "fetch"})
cloudinary.Api.UrlImgUp.Transform(new Transformation().Width(150).Height(150).Gravity("face").Radius(20).Crop("thumb")).Type("fetch").BuildImageTag("http://upload.wikimedia.org/wikipedia/commons/4/46/Jennifer_Lawrence_at_the_83rd_Academy_Awards.jpg")
The Auto Upload feature is implemented by mapping a base remote URL to a specified folder in your Cloudinary account. Then, whenever accessing a Cloudinary delivery URL containing the folder prefix, any resources are automatically retrieved from the mapped URL if they are not already uploaded to the folder.
For example: Creating a folder called remote_media
and then mapping it to the URL prefix http://upload.wikimedia.org/wikipedia/
allows you to generate a Cloudinary delivery URL that substitutes the remote_media
folder prefix for the URL prefix. When the Cloudinary delivery URL is accessed for the first time, Cloudinary automatically retrieves the remote image from http://upload.wikimedia.org/wikipedia/ and stores it in your Cloudinary account.
To retrieve the following image from Wikimedia, and automatically upload it to your Cloudinary account:
http://upload.wikimedia.org/wikipedia/commons/2/29/Marcelo_Facini.jpg
Access the following Cloudinary URL:
cl_image_tag("remote_media/commons/2/29/Marcelo_Facini.jpg")
cl_image_tag("remote_media/commons/2/29/Marcelo_Facini.jpg")
CloudinaryImage("remote_media/commons/2/29/Marcelo_Facini.jpg").image()
cloudinary.image("remote_media/commons/2/29/Marcelo_Facini.jpg")
cloudinary.url().imageTag("remote_media/commons/2/29/Marcelo_Facini.jpg")
$.cloudinary.image("remote_media/commons/2/29/Marcelo_Facini.jpg")
cloudinary.Api.UrlImgUp.BuildImageTag("remote_media/commons/2/29/Marcelo_Facini.jpg")
The image is dynamically retrieved the first time this URL is accessed and stored in your Cloudinary account with a public ID of remote_media/commons/2/29/Marcelo_Facini
.
For more information, see the detailed documentation on Fetching remote images.
Profile photos on social networks
You can easily display images from social networks by referencing the unique identifier used on their site. The cloudinary image delivery URL becomes:
http://res.cloudinary.com/<cloud name>/image/<social type>/<social identifier>.<format file extension>
Where:
cloud name
- the name of your Cloudinary account, a unique public identifier for URL building and API access.social type
- the social network identifiersocial identifier
- the unique identifier of the resource on the social network.format file extension
- (optional) the requested delivery format of the image.
The profile picture can be resized and manipulated like any other image uploaded to Cloudinary. Cloudinary supports profile picture fetching from the following social networks:
Access the Facebook profile picture based on the Facebook unique user ID (social type = 'facebook'). Example for Bill Clinton whose ID is 65646572251
, scaled to a circular thumbnail with a width of 150 pixels:
cl_image_tag("65646572251.jpg", :width=>150, :radius=>"max", :type=>"facebook")
cl_image_tag("65646572251.jpg", array("width"=>150, "radius"=>"max", "type"=>"facebook"))
CloudinaryImage("65646572251.jpg").image(width=150, radius="max", type="facebook")
cloudinary.image("65646572251.jpg", {width: 150, radius: "max", type: "facebook"})
cloudinary.url().transformation(new Transformation().width(150).radius("max")).type("facebook").imageTag("65646572251.jpg")
$.cloudinary.image("65646572251.jpg", {width: 150, radius: "max", type: "facebook"})
cloudinary.Api.UrlImgUp.Transform(new Transformation().Width(150).Radius("max")).Type("facebook").BuildImageTag("65646572251.jpg")
Access the Twitter profile picture based on the unique Twitter User ID (type = 'twitter') or Twitter Screen Name (social type = 'twitter_name'). Example for Bill Clinton whose ID is 18913373
, scaled to a width of 150 pixels with a sepia effect applied:
cl_image_tag("18913373.jpg", :width=>150, :effect=>"sepia", :type=>"twitter")
cl_image_tag("18913373.jpg", array("width"=>150, "effect"=>"sepia", "type"=>"twitter"))
CloudinaryImage("18913373.jpg").image(width=150, effect="sepia", type="twitter")
cloudinary.image("18913373.jpg", {width: 150, effect: "sepia", type: "twitter"})
cloudinary.url().transformation(new Transformation().width(150).effect("sepia")).type("twitter").imageTag("18913373.jpg")
$.cloudinary.image("18913373.jpg", {width: 150, effect: "sepia", type: "twitter"})
cloudinary.Api.UrlImgUp.Transform(new Transformation().Width(150).Effect("sepia")).Type("twitter").BuildImageTag("18913373.jpg")
Google+
Access the Google+ profile picture based on the users unique numeric ID (social type = 'gplus'). Example for Larry Page whose ID is 106189723444098348646
, scaled to a width of 150 pixels with rounded corners and a 10px grey border:
cl_image_tag("106189723444098348646.jpg", :width=>150, :radius=>30, :border=>"10px_solid_grey", :type=>"gplus")
cl_image_tag("106189723444098348646.jpg", array("width"=>150, "radius"=>30, "border"=>"10px_solid_grey", "type"=>"gplus"))
CloudinaryImage("106189723444098348646.jpg").image(width=150, radius=30, border="10px_solid_grey", type="gplus")
cloudinary.image("106189723444098348646.jpg", {width: 150, radius: 30, border: "10px_solid_grey", type: "gplus"})
cloudinary.url().transformation(new Transformation().width(150).radius(30).border("10px_solid_grey")).type("gplus").imageTag("106189723444098348646.jpg")
$.cloudinary.image("106189723444098348646.jpg", {width: 150, radius: 30, border: "10px_solid_grey", type: "gplus"})
cloudinary.Api.UrlImgUp.Transform(new Transformation().Width(150).Radius(30).Border("10px_solid_grey")).Type("gplus").BuildImageTag("106189723444098348646.jpg")
Access the Instagram profile picture based on the users account name (social type = 'instagram_name'). Example for angelinajolieofficial
, with a 3px black border and text overlay of 'Angelina' placed 20 pixels from the bottom of the image:
cl_image_tag("angelinajolieofficial.jpg", :type=>"instagram_name", :transformation=>[ {:overlay=>"text:roboto_25_bold:Angelina", :gravity=>"south", :y=>20}, {:border=>"3px_solid_black"} ])
cl_image_tag("angelinajolieofficial.jpg", array("type"=>"instagram_name", "transformation"=>array( array("overlay"=>"text:roboto_25_bold:Angelina", "gravity"=>"south", "y"=>20), array("border"=>"3px_solid_black") )))
CloudinaryImage("angelinajolieofficial.jpg").image(type="instagram_name", transformation=[ {"overlay": "text:roboto_25_bold:Angelina", "gravity": "south", "y": 20}, {"border": "3px_solid_black"} ])
cloudinary.image("angelinajolieofficial.jpg", {type: "instagram_name", transformation: [ {overlay: "text:roboto_25_bold:Angelina", gravity: "south", y: 20}, {border: "3px_solid_black"} ]})
cloudinary.url().transformation(new Transformation() .overlay("text:roboto_25_bold:Angelina").gravity("south").y(20).chain() .border("3px_solid_black")).type("instagram_name").imageTag("angelinajolieofficial.jpg")
$.cloudinary.image("angelinajolieofficial.jpg", {type: "instagram_name", transformation: [ {overlay: "text:roboto_25_bold:Angelina", gravity: "south", y: 20}, {border: "3px_solid_black"} ]})
cloudinary.Api.UrlImgUp.Transform(new Transformation() .Overlay("text:roboto_25_bold:Angelina").Gravity("south").Y(20).Chain() .Border("3px_solid_black")).Type("instagram_name").BuildImageTag("angelinajolieofficial.jpg")
Gravatar
Access the Gravatar profile picture based on the user's email address (social type = 'gravatar') which is encoded with MD5 hash for better privacy. Example for info@cloudinary.com
(MD5 hash: e3264cf16f34ecd3c7c564f5668cbc1e), scaled to 150 pixels wide and rotated 45 degrees clockwise:
cl_image_tag("e3264cf16f34ecd3c7c564f5668cbc1e.jpg", :width=>150, :angle=>45, :type=>"gravatar")
cl_image_tag("e3264cf16f34ecd3c7c564f5668cbc1e.jpg", array("width"=>150, "angle"=>45, "type"=>"gravatar"))
CloudinaryImage("e3264cf16f34ecd3c7c564f5668cbc1e.jpg").image(width=150, angle=45, type="gravatar")
cloudinary.image("e3264cf16f34ecd3c7c564f5668cbc1e.jpg", {width: 150, angle: 45, type: "gravatar"})
cloudinary.url().transformation(new Transformation().width(150).angle(45)).type("gravatar").imageTag("e3264cf16f34ecd3c7c564f5668cbc1e.jpg")
$.cloudinary.image("e3264cf16f34ecd3c7c564f5668cbc1e.jpg", {width: 150, angle: 45, type: "gravatar"})
cloudinary.Api.UrlImgUp.Transform(new Transformation().Width(150).Angle(45)).Type("gravatar").BuildImageTag("e3264cf16f34ecd3c7c564f5668cbc1e.jpg")
Thumbnails of public videos
You can easily display thumbnail images to videos on various video sites by referencing the unique video identifier used on their site. The cloudinary image delivery URL becomes:
http://res.cloudinary.com/<cloud name>/image/<type>/<identifier>.<format file extension>
Where:
cloud name
- the name of your Cloudinary account, a unique public identifier for URL building and API access.type
- the video website identifier (youtube, hulu, vimeo, animoto, worldstarhiphop or dailymotion)public ID
- the unique identifier of the resource or the full URL of the video.format file extension
- the requested delivery format of the image.
For example, to display the thumbnail of the following YouTube video: http://www.youtube.com/watch?v=o-urnlaJpOA
, add the video ID to the URL ('o-urnlaJpOA' in this example):
cl_image_tag("o-urnlaJpOA.jpg", :type=>"youtube")
cl_image_tag("o-urnlaJpOA.jpg", array("type"=>"youtube"))
CloudinaryImage("o-urnlaJpOA.jpg").image(type="youtube")
cloudinary.image("o-urnlaJpOA.jpg", {type: "youtube"})
cloudinary.url().type("youtube").imageTag("o-urnlaJpOA.jpg")
$.cloudinary.image("o-urnlaJpOA.jpg", {type: "youtube"})
cloudinary.Api.UrlImgUp.Type("youtube").BuildImageTag("o-urnlaJpOA.jpg")
The thumbnail can be resized and manipulated like any other image uploaded to Cloudinary. For example, to scale the image to a width of 500 pixels with a 5px black border:
cl_image_tag("o-urnlaJpOA.jpg", :width=>500, :border=>"5px_solid_black", :type=>"youtube")
cl_image_tag("o-urnlaJpOA.jpg", array("width"=>500, "border"=>"5px_solid_black", "type"=>"youtube"))
CloudinaryImage("o-urnlaJpOA.jpg").image(width=500, border="5px_solid_black", type="youtube")
cloudinary.image("o-urnlaJpOA.jpg", {width: 500, border: "5px_solid_black", type: "youtube"})
cloudinary.url().transformation(new Transformation().width(500).border("5px_solid_black")).type("youtube").imageTag("o-urnlaJpOA.jpg")
$.cloudinary.image("o-urnlaJpOA.jpg", {width: 500, border: "5px_solid_black", type: "youtube"})
cloudinary.Api.UrlImgUp.Transform(new Transformation().Width(500).Border("5px_solid_black")).Type("youtube").BuildImageTag("o-urnlaJpOA.jpg")
You can also pass the full URL of the video instead of just its identifier. The following example delivers a thumbnail of a YouTube video based on a full video URL (http://www.youtube.com/watch?v=aNwnPElsJGE
). Note that if the URL includes special characters, they should be escaped (e.g., '%3F' instead of '?'). If you use our client library helper methods then the escaping is done for you automatically.
cl_image_tag("http://www.youtube.com/watch?v=aNwnPElsJGE", :type=>"youtube")
cl_image_tag("http://www.youtube.com/watch?v=aNwnPElsJGE", array("type"=>"youtube"))
CloudinaryImage("http://www.youtube.com/watch?v=aNwnPElsJGE").image(type="youtube")
cloudinary.image("http://www.youtube.com/watch?v=aNwnPElsJGE", {type: "youtube"})
cloudinary.url().type("youtube").imageTag("http://www.youtube.com/watch?v=aNwnPElsJGE")
$.cloudinary.image("http://www.youtube.com/watch?v=aNwnPElsJGE", {type: "youtube"})
cloudinary.Api.UrlImgUp.Type("youtube").BuildImageTag("http://www.youtube.com/watch?v=aNwnPElsJGE")
See the article on Generating video thumbnails from YouTube and other video sites for more information.
Advanced URL delivery options
Cloudinary offers a variety of options for delivering your images. This section contains information on the following topics:
- Include image versions in the delivery URL
- Handle image delivery errors
- Generate a client-side list of resources with a specified tag
- Control access to your images
- Use private CDNs and CNAMEs
- Deliver images from multiple CDN sub-domains
- Create SEO friendly image URLs
- Use a default image placeholder
Image versions
By default, Cloudinary assigns a randomly generated unique public ID to each uploaded image. Alternatively, you can either define your own custom public ID or one based on the original file name of the uploaded image. If you upload an image with a public ID that already exists, the file will be overwritten. Keep in mind though that the CDN may already contain a previously cached copy of the older image.
To force the CDN to display the latest uploaded image, you can add a version component to Cloudinary's URLs. The version value is returned by Cloudinary as part of the response of the image upload, and represents the timestamp of the upload. Adding the version component to URLs can be done by setting the version
parameter (v
in URLs), for example:
http://res.cloudinary.com/demo/image/upload/v1312461204/sample.jpg
As an alternative to using versions, you can set the invalidate
parameter to true
while uploading a new image in order to invalidate the previous image throughout the CDN. Note that it usually takes a few minutes (although it might take up to an hour) for the invalidation to fully propagate through the CDN, while the version
component takes effect immediately.
Note: There are also a number of other important considerations when using the invalidate functionality. For example, if there is no version number in a URL that includes a folder structure, then by default, those URLs are not invalidated. For details on invalidating images, see Invalidating cached images on the CDN.
Error handling
If you have a problem when accessing a Cloudinary transformation URL (e.g., a blank result in your browser), it might be a simple matter of using the wrong transformation syntax. To understand more, check the X-Cld-Error HTTP response header which is where Cloudinary reports any errors it encounters (e.g., invalid syntax, invalid parameters, limit issues, etc.).
For example, trying to access the following URL would result in a X-Cld-Error: Invalid width - abc
error, as the width parameter is used with an integer value and not a string:
http://res.cloudinary.com/demo/image/upload/w_abc/sample.jpg
To view the X-Cld-Error header on a Chrome browser for example, select Developers Tools from the View menu. Then select the Network tab, refresh your page, click on the image name with the 400 status code and look for X-Cld-Error under Response Headers.
Client-side resource lists
You can use a list
delivery type to generate a list of resources with a specified tag. URL syntax:
http://res.cloudinary.com/<your_cloud_name>/<resource_type>/list/<tag>.json
The response is a JSON snippet listing all the resources of the specified resource type and the specified tag. For example, the request below generates a JSON list of all image resources in the demo project with the tag logo
.
cl_image_tag("logo.json", :type=>"list")
cl_image_tag("logo.json", array("type"=>"list"))
CloudinaryImage("logo.json").image(type="list")
cloudinary.image("logo.json", {type: "list"})
cloudinary.url().type("list").imageTag("logo.json")
$.cloudinary.image("logo.json", {type: "list"})
cloudinary.Api.UrlImgUp.Type("list").BuildImageTag("logo.json")
JSON response:
{"resources":
[{"public_id":"amazon_logo","version":1315740184,"format":"png","width":162,"height":38,"type":"upload","created_at":"2011-09-11T11:23:04Z"},
{"public_id":"microsoft_logo","version":1315740090,"format":"png","width":216,"height":70,"type":"upload","created_at":"2011-09-11T11:21:30Z"},
{"public_id":"apple_logo","version":1315740074,"format":"jpg","width":206,"height":250,"type":"upload","created_at":"2011-09-11T11:21:14Z","context":{"custom":{"Main":"true"}}},
{"public_id":"google_logo","version":1315740052,"format":"png","width":275,"height":95,"type":"upload","created_at":"2011-09-11T11:20:52Z","context":{"custom":{"caption":"Google Logo"}}}],"updated_at":"2015-09-10T17:04:32Z"}
Notes:
- By default, the
list
delivery type is restricted. To enable it, open theSecurity
settings in your Management console, and clear the checkmark from theResource list
item underRestricted image types
. You may want to clear this option only temporarily, as needed. Alternatively, you can bypass this (and any) delivery type restriction using a signed URL. - This option supports listing up to 1000 resources. To view more than 1000, use the resources_by_tag property of the Admin API, and include the
next_cursor
parameter to view long lists. - The JSON response is cached on the CDN for one minute, and the file is invalidated if changes in your stored resources make the current response invalid.
Control access to images
When uploading images to Cloudinary, both the original images and their transformed versions are publicly available through a CDN, by default. You can use random Public IDs to make it harder to guess image URLs, but you might still want further access control by:
- Enabling strict transformations.
- Using signed delivery URLs
- Uploading images as private.
- Uploading images as authenticated.
Strict transformations
Cloudinary's manipulation URLs are dynamic, which means that if the requested transformed image does not already exist, then it is created on-the-fly. This is a powerful feature, but you may not want your end users to play with these options on your images. To control this, you can enable Strict Transformations on your account to prevent transformations from being dynamically applied to images. Except for any transformations that you specifically allow to be used dynamically, your users will be restricted to accessing only pre-generated transformed images (generated eagerly during upload or with an authenticated request to our API).
Enable the "Strict Transformations" setting in your Cloudinary management console's security settings page. To mark a specific transformation as allowed, either use the Admin API or open the Transformations tab of the Management Console. Next to each transformation is an icon that can be toggled to either allow or protect the transformation.
Trying to dynamically generate and deliver an allowed transformation will work:
cl_image_tag("sheep.jpg", :height=>200, :width=>300, :radius=>20, :crop=>"fill")
cl_image_tag("sheep.jpg", array("height"=>200, "width"=>300, "radius"=>20, "crop"=>"fill"))
CloudinaryImage("sheep.jpg").image(height=200, width=300, radius=20, crop="fill")
cloudinary.image("sheep.jpg", {height: 200, width: 300, radius: 20, crop: "fill"})
cloudinary.url().transformation(new Transformation().height(200).width(300).radius(20).crop("fill")).imageTag("sheep.jpg")
$.cloudinary.image("sheep.jpg", {height: 200, width: 300, radius: 20, crop: "fill"})
cloudinary.Api.UrlImgUp.Transform(new Transformation().Height(200).Width(300).Radius(20).Crop("fill")).BuildImageTag("sheep.jpg")
Trying to access any other transformation, either disallowed or non-existing, will not succeed.
Note: The option to apply a transformation to an image on-the-fly is blocked only from the time that the strict transformations feature is enabled or from the time that a previously Allowed
transformation is changed to Disallowed
. Any derived image that was generated while a particular transformation was still allowed, remains accessible.
Signed delivery URLs
A signed Cloudinary image delivery URL is a dynamic URL that has its signature validated before making it available for view (see the article about on the fly image manipulations secured with signed urls for more details). Signed delivery URLs are generally used to:
- Deliver specific derived images when strict transformations are enabled.
- Apply add-on based manipulation directives that require signing the URL.
- Fetch images from specific URLs when "Fetched URLs" are restricted.
- Allow access to private/authenticated images.
A signed delivery URL contains a signature component of the format /s--SIGNATURE--/
. The signature is generated from the first 8 characters of a base64 encoding of a SHA1 digest of your image public ID and transformation string concatenated with your API secret. The signature is automatically generated by Cloudinary's client integration SDKs by adding the sign_url
boolean parameter to the helper method and setting it to true.
For example, to create an image tag for the authenticated image sample
cropped to a height and width of 300 pixels, while signing the transformation URL.
cl_image_tag("sample.jpg", :width=>300, :height=>300, :sign_url=>true, :type=>"authenticated")
cl_image_tag("sample.jpg", array("width"=>300, "height"=>300, "sign_url"=>true, "type"=>"authenticated"))
CloudinaryImage("sample.jpg").image(width=300, height=300, sign_url=True, type="authenticated")
cloudinary.image("sample.jpg", {width: 300, height: 300, sign_url: true, type: "authenticated"})
cloudinary.url().transformation(new Transformation().width(300).height(300)).signed(true).type("authenticated").imageTag("sample.jpg")
$.cloudinary.image("sample.jpg", {width: 300, height: 300, type: "authenticated"})
cloudinary.Api.UrlImgUp.Transform(new Transformation().Width(300).Height(300)).Signed(true).Type("authenticated").BuildImageTag("sample.jpg")
Once a derived image has been generated (whether dynamically on first access or eagerly during upload), the signature checking is skipped and the signature itself can be omitted (except for Authenticated images which always require a signature).
Private images
Images can be uploaded as private
to restrict access to the original image and only allow access to derived (transformed) versions of the image. The original image can be accessed only with a signed URL, but by default, all derived versions of the image are accessible. To deliver a transformation of an image uploaded as private, set the type
parameter in the delivery URL to private
(instead of the default upload
).
An image that was uploaded as �private’ cannot be accessed publicly without a signed URL. For example, the following delivery URL for the sample
image returns an error:
http://res.cloudinary.com/demo/image/private/sample.jpg
Delivering any derived versions of the image is still possible. For example, the sample
private image with a width of 300 pixels:
http://res.cloudinary.com/demo/image/private/w_300/sample.jpg
By default, all derived versions of the image are accessible, but access to the derived images can also be restricted by activating the Strict Transformations mode. This mode prevents access to derived versions of the image, except for those that have been specifically enabled (e.g., with watermarks) that are then available for public delivery to your users. With Strict Transformations enabled you need to either eagerly generate all derived images or mark specific dynamic transformations as allowed.
Providing time-limited access to private images
You can make a private original image temporarily accessible, for example, to enable a customer to access a stock photo on your site after she purchases it. To do this, you need to deliver a time-limited and signed URL. You can do this directly using the API or you can use the private_download_url
Utils method, which generates a time-limited, signed URL link to the original image, which you can then provide to relevant customers. For example:
Cloudinary::Utils.private_download_url('my_picID', 'jpg') php \Cloudinary\Uploader::rename('my_picID', 'new_name');
cloudinary.uploader.rename('my_picID', 'new_name')
cloudinary.v2.uploader.rename('my_picID', 'new_name', function(error, result) { console.log(result) })
cloudinary.uploader().rename("my_picID", "new_name", ObjectUtils.emptyMap());
curl https://api.cloudinary.com/v1_1/demo/image/private_download_url -X POST --data 'public_id]=my_picID&format=jpg×tamp=1346076992&api_key=824698761754661&signature=d994c2b972c30d84d33fde684aa377fc17878be6'
This generates a link similar to the following:
https://api.cloudinary.com/v1_1/private-demo/image/download?api_key=824698761754661&format=jpg&public_id=my_picID&signature=d994c2b972c30d84d33fde684aa377fc17878be6×tamp=1346076992
The generated URL delivers the image via a secure authenticated API request to Cloudinary each time. The image is not cached on the CDN.
Required parameters
public_id
- The identifier of the uploaded image.format
- The image file format.
Optional parameters:
resource_type
- The resource type (image
,video
orraw
) of the file to deliver. Default:image
.expires_at
- The date (UNIX time in seconds) for the URL expiration. Default: 1 hour from the time the URL is generated.attachment
- If true, the URL downloads the image as an attachment. Otherwise, the image is displayed. Default:false
.
Authenticated images
Images can be uploaded as authenticated
to even further restrict access to both the original image and to the derived (transformed) versions of the image. Authenticated images and their derived versions are accessible only via signed delivery URLs.
If an image was uploaded as �authenticated’, neither the image nor any of its derived images can be accessed publicly without a signed URL. For example, the following URL returns an error:
http://res.cloudinary.com/demo/image/authenticated/sample.jpg
A signed delivery URL is needed to deliver the sample
image:
http://res.cloudinary.com/demo/image/authenticated/s--kh4rZOVi--/sample.jpg
Note: The signed URLs use a constant signature based on your API secret and are not time limited. Implementing time limited access URLs requires a small setup on Cloudinary's side. Contact us at support@cloudinary.com for more details.
Private CDNs and CNAMEs
The general Cloudinary shared CDN distribution is http://res.cloudinary.com
and so image delivery URLs follow the format as described above:
http://res.cloudinary.com/<cloud_name>/image/upload/<public ID>.<extension>
If you use a private CDN distribution configuration, the image delivery URLs follow the format:
http://<cloud_name>-res.cloudinary.com/image/upload/<public ID>.<extension>
For example:
http://demo-res.cloudinary.com/image/upload/sample.jpg
For customers with a Custom Domain Name (CNAME), the image delivery URL becomes:
http://<custom domain name>/image/upload/<public ID>.<extension>
For example:
http://www.example.com/image/upload/sample.jpg
Note: CNAMEs and private CDN distributions are available for Cloudinary's Advanced plan and above, and require a small setup on Cloudinary's side. An HTTPS-enabled CNAME also entails an additional cost. Contact us at support@cloudinary.com for more details.
Multiple CDN sub-domains
Browsers currently limit the number of download requests they perform concurrently from each unique domain, which means that downloading many images from a single web page might be somewhat slow. To overcome this limitation, Cloudinary supports downloading images via multiple sub-domains, which means you can spread your image downloads between the different sub-domains, resulting in a much improved web browsing speed.
Note that the improvement only applies to image requests over HTTP. It is not recommended to use multiple sub-domains together with HTTPS as opening an HTTPS connection requires more time than opening an HTTP connection (several round trips are needed to perform the encryption handshake).
Cloudinary supports the default res
sub-domain, as well as the res-1
through res-5
sub-domains, as a prefix to the host name. Mapping between a specific image (by public ID) and the six different sub-domains (res
plus res-1
through res-5
) should be consistent in order to ensure that the browsers can correctly cache the images. For example, referencing a certain image once via 'res-1' and then again via 'res-2' will bypass browser caching and download the image twice.
For example, the sample
image delivered via the res-4
sub-domain:
http://res-4.cloudinary.com/demo/image/upload/sample.jpg
When using one of Cloudinary's framework SDKs, you can also automatically enable delivering images from the res-1
through res-5
sub-domains by setting the cdn_subdomain
parameter to true
, either globally (e.g., in the CLOUDINARY_URL environment variable) or locally in each call. Note that the Cloudinary SDKs automatically map individual images consistently to the same sub-domain using a CRC32 based code of the image's public ID.
You can also use multiple sub-domains when using a custom domain (CNAME) by prepending the a1
through a5
sub-domains, as a prefix to the host name, for example:
http://a1.<mydomain.com>/image/upload/sample.jpg
Note: CNAMEs are only available for Cloudinary's Advanced plan and above, and requires a small setup on Cloudinary's side. Furthermore, the sub-domains need to be defined in the DNS settings of the domain name. Contact us at support@cloudinary.com for more details.
For more information on using sub-domains, see the Reduce site load time with multiple CDN sub-domains article.
SEO friendly image URLs
Image URLs are specified in the source code of HTML pages and are leveraged by search engines to understand the image's content. Concise and descriptive image file names are better for search engines to extract information about an image, therefore supporting your site's SEO ranking.
SEO starts with the ability to define custom public IDs while uploading images which can be as descriptive as necessary. Cloudinary can help make your image URLs more SEO friendly in a few other ways:
For more information on creating SEO friendly URLs, see the article on How to dynamically create SEO friendly URLs for your site's images.
Root path URLs
The Root Path URL feature allows you to create shorter image URLs for delivering uploaded images. The default Cloudinary resource delivery URL includes the resource type
and type
parameters, for example, /image/upload
. With Cloudinary’s Root Path URL feature, the resource type and type parameters are set to the default values 'image' and 'upload' respectively, which means that any URL without the resource type and type parameters will automatically default to using those values.
For example, the default delivery URL for the sample
image in JPEG format is normally:
http://res.cloudinary.com/demo/image/upload/sample.jpg
The delivery URL using the Root Path URL feature for image uploads is:
http://res.cloudinary.com/demo/sample.jpg
Both the URLs above deliver the same uploaded image.
Dynamic SEO suffixes
The dynamic SEO suffixes feature allows you to dynamically add a descriptive suffix to the Public ID in the image URL. This can be useful:
- If an image is not given a suitable Public ID during the upload process.
- To support different languages for describing a single image.
- To reflect specific content on certain pages.
Note: This feature requires a private CDN distribution, which is available for Cloudinary's Advanced plan and above, and requires a small setup on Cloudinary's side. Contact us at support@cloudinary.com for more details.
To add a dynamic SEO suffix, an image’s path prefix must first be changed from the default /image/upload
to the shorter version /images
. Any custom suffix can then be dynamically added to the Public ID, after adding a slash (/
).
For example the default delivery URL for the t8sn7wg4jd74j
image in JPEG format is:
http://demo-res.cloudinary.com/image/upload/t8sn7wg4jd74j.jpg
The delivery URL with the suffix basketball-game
added to the Public ID is:
http://demo-res.cloudinary.com/images/t8sn7wg4jd74j/basketball-game.jpg
In the URL below, the same image is given a suffix in Spanish:
http://demo-res.cloudinary.com/images/t8sn7wg4jd74j/baloncesto-juego.jpg
All the URLs above deliver the same uploaded image.
Note: Dynamic SEO suffixes are also available for raw files and private images. For raw files, the default /raw/upload
should be replaced by /files
, and for private uploads, the default /private/upload
should be replaced by /private_images
.
CNAME
You can also make your URLs more SEO friendly by using a custom domain (CNAME) for your URLs instead of the shared res.cloudinary.com
. The dynamic SEO suffix and CNAME features can also be used together, for example:
http://<mydomain.com>/t8sn7wg4jd74j/basktetball-game.jpg
Note: CNAMEs are available for Cloudinary's Advanced plan and above, and requires a small setup on Cloudinary's side. Contact us at support@cloudinary.com for more details.
Using a default image placeholder
Default images can be used in the case that a requested image does not exist. For example, a site that automatically stores user profile pictures with the same name as the user themselves, allowing you to reference the pictures by user name (unless the user has not uploaded a profile picture yet).
Specify a default image to use with the default_image
parameter (d
in URLs) and the public ID + format of a previously uploaded image, for example, d_placeholder.png
to use the image with the public ID of placeholder
as the default image. Note that any requested transformations are also applied on the default image as well.
For example, to use the PNG image called avatar
as a default image in the case that the image called non_existing_id
does not exist:
cl_image_tag("non_existing_id.png", :default_image=>"avatar.png")
cl_image_tag("non_existing_id.png", array("default_image"=>"avatar.png"))
CloudinaryImage("non_existing_id.png").image(default_image="avatar.png")
cloudinary.image("non_existing_id.png", {default_image: "avatar.png"})
cloudinary.url().transformation(new Transformation().defaultImage("avatar.png")).imageTag("non_existing_id.png")
$.cloudinary.image("non_existing_id.png", {default_image: "avatar.png"})
cloudinary.Api.UrlImgUp.Transform(new Transformation().DefaultImage("avatar.png")).BuildImageTag("non_existing_id.png")
The same example as above, but with transformation parameters applied to scale down to 200 pixels wide and rotate by 45 degrees:
cl_image_tag("non_existing_id.png", :transformation=>[ {:width=>200, :angle=>45}, {:default_image=>"avatar.png"} ])
cl_image_tag("non_existing_id.png", array("transformation"=>array( array("width"=>200, "angle"=>45), array("default_image"=>"avatar.png") )))
CloudinaryImage("non_existing_id.png").image(transformation=[ {"width": 200, "angle": 45}, {"default_image": "avatar.png"} ])
cloudinary.image("non_existing_id.png", {transformation: [ {width: 200, angle: 45}, {default_image: "avatar.png"} ]})
cloudinary.url().transformation(new Transformation() .width(200).angle(45).chain() .defaultImage("avatar.png")).imageTag("non_existing_id.png")
$.cloudinary.image("non_existing_id.png", {transformation: [ {width: 200, angle: 45}, {default_image: "avatar.png"} ]})
cloudinary.Api.UrlImgUp.Transform(new Transformation() .Width(200).Angle(45).Chain() .DefaultImage("avatar.png")).BuildImageTag("non_existing_id.png")
Creating images from PDF files
You can upload PDF files to Cloudinary as an image type. You can deliver them via a CDN, convert them to images, and generate thumbnails. To deliver an image of the first page in a PDF file, simply change the file extension from pdf
to the image format of your choice in the Cloudinary delivery URL. For example, to deliver a JPEG image of the first page in a previously uploaded PDF file called multi_page_pdf
(scaled down to a width of 300 pixels):
cl_image_tag("multi_page_pdf.jpg", :width=>300)
cl_image_tag("multi_page_pdf.jpg", array("width"=>300))
CloudinaryImage("multi_page_pdf.jpg").image(width=300)
cloudinary.image("multi_page_pdf.jpg", {width: 300})
cloudinary.url().transformation(new Transformation().width(300)).imageTag("multi_page_pdf.jpg")
$.cloudinary.image("multi_page_pdf.jpg", {width: 300})
cloudinary.Api.UrlImgUp.Transform(new Transformation().Width(300)).BuildImageTag("multi_page_pdf.jpg")
To deliver an image of a different page in the PDF file, use the page
parameter (pg
in URLs). For example, to deliver the second page in the PDF file as a png image (scaled down to a width of 300 pixels):
cl_image_tag("multi_page_pdf.png", :width=>300, :page=>2)
cl_image_tag("multi_page_pdf.png", array("width"=>300, "page"=>2))
CloudinaryImage("multi_page_pdf.png").image(width=300, page=2)
cloudinary.image("multi_page_pdf.png", {width: 300, page: 2})
cloudinary.url().transformation(new Transformation().width(300).page(2)).imageTag("multi_page_pdf.png")
$.cloudinary.image("multi_page_pdf.png", {width: 300, page: 2})
cloudinary.Api.UrlImgUp.Transform(new Transformation().Width(300).Page(2)).BuildImageTag("multi_page_pdf.png")
Furthermore, you can control the resolution of the resulting image by changing the default dpi value of 150 with the density
parameter (dn
in URLs). For example, to deliver a JPEG image of the PDF file with a density of 20:
cl_image_tag("multi_page_pdf.jpg", :density=>20)
cl_image_tag("multi_page_pdf.jpg", array("density"=>20))
CloudinaryImage("multi_page_pdf.jpg").image(density=20)
cloudinary.image("multi_page_pdf.jpg", {density: 20})
cloudinary.url().transformation(new Transformation().density(20)).imageTag("multi_page_pdf.jpg")
$.cloudinary.image("multi_page_pdf.jpg", {density: 20})
cloudinary.Api.UrlImgUp.Transform(new Transformation().Density(20)).BuildImageTag("multi_page_pdf.jpg")
You can also use the explode method of the Admin API to explicitly generate derived images of all pages of a PDF, including optionally applying any transformation on all the pages before storing them. This method is useful for pre-generating all the pages, so that they do not need to be generated on-the-fly when first accessed by your users.
Note: To create PDF files and images from Office documents, see the Aspose add-on documentation.
Managing Animated GIFs
You can upload animated GIFs to Cloudinary, resize and crop them, further transform them, optimize them, convert them to modern video or animated image formats and create new animated GIFs.
Animated GIFs can be uploaded to Cloudinary just like any other image format. Besides the usual image transformation features available to animated GIFs, they can also be managed in the following ways:
- Manipulate animated GIFs
- Convert an animated GIF to video
- Convert an animated GIF to animated WebP
- Apply lossy GIF compression
- Create animated GIFs
Manipulating animated GIFs
Animated GIFs can be manipulated like any other image uploaded to Cloudinary. For example:
- Original uploaded
kitten_fighting
animated GIF:
cl_image_tag("kitten_fighting.gif")
cl_image_tag("kitten_fighting.gif")
CloudinaryImage("kitten_fighting.gif").image()
cloudinary.image("kitten_fighting.gif")
cloudinary.url().imageTag("kitten_fighting.gif")
$.cloudinary.image("kitten_fighting.gif")
cloudinary.Api.UrlImgUp.BuildImageTag("kitten_fighting.gif")
- Resized to a width of 200 pixels (height is adjusted automatically to keep the aspect ratio):
cl_image_tag("kitten_fighting.gif", :width=>200)
cl_image_tag("kitten_fighting.gif", array("width"=>200))
CloudinaryImage("kitten_fighting.gif").image(width=200)
cloudinary.image("kitten_fighting.gif", {width: 200})
cloudinary.url().transformation(new Transformation().width(200)).imageTag("kitten_fighting.gif")
$.cloudinary.image("kitten_fighting.gif", {width: 200})
cloudinary.Api.UrlImgUp.Transform(new Transformation().Width(200)).BuildImageTag("kitten_fighting.gif")
- Cropped to a height and width of 200 pixels with rounded corners:
cl_image_tag("kitten_fighting.gif", :width=>200, :height=>200, :radius=>"max", :crop=>"crop")
cl_image_tag("kitten_fighting.gif", array("width"=>200, "height"=>200, "radius"=>"max", "crop"=>"crop"))
CloudinaryImage("kitten_fighting.gif").image(width=200, height=200, radius="max", crop="crop")
cloudinary.image("kitten_fighting.gif", {width: 200, height: 200, radius: "max", crop: "crop"})
cloudinary.url().transformation(new Transformation().width(200).height(200).radius("max").crop("crop")).imageTag("kitten_fighting.gif")
$.cloudinary.image("kitten_fighting.gif", {width: 200, height: 200, radius: "max", crop: "crop"})
cloudinary.Api.UrlImgUp.Transform(new Transformation().Width(200).Height(200).Radius("max").Crop("crop")).BuildImageTag("kitten_fighting.gif")
Deliver a single frame
Use the page
parameter (pg
in URLs) to deliver only a single frame of an animated GIF. For example, to deliver the second frame in the kitten_fighting
GIF file:
cl_image_tag("kitten_fighting.gif", :page=>2)
cl_image_tag("kitten_fighting.gif", array("page"=>2))
CloudinaryImage("kitten_fighting.gif").image(page=2)
cloudinary.image("kitten_fighting.gif", {page: 2})
cloudinary.url().transformation(new Transformation().page(2)).imageTag("kitten_fighting.gif")
$.cloudinary.image("kitten_fighting.gif", {page: 2})
cloudinary.Api.UrlImgUp.Transform(new Transformation().Page(2)).BuildImageTag("kitten_fighting.gif")
Control the delay between frames
Use the delay
parameter (dl
in URLs) to control the amount of time (in milliseconds) that passes between displaying the individual frames in an animated GIF. For example, to deliver the kitten_fighting
GIF with a delay of 200 milliseconds between frames:
cl_image_tag("kitten_fighting.gif", :delay=>"200")
cl_image_tag("kitten_fighting.gif", array("delay"=>"200"))
CloudinaryImage("kitten_fighting.gif").image(delay="200")
cloudinary.image("kitten_fighting.gif", {delay: "200"})
cloudinary.url().transformation(new Transformation().delay("200")).imageTag("kitten_fighting.gif")
$.cloudinary.image("kitten_fighting.gif", {delay: "200"})
cloudinary.Api.UrlImgUp.Transform(new Transformation().Delay("200")).BuildImageTag("kitten_fighting.gif")
Converting an animated GIF to video
To deliver an animated GIF as a video file, simply change the file extension to either the webm
or the mp4
video format. The file is automatically converted to a video format and codec that best fits web and mobile browsers, and the default quality settings represent an optimized trade off between visual quality and file size. See the article on Reduce size of animated GIFs, automatically convert to WebM and MP4
For example, to deliver the kitten_fighting
GIF as an MP4 video, reducing the file size by 95%:
cl_video_tag("kitten_fighting")
cl_video_tag("kitten_fighting")
CloudinaryImage("kitten_fighting").video()
cloudinary.video("kitten_fighting")
cloudinary.url().videoTag("kitten_fighting")
$.cloudinary.video("kitten_fighting")
cloudinary.Api.UrlImgUp.BuildVideoTag("kitten_fighting")
The video file can also be delivered using Cloudinary's video tags and further manipulated like any other video file. See the video manipulation and delivery documentation for more details.
Note: To deliver video files as animated GIFs and animated WebPs, see the Creating animated GIF and animated WebP video documentation.
Converting an animated GIF to animated WebP
There are a quite a few advantages to delivering animated files in the WebP format instead of the GIF format, including:
- WebP supports 24-bit RGB color with an 8-bit alpha channel, compared to GIF's 8-bit color and 1-bit alpha.
- WebP supports both lossy and lossless compression (a single animation can combine lossy and lossless frames), well-suited to animated images created from real-world videos. GIF only supports lossless compression.
- WebP requires fewer bytes than GIF, ranging from 64% smaller for Animated GIF converted to lossy WebP, to 19% smaller for lossless WebP.
To deliver an animated WebP instead of an animated GIF, change the file extension from .gif
to .webp
and set the flag
parameter to awebp
(fl_awebp
in URLs). For example, delivering the animated gif called kitten_fighting
as an animated WebP:
cl_image_tag("kitten_fighting.webp", :flags=>"awebp")
cl_image_tag("kitten_fighting.webp", array("flags"=>"awebp"))
CloudinaryImage("kitten_fighting.webp").image(flags="awebp")
cloudinary.image("kitten_fighting.webp", {flags: "awebp"})
cloudinary.url().transformation(new Transformation().flags("awebp")).imageTag("kitten_fighting.webp")
$.cloudinary.image("kitten_fighting.webp", {flags: "awebp"})
cloudinary.Api.UrlImgUp.Transform(new Transformation().Flags("awebp")).BuildImageTag("kitten_fighting.webp")
The disadvantage of the WebP format is that whereas animated GIFs are universally supported, WebP is only supported by the Chrome, Android and Opera web browsers. To offset this problem you can automatically detect the user's browser and deliver the correct supported format by setting the fetch_format
parameter to auto
(or f_auto
in URLs). For example, to deliver kitten_fighting
in the WebP format to supported browsers, and in the GIF format to the rest:
cl_image_tag("kitten_fighting.gif", :fetch_format=>:auto)
cl_image_tag("kitten_fighting.gif", array("fetch_format"=>"auto"))
CloudinaryImage("kitten_fighting.gif").image(fetch_format="auto")
cloudinary.image("kitten_fighting.gif", {fetch_format: "auto"})
cloudinary.url().transformation(new Transformation().fetchFormat("auto")).imageTag("kitten_fighting.gif")
$.cloudinary.image("kitten_fighting.gif", {fetch_format: "auto"})
cloudinary.Api.UrlImgUp.Transform(new Transformation().FetchFormat("auto")).BuildImageTag("kitten_fighting.gif")
Applying lossy GIF compression
The compression algorithms used in GIFs are lossless, and there is no loss of data when compressing this palette-based format. The "lossiness" comes in when the GIF is first filtered or altered so that the image can then compress more efficiently. The loss of data occurs in this filtering phase by increasing redundant patterns along scan lines to subsequently improve the actual compression and decrease the file size.
To automatically use lossy compression when delivering your animated GIF files, set the flag
parameter to lossy
(fl_lossy
in URLs). For example, the kitten_fighting
animated GIF has a file size of 6.3 MB without lossy compression, and a file size of 2.5 MB with lossy compression. The file still looks good and is now 40% of the original size:
cl_image_tag("kitten_fighting.gif", :flags=>"lossy")
cl_image_tag("kitten_fighting.gif", array("flags"=>"lossy"))
CloudinaryImage("kitten_fighting.gif").image(flags="lossy")
cloudinary.image("kitten_fighting.gif", {flags: "lossy"})
cloudinary.url().transformation(new Transformation().flags("lossy")).imageTag("kitten_fighting.gif")
$.cloudinary.image("kitten_fighting.gif", {flags: "lossy"})
cloudinary.Api.UrlImgUp.Transform(new Transformation().Flags("lossy")).BuildImageTag("kitten_fighting.gif")
To control the level of lossy compression in the resulting animated GIF add the quality
parameter (q
in URLs), which has a default value of 80 (applied in the example above). For example, enabling lossy compression for the kitten_fighting
GIF and also setting the quality parameter to 50 results in a file size of 2.1 MB - 33% of the original file size.
cl_image_tag("kitten_fighting.gif", :flags=>"lossy", :quality=>50)
cl_image_tag("kitten_fighting.gif", array("flags"=>"lossy", "quality"=>50))
CloudinaryImage("kitten_fighting.gif").image(flags="lossy", quality=50)
cloudinary.image("kitten_fighting.gif", {flags: "lossy", quality: 50})
cloudinary.url().transformation(new Transformation().flags("lossy").quality(50)).imageTag("kitten_fighting.gif")
$.cloudinary.image("kitten_fighting.gif", {flags: "lossy", quality: 50})
cloudinary.Api.UrlImgUp.Transform(new Transformation().Flags("lossy").Quality(50)).BuildImageTag("kitten_fighting.gif")
Creating animated GIFs
Cloudinary supports the creation of a single animated GIF from multiple images, where each image is included as a single frame of the resulting GIF. The process requires 3 steps:
Step 1: Upload all the images to be included in the animated GIF. Make sure that you include:
- An appropriate public ID when uploading each of the files - when they are merged into a single animated GIF they are sorted alphabetically by their public IDs.
- An identical tag for all images. The tag must also be unique to these images only - the GIF creation process finds all images with the same tag and merges them into a single file.
Step 2: Use the multi method of the upload API to create the animated GIF. If the images to be merged are not all the same size, you can add transformation parameters to the URL to crop them accordingly (using one of the crop modes plus width
or height
, etc). For example, to create an animated GIF from all images that have been given the tag arrow_animation
:
Cloudinary::Uploader.multi(:tag => 'arrow_animation')
\Cloudinary\Uploader::multi(array('tag' => 'arrow_animation'));
cloudinary.uploader.multi(tag = 'arrow_animation')
cloudinary.uploader.v2.multi({ tag: 'arrow_animation' }, function(error,result) {console.log(result) });
cloudinary.uploader().multi( ObjectUtils.asMap('tag', 'arrow_animation'));
curl https://api.cloudinary.com/v1_1/demo/image/multi -X POST --data 'tag=arrow_animation×tamp=173719931&api_key=436464676&signature=a788d68f86a6f868af'
Step 3: To deliver the animated GIF, use the Cloudinary image delivery URL with type
set to multi
. For example, to deliver the animated GIF created from all images with the tag arrow_animation
:
cl_image_tag("arrow_animation.gif", :type=>"multi")
cl_image_tag("arrow_animation.gif", array("type"=>"multi"))
CloudinaryImage("arrow_animation.gif").image(type="multi")
cloudinary.image("arrow_animation.gif", {type: "multi"})
cloudinary.url().type("multi").imageTag("arrow_animation.gif")
$.cloudinary.image("arrow_animation.gif", {type: "multi"})
cloudinary.Api.UrlImgUp.Type("multi").BuildImageTag("arrow_animation.gif")
The following example showcases a method to create a very simple animated gif of revolving text consisting of 20 individual frames. A script is executed to upload the individual images to Cloudinary, where each individual image (frame) is constructed from:
- A previously uploaded blank image used as a base image.
- A text string overlaid over the base image.
Each frame is a combination of the base image together with an overlay of a slightly modified version of the text string. The text is modified for each frame with the distort
effect parameter to change its perspective.
coordinates = {} (0..10).each do |frame| x_offset = frame * 10 y_back = 10*(frame < 5 ? -frame : frame - 10) y_front = y_back*2 front = [ x_offset, y_front, 100 - x_offset, -y_back, 100 - x_offset, 100+y_back, x_offset, 100 - y_front ] .map { |i| "#{i}p" }.join(":") back = [ x_offset, -y_back, 100 - x_offset, y_back*2, 100 - x_offset, 100 - y_back*2, x_offset, 100 + y_back ] .map { |i| "#{i}p" }.join(":") coordinates[frame] = front coordinates[20 - frame] = back end (0..19).each do |frame| x_offset = frame < 10 ? frame*10 : 200 - frame*10 myurl = Cloudinary::Utils.cloudinary_url( "base.png", :transformation => [ { :width => 510, :height => 300, :crop => "scale", :background => "white" }, { :overlay => "text:roboto_150_bold:Spinning text", :color => "#0071BA", :width => 500, :height => 100 }, { :effect => "distort:#{coordinates[frame]}" }, { :crop => "crop", gravity: "center", :width => ((500*(100-2*x_offset)/100.0).abs.to_i), :height => 300 }, { :flags => "layer_apply" }]) Cloudinary::Uploader.upload( myurl, :public_id => "spinning_text_#{'%02d' % frame}", :tags => "spinning_text" ) if x_offset != 50 end Cloudinary::Uploader.multi("spinning_text", :delay => 100)
After the script is run and the images are uploaded, the following URL delivers the animated GIF:
cl_image_tag("spinning_text.gif", :delay=>"100", :type=>"multi")
cl_image_tag("spinning_text.gif", array("delay"=>"100", "type"=>"multi"))
CloudinaryImage("spinning_text.gif").image(delay="100", type="multi")
cloudinary.image("spinning_text.gif", {delay: "100", type: "multi"})
cloudinary.url().transformation(new Transformation().delay("100")).type("multi").imageTag("spinning_text.gif")
$.cloudinary.image("spinning_text.gif", {delay: "100", type: "multi"})
cloudinary.Api.UrlImgUp.Transform(new Transformation().Delay("100")).Type("multi").BuildImageTag("spinning_text.gif")
Flags for controlling transformations
Set one or more flags that alter the default transformation behavior with the flag
parameter (fl
in URLs). You can set multiple flags by separating the individual flags with a dot (.
).
There are a large number of flags available, which can be roughly divided into the following types of flags:
- Cropping and positioning flags
- Delivery and image format flags
- Metadata and color profiles flags
- Overlays, PDF and text flags
For a full list of all the supported flags, see the Image transformations reference table.
Cropping and positioning flags
Parameter | Description |
---|---|
relative |
Modify percentage-based width & height parameters of overlays and underlays (e.g., 1.0) to be relative to the containing image instead of the added layer. |
region_relative |
Modify percentage-based width & height parameters of overlays and underlays (e.g., 1.0) to be relative to the overlaid region. Currently regions are only defined when using gravity set to one of the face detection settings or 'custom'. |
cutter |
Trim pixels according to the transparency levels of a given overlay image. Whenever the overlay image is opaque, the original is shown, and wherever the overlay is transparent, the result will be transparent as well. |
clip |
Trim pixels according to a clipping path included in the original image metadata (e.g., manually created using software such as Adobe PhotoShop). |
ignore_aspect_ratio |
Allow specifying only width or height so the value of the second axis remains as is and is not recalculated to maintain the aspect ratio of the original image. |
no_overflow |
Do not extend the image canvas beyond the original dimensions when overlaying text and other images. |
tiled |
Tile the added overlay over the entire image. |
Examples:
- To deliver the
cloudinary_icon
image with a height of 150 pixels and ignoring the aspect ratio (width is not automatically adjusted):
cl_image_tag("cloudinary_icon.jpg", :height=>150, :flags=>"ignore_aspect_ratio")
cl_image_tag("cloudinary_icon.jpg", array("height"=>150, "flags"=>"ignore_aspect_ratio"))
CloudinaryImage("cloudinary_icon.jpg").image(height=150, flags="ignore_aspect_ratio")
cloudinary.image("cloudinary_icon.jpg", {height: 150, flags: "ignore_aspect_ratio"})
cloudinary.url().transformation(new Transformation().height(150).flags("ignore_aspect_ratio")).imageTag("cloudinary_icon.jpg")
$.cloudinary.image("cloudinary_icon.jpg", {height: 150, flags: "ignore_aspect_ratio"})
cloudinary.Api.UrlImgUp.Transform(new Transformation().Height(150).Flags("ignore_aspect_ratio")).BuildImageTag("cloudinary_icon.jpg")
- To add the
cloudinary_icon
overlay to theflower
image, where the overlay is scaled to 20% of the width of the base image:
cl_image_tag("flower.jpg", :overlay=>"cloudinary_icon", :width=>0.2, :flags=>"relative")
cl_image_tag("flower.jpg", array("overlay"=>"cloudinary_icon", "width"=>0.2, "flags"=>"relative"))
CloudinaryImage("flower.jpg").image(overlay="cloudinary_icon", width=0.2, flags="relative")
cloudinary.image("flower.jpg", {overlay: "cloudinary_icon", width: 0.2, flags: "relative"})
cloudinary.url().transformation(new Transformation().overlay("cloudinary_icon").width(0.2).flags("relative")).imageTag("flower.jpg")
$.cloudinary.image("flower.jpg", {overlay: "cloudinary_icon", width: 0.2, flags: "relative"})
cloudinary.Api.UrlImgUp.Transform(new Transformation().Overlay("cloudinary_icon").Width(0.2).Flags("relative")).BuildImageTag("flower.jpg")
Delivery and image format flags
Parameter | Description |
---|---|
progressive |
Generate a JPEG image using the progressive (interlaced) JPEG format. This format allows the browser to quickly show a low-quality rendering of the image until the full quality image is loaded. |
png8 |
Generate PNG images in the PNG8 format instead of the default PNG24 format, reducing the file size significantly, but limited to 256 colors. |
awebp |
When converting animated GIF images to the WebP format, generate an Animated WebP from all the frames in the animated GIF file instead of only from the first still frame of the GIF. |
lossy |
Automatically use lossy compression when delivering animated GIF files. This flag can also be used as a conditional flag for delivering PNG files: it tells Cloudinary to deliver the image in PNG format (as requested) unless there is no transparency channel - in which case deliver in JPEG format. |
attachment |
Deliver the image as an attachment for download. When the image's URL is accessed, tells the browser to download and save the image instead of embedding it and displaying it on a web page. |
Examples:
- To deliver an image scaled to a width of 300 pixels in PNG8 format instead of PNG24:
cl_image_tag("sample.png", :width=>300, :flags=>"png8")
cl_image_tag("sample.png", array("width"=>300, "flags"=>"png8"))
CloudinaryImage("sample.png").image(width=300, flags="png8")
cloudinary.image("sample.png", {width: 300, flags: "png8"})
cloudinary.url().transformation(new Transformation().width(300).flags("png8")).imageTag("sample.png")
$.cloudinary.image("sample.png", {width: 300, flags: "png8"})
cloudinary.Api.UrlImgUp.Transform(new Transformation().Width(300).Flags("png8")).BuildImageTag("sample.png")
- To deliver an image as an attachment (clicking the image downloads the file instead of opening the image in a new browser window):
cl_image_tag("sample.png", :flags=>"attachment")
cl_image_tag("sample.png", array("flags"=>"attachment"))
CloudinaryImage("sample.png").image(flags="attachment")
cloudinary.image("sample.png", {flags: "attachment"})
cloudinary.url().transformation(new Transformation().flags("attachment")).imageTag("sample.png")
$.cloudinary.image("sample.png", {flags: "attachment"})
cloudinary.Api.UrlImgUp.Transform(new Transformation().Flags("attachment")).BuildImageTag("sample.png")
Metadata and color profiles flags
Parameter | Description |
---|---|
keep_iptc |
Cloudinary's default behavior is to strip all metadata when generating new image transformations. Add this flag to keep the metadata. |
force_strip |
(Only relevant when applying an incoming transformation to an uploading image) Tells Cloudinary to clear all image metadata (IPTC, Exif and XMP) before storing the uploading image. |
strip_profile |
Tells Cloudinary to clear all ICC color profile data included with the image. |
For example, to deliver an image scaled to a width of 300 pixels with its meta-data:
cl_image_tag("sample.jpg", :width=>300, :flags=>"keep_iptc")
cl_image_tag("sample.jpg", array("width"=>300, "flags"=>"keep_iptc"))
CloudinaryImage("sample.jpg").image(width=300, flags="keep_iptc")
cloudinary.image("sample.jpg", {width: 300, flags: "keep_iptc"})
cloudinary.url().transformation(new Transformation().width(300).flags("keep_iptc")).imageTag("sample.jpg")
$.cloudinary.image("sample.jpg", {width: 300, flags: "keep_iptc"})
cloudinary.Api.UrlImgUp.Transform(new Transformation().Width(300).Flags("keep_iptc")).BuildImageTag("sample.jpg")
Overlays, PDF and text flags
Parameter | Description |
---|---|
layer_apply |
Apply all chained transformations, until a transformation component that includes this flag, on the last added overlay or underlay instead of applying them on the base image. See the topic on applying chained transformations to overlays for more information. |
rasterize |
Reduces the image to one flat pixelated layer (as opposed to the default vector based graphic) in order to enable PDF resizing and overlay transformations. |
text_no_trim |
Tells Cloudinary not to automatically trim the excess space from around a dynamic text string. |
For example, to add the face_left
overlay to the flower
image, where the transformations (resize to a 200x200 circular thumbnail with face detection) are applied to the overlay instead of the base image:
cl_image_tag("flower.jpg", :transformation=>[ {:overlay=>"face_left"}, {:width=>200, :height=>200, :gravity=>"face", :radius=>"max", :crop=>"thumb"}, {:flags=>"layer_apply", :gravity=>"north_east"} ])
cl_image_tag("flower.jpg", array("transformation"=>array( array("overlay"=>"face_left"), array("width"=>200, "height"=>200, "gravity"=>"face", "radius"=>"max", "crop"=>"thumb"), array("flags"=>"layer_apply", "gravity"=>"north_east") )))
CloudinaryImage("flower.jpg").image(transformation=[ {"overlay": "face_left"}, {"width": 200, "height": 200, "gravity": "face", "radius": "max", "crop": "thumb"}, {"flags": "layer_apply", "gravity": "north_east"} ])
cloudinary.image("flower.jpg", {transformation: [ {overlay: "face_left"}, {width: 200, height: 200, gravity: "face", radius: "max", crop: "thumb"}, {flags: "layer_apply", gravity: "north_east"} ]})
cloudinary.url().transformation(new Transformation() .overlay("face_left").chain() .width(200).height(200).gravity("face").radius("max").crop("thumb").chain() .flags("layer_apply").gravity("north_east")).imageTag("flower.jpg")
$.cloudinary.image("flower.jpg", {transformation: [ {overlay: "face_left"}, {width: 200, height: 200, gravity: "face", radius: "max", crop: "thumb"}, {flags: "layer_apply", gravity: "north_east"} ]})
cloudinary.Api.UrlImgUp.Transform(new Transformation() .Overlay("face_left").Chain() .Width(200).Height(200).Gravity("face").Radius("max").Crop("thumb").Chain() .Flags("layer_apply").Gravity("north_east")).BuildImageTag("flower.jpg")
Conditional transformations
Cloudinary supports conditional transformations, where a transformation is only applied if a specified condition is met, for example, when the image's width is greater than 300 pixels. This section consists of the following topics:
- Specifying a condition.
- Evaluating multiple conditions.
- Conditionally applying multiple transformations.
- Including else branch transformations.
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 characteristic of the image to evaluate as it would appear in URLs, for example 'w' for width.operator
- the comparison operator for the comparison in shorthand, for example 'lt' for 'less than'.image characteristic value
- the value of the characteristic or a different image characteristic.
For example, you can limit an image size to a width of 300 pixels using the limit crop mode, and with a conditional transformation you can also add a text caption if the image is scaled down (if_w_gt_300
):
cl_image_tag("sample.jpg", :transformation=>[ {:if=>"w_gt_300", :color=>"white", :gravity=>"south_east", :overlay=>"text:Arial_60_bold:Image%20scaled%20down%20to%20300px"}, {:width=>300, :crop=>"limit"} ])
cl_image_tag("sample.jpg", array("transformation"=>array( array("if"=>"w_gt_300", "color"=>"white", "gravity"=>"south_east", "overlay"=>"text:Arial_60_bold:Image%20scaled%20down%20to%20300px"), array("width"=>300, "crop"=>"limit") )))
CloudinaryImage("sample.jpg").image(transformation=[ {"if": "w_gt_300", "color": "white", "gravity": "south_east", "overlay": "text:Arial_60_bold:Image%20scaled%20down%20to%20300px"}, {"width": 300, "crop": "limit"} ])
cloudinary.image("sample.jpg", {transformation: [ {if: "w_gt_300", color: "white", gravity: "south_east", overlay: "text:Arial_60_bold:Image%20scaled%20down%20to%20300px"}, {width: 300, crop: "limit"} ]})
cloudinary.url().transformation(new Transformation() .if("w_gt_300").color("white").gravity("south_east").overlay("text:Arial_60_bold:Image%20scaled%20down%20to%20300px").chain() .width(300).crop("limit")).imageTag("sample.jpg")
$.cloudinary.image("sample.jpg", {transformation: [ {if: "w_gt_300", color: "white", gravity: "south_east", overlay: "text:Arial_60_bold:Image%20scaled%20down%20to%20300px"}, {width: 300, crop: "limit"} ]})
cloudinary.Api.UrlImgUp.Transform(new Transformation() .If("w_gt_300").Color("white").Gravity("south_east").Overlay("text:Arial_60_bold:Image%20scaled%20down%20to%20300px").Chain() .Width(300).Crop("limit")).BuildImageTag("sample.jpg")
Supported Operators:
Operator | 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 (>=) |
The Cloudinary SDKs also support the use of operator symbols (in the brackets above), e.g., both of the following are valid:
- { if: "w_gt_1000", crop: "scale", width: 500}
- { if: "width > 1000", crop: "scale", width: 500}
Supported image characteristics:
Characteristic | Description |
---|---|
w |
(also width in SDKs) The image's current width. |
iw |
The image's initial width. |
h |
(also height in SDKs) The image's current height. |
ih |
The image's initial height. |
ar |
(also aspect_ratio in SDKs) The aspect ratio of 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. |
pc |
(also page_count in SDKs) The total number of pages in the image/document. |
fc |
(also face_count in SDKs) The total number of detected faces in the image. |
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. - 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 a logical conjunction operator.
Operator | Description |
---|---|
and |
The transformations are applied only if BOTH conditions evaluate as true. |
or |
The transformations are applied if EITHER condition evaluates as true. |
Note: there is a precedence for the evaluation of operators: 'and' is evaluated before 'or'.
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
):
cl_image_tag("sample.jpg", :if=>"ar_gt_3:4_and_w_gt_300_and_h_gt_200", :width=>300, :height=>200, :crop=>"crop")
cl_image_tag("sample.jpg", array("if"=>"ar_gt_3:4_and_w_gt_300_and_h_gt_200", "width"=>300, "height"=>200, "crop"=>"crop"))
CloudinaryImage("sample.jpg").image(if="ar_gt_3:4_and_w_gt_300_and_h_gt_200", width=300, height=200, crop="crop")
cloudinary.image("sample.jpg", {if: "ar_gt_3:4_and_w_gt_300_and_h_gt_200", width: 300, height: 200, crop: "crop"})
cloudinary.url().transformation(new Transformation().if("ar_gt_3:4_and_w_gt_300_and_h_gt_200").width(300).height(200).crop("crop")).imageTag("sample.jpg")
$.cloudinary.image("sample.jpg", {if: "ar_gt_3:4_and_w_gt_300_and_h_gt_200", width: 300, height: 200, crop: "crop"})
cloudinary.Api.UrlImgUp.Transform(new Transformation().If("ar_gt_3:4_and_w_gt_300_and_h_gt_200").Width(300).Height(200).Crop("crop")).BuildImageTag("sample.jpg")
Multiple conditional 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=>"text:Arial_20: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"=>"text:Arial_20:Image%20shown%20in%20full%20scale", "color"=>"white", "gravity"=>"south_east"), array("effect"=>"blur:400", "underlay"=>"small_dinosaur", "width"=>600, "crop"=>"scale"), array("if"=>"end") )))
CloudinaryImage("small_dinosaur.jpg").image(transformation=[ {"if": "w_lt_600"}, {"overlay": "text:Arial_20: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: "text:Arial_20: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("text:Arial_20:Image%20shown%20in%20full%20scale").color("white").gravity("south_east").chain() .effect("blur:400").underlay("small_dinosaur").width(600).crop("scale").chain() .if("end")).imageTag("small_dinosaur.jpg")
$.cloudinary.image("small_dinosaur.jpg", {transformation: [ {if: "w_lt_600"}, {overlay: "text:Arial_20:Image%20shown%20in%20full%20scale", color: "white", gravity: "south_east"}, {effect: "blur:400", underlay: "small_dinosaur", width: 600, crop: "scale"}, {if: "end"} ]})
cloudinary.Api.UrlImgUp.Transform(new Transformation() .If("w_lt_600").Chain() .Overlay("text:Arial_20:Image%20shown%20in%20full%20scale").Color("white").Gravity("south_east").Chain() .Effect("blur:400").Underlay("small_dinosaur").Width(600).Crop("scale").Chain() .If("end")).BuildImageTag("small_dinosaur.jpg")
Notes:
- Multiple separate conditions can be used in a single URL, but only one per transformation component.
- Cloudinary supports a single level of nested 'if' conditions.
- 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 also specify a transformation that is applied in the case that the initial condition is evaluated as negative (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_w_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
):
cl_image_tag("sample.jpg", :transformation=>[ {:if=>"w_lte_200", :height=>120, :width=>80, :crop=>"fill"}, {:if=>"else", :height=>90, :width=>100, :crop=>"fill"} ])
cl_image_tag("sample.jpg", array("transformation"=>array( array("if"=>"w_lte_200", "height"=>120, "width"=>80, "crop"=>"fill"), array("if"=>"else", "height"=>90, "width"=>100, "crop"=>"fill") )))
CloudinaryImage("sample.jpg").image(transformation=[ {"if": "w_lte_200", "height": 120, "width": 80, "crop": "fill"}, {"if": "else", "height": 90, "width": 100, "crop": "fill"} ])
cloudinary.image("sample.jpg", {transformation: [ {if: "w_lte_200", height: 120, width: 80, crop: "fill"}, {if: "else", height: 90, width: 100, crop: "fill"} ]})
cloudinary.url().transformation(new Transformation() .if("w_lte_200").height(120).width(80).crop("fill").chain() .if("else").height(90).width(100).crop("fill")).imageTag("sample.jpg")
$.cloudinary.image("sample.jpg", {transformation: [ {if: "w_lte_200", height: 120, width: 80, crop: "fill"}, {if: "else", height: 90, width: 100, crop: "fill"} ]})
cloudinary.Api.UrlImgUp.Transform(new Transformation() .If("w_lte_200").Height(120).Width(80).Crop("fill").Chain() .If("else").Height(90).Width(100).Crop("fill")).BuildImageTag("sample.jpg")
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, and 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", :transformation=>[ {:if=>"w_lte_400"}, {:height=>220, :width=>180, :crop=>"fill"}, {:effect=>"red"}, {:if=>"else"}, {:height=>190, :width=>300, :crop=>"fill"}, {:effect=>"oil_paint"}, {:if=>"end"} ])
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") )))
CloudinaryImage("sample.jpg").image(transformation=[ {"if": "w_lte_400"}, {"height": 220, "width": 180, "crop": "fill"}, {"effect": "red"}, {"if": "else"}, {"height": 190, "width": 300, "crop": "fill"}, {"effect": "oil_paint"}, {"if": "end"} ])
cloudinary.image("sample.jpg", {transformation: [ {if: "w_lte_400"}, {height: 220, width: 180, crop: "fill"}, {effect: "red"}, {if: "else"}, {height: 190, width: 300, crop: "fill"}, {effect: "oil_paint"}, {if: "end"} ]})
cloudinary.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")).imageTag("sample.jpg")
$.cloudinary.image("sample.jpg", {transformation: [ {if: "w_lte_400"}, {height: 220, width: 180, crop: "fill"}, {effect: "red"}, {if: "else"}, {height: 190, width: 300, crop: "fill"}, {effect: "oil_paint"}, {if: "end"} ]})
cloudinary.Api.UrlImgUp.Transform(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")).BuildImageTag("sample.jpg")
Transformations reference
The Image Transformations Reference table summarizes the extensive list of parameters available for manipulating images.