Cloudinary Blog

How to overlay text on image easily, pixel perfect and with no CSS/HTML

Overlay Text on Image, Pixel Perfect with No CSS/HTML

Our customers frequently ask us if we can help them apply dynamic text overlays over images. While a common approach is to add text elements in your pages using HTML elements, CSS or native mobile UI controls, in many cases it's preferable to create images with text layers already included. It makes it simpler to display rich content on different media channels and devices, while ensuring a pixel-perfect result as your graphic designer envisioned.

Text overlays on images can be used to embed a caption, a photographer's name or a watermark for copyright reasons. It can also be used to embed dynamic images in emails that have limited visual customization capabilities, dynamic building of advertisement banners with variable content, dynamic creation of print materials (e.g., coupons, greeting cards, business cards) and more.

Cloudinary's cloud-based media management service allows you to upload, specify a given text, and dynamically overlay it over your images and videos. Cloudinary does the image and video processing on the fly, and returns a new image which includes the required text layer. We've already shown in previous posts how you can create text layers using authenticated API calls and use text layers to build dynamic banners.

You can now use Cloudinary's image manipulation URLs to add text layers to images on-the-fly, while selecting any font out of a set of hundreds of fonts. You can also further customize and manipulate your text layers to achieve the desired look and feel. All this is done in the cloud using dynamic URLs (no authenticated API calls are required).

Dynamic styles

Cloudinary's dynamic manipulation URL allows you to add a text overlay while specifying the font, the actual text content, and customizing the look and feel.

For example, the following dynamic URL added the label 'Sea Shell' as an overlay on a previously-uploaded image named sea_shell.jpg. The component that starts with l_text: is followed by the font name and size and then the actual 'Sea Shell' label. The overlay is positioned 20 pixels from the top of the containing image by setting the gravity parameter to north (or g_north in the URL). In this example, we added a label using the Arial font of size 60 pixels.

Ruby:
cl_image_tag("sea_shell.jpg", :transformation=>[
  {:width=>400, :crop=>"scale"},
  {:overlay=>{:font_family=>"arial", :font_size=>60, :text=>"Sea%20Shell"}, :gravity=>"north", :y=>20}
  ])
PHP:
cl_image_tag("sea_shell.jpg", array("transformation"=>array(
  array("width"=>400, "crop"=>"scale"),
  array("overlay"=>array("font_family"=>"arial", "font_size"=>60, "text"=>"Sea%20Shell"), "gravity"=>"north", "y"=>20)
  )))
Python:
CloudinaryImage("sea_shell.jpg").image(transformation=[
  {'width': 400, 'crop': "scale"},
  {'overlay': {'font_family': "arial", 'font_size': 60, 'text': "Sea%20Shell"}, 'gravity': "north", 'y': 20}
  ])
Node.js:
cloudinary.image("sea_shell.jpg", {transformation: [
  {width: 400, crop: "scale"},
  {overlay: {font_family: "arial", font_size: 60, text: "Sea%20Shell"}, gravity: "north", y: 20}
  ]})
Java:
cloudinary.url().transformation(new Transformation()
  .width(400).crop("scale").chain()
  .overlay(new TextLayer().fontFamily("arial").fontSize(60).text("Sea%20Shell")).gravity("north").y(20)).imageTag("sea_shell.jpg");
JS:
cloudinary.imageTag('sea_shell.jpg', {transformation: [
  {width: 400, crop: "scale"},
  {overlay: new cloudinary.TextLayer().fontFamily("arial").fontSize(60).text("Sea%20Shell"), gravity: "north", y: 20}
  ]}).toHtml();
jQuery:
$.cloudinary.image("sea_shell.jpg", {transformation: [
  {width: 400, crop: "scale"},
  {overlay: new cloudinary.TextLayer().fontFamily("arial").fontSize(60).text("Sea%20Shell"), gravity: "north", y: 20}
  ]})
React:
<Image publicId="sea_shell.jpg" >
  <Transformation width="400" crop="scale" />
  <Transformation overlay={{fontFamily: "arial", fontSize: 60, text: "Sea%20Shell"}} gravity="north" y="20" />
</Image>
Angular:
<cl-image public-id="sea_shell.jpg" >
  <cl-transformation width="400" crop="scale">
  </cl-transformation>
  <cl-transformation overlay="text:arial_60:Sea%20Shell" gravity="north" y="20">
  </cl-transformation>
</cl-image>
.Net:
cloudinary.Api.UrlImgUp.Transform(new Transformation()
  .Width(400).Crop("scale").Chain()
  .Overlay(new TextLayer().FontFamily("arial").FontSize(60).Text("Sea%20Shell")).Gravity("north").Y(20)).BuildImageTag("sea_shell.jpg")
Android:
MediaManager.get().url().transformation(new Transformation()
  .width(400).crop("scale").chain()
  .overlay(new TextLayer().fontFamily("arial").fontSize(60).text("Sea%20Shell")).gravity("north").y(20)).generate("sea_shell.jpg");
iOS:
imageView.cldSetImage(cloudinary.createUrl().setTransformation(CLDTransformation()
  .setWidth(400).setCrop("scale").chain()
  .setOverlay("text:arial_60:Sea%20Shell").setGravity("north").setY(20)).generate("sea_shell.jpg")!, cloudinary: cloudinary)
Sea shell photo with text overlay

You can click on the tabs in the example above to see how to build this dynamic manipulation URL using Cloudinary's client libraries for Ruby on Rails, Python & Django, PHP, Node.js, Java and .Net.

Cloudinary supports hundreds of fonts, include all Google’s Web Fonts. You can specify the name of the font in manipulation URLs (case insensitive). In addition, you can specify any standard font customization by appending one or more of the following directives: bold, italic, underline, strikethrough, center, left, right.

The following example URL and client libraries code adds the same label, this time using the Courier font with bold, italic and underline:

Ruby:
cl_image_tag("sea_shell.jpg", :transformation=>[
  {:width=>400, :crop=>"scale"},
  {:overlay=>{:font_family=>"courier", :font_size=>60, :font_weight=>"bold", :font_style=>"italic", :text_decoration=>"underline", :text=>"Sea%20Shell"}, :gravity=>"north", :y=>20}
  ])
PHP:
cl_image_tag("sea_shell.jpg", array("transformation"=>array(
  array("width"=>400, "crop"=>"scale"),
  array("overlay"=>array("font_family"=>"courier", "font_size"=>60, "font_weight"=>"bold", "font_style"=>"italic", "text_decoration"=>"underline", "text"=>"Sea%20Shell"), "gravity"=>"north", "y"=>20)
  )))
Python:
CloudinaryImage("sea_shell.jpg").image(transformation=[
  {'width': 400, 'crop': "scale"},
  {'overlay': {'font_family': "courier", 'font_size': 60, 'font_weight': "bold", 'font_style': "italic", 'text_decoration': "underline", 'text': "Sea%20Shell"}, 'gravity': "north", 'y': 20}
  ])
Node.js:
cloudinary.image("sea_shell.jpg", {transformation: [
  {width: 400, crop: "scale"},
  {overlay: {font_family: "courier", font_size: 60, font_weight: "bold", font_style: "italic", text_decoration: "underline", text: "Sea%20Shell"}, gravity: "north", y: 20}
  ]})
Java:
cloudinary.url().transformation(new Transformation()
  .width(400).crop("scale").chain()
  .overlay(new TextLayer().fontFamily("courier").fontSize(60).fontWeight("bold").fontStyle("italic").textDecoration("underline").text("Sea%20Shell")).gravity("north").y(20)).imageTag("sea_shell.jpg");
JS:
cloudinary.imageTag('sea_shell.jpg', {transformation: [
  {width: 400, crop: "scale"},
  {overlay: new cloudinary.TextLayer().fontFamily("courier").fontSize(60).fontWeight("bold").fontStyle("italic").textDecoration("underline").text("Sea%20Shell"), gravity: "north", y: 20}
  ]}).toHtml();
jQuery:
$.cloudinary.image("sea_shell.jpg", {transformation: [
  {width: 400, crop: "scale"},
  {overlay: new cloudinary.TextLayer().fontFamily("courier").fontSize(60).fontWeight("bold").fontStyle("italic").textDecoration("underline").text("Sea%20Shell"), gravity: "north", y: 20}
  ]})
React:
<Image publicId="sea_shell.jpg" >
  <Transformation width="400" crop="scale" />
  <Transformation overlay={{fontFamily: "courier", fontSize: 60, fontWeight: "bold", fontStyle: "italic", textDecoration: "underline", text: "Sea%20Shell"}} gravity="north" y="20" />
</Image>
Angular:
<cl-image public-id="sea_shell.jpg" >
  <cl-transformation width="400" crop="scale">
  </cl-transformation>
  <cl-transformation overlay="text:courier_60_bold_italic_underline:Sea%20Shell" gravity="north" y="20">
  </cl-transformation>
</cl-image>
.Net:
cloudinary.Api.UrlImgUp.Transform(new Transformation()
  .Width(400).Crop("scale").Chain()
  .Overlay(new TextLayer().FontFamily("courier").FontSize(60).FontWeight("bold").FontStyle("italic").TextDecoration("underline").Text("Sea%20Shell")).Gravity("north").Y(20)).BuildImageTag("sea_shell.jpg")
Android:
MediaManager.get().url().transformation(new Transformation()
  .width(400).crop("scale").chain()
  .overlay(new TextLayer().fontFamily("courier").fontSize(60).fontWeight("bold").fontStyle("italic").textDecoration("underline").text("Sea%20Shell")).gravity("north").y(20)).generate("sea_shell.jpg");
iOS:
imageView.cldSetImage(cloudinary.createUrl().setTransformation(CLDTransformation()
  .setWidth(400).setCrop("scale").chain()
  .setOverlay("text:courier_60_bold_italic_underline:Sea%20Shell").setGravity("north").setY(20)).generate("sea_shell.jpg")!, cloudinary: cloudinary)
Sea shell photo with Courier bold, italic and underline text overlay

Colors and opacity

The color of the text overlay can be selected to match your graphic design by setting the color manipulation parameter (or co for URLs) to a color name or an RGB representation. The example below added the ‘Sea Shell’ label colored blue and this time using the bold Helvetica font of size 80 pixels.

Ruby:
cl_image_tag("sea_shell.jpg", :transformation=>[
  {:width=>400, :crop=>"scale"},
  {:overlay=>{:font_family=>"helvetica", :font_size=>80, :font_weight=>"bold", :text=>"Sea%20Shell"}, :gravity=>"north", :y=>20, :color=>"blue"}
  ])
PHP:
cl_image_tag("sea_shell.jpg", array("transformation"=>array(
  array("width"=>400, "crop"=>"scale"),
  array("overlay"=>array("font_family"=>"helvetica", "font_size"=>80, "font_weight"=>"bold", "text"=>"Sea%20Shell"), "gravity"=>"north", "y"=>20, "color"=>"blue")
  )))
Python:
CloudinaryImage("sea_shell.jpg").image(transformation=[
  {'width': 400, 'crop': "scale"},
  {'overlay': {'font_family': "helvetica", 'font_size': 80, 'font_weight': "bold", 'text': "Sea%20Shell"}, 'gravity': "north", 'y': 20, 'color': "blue"}
  ])
Node.js:
cloudinary.image("sea_shell.jpg", {transformation: [
  {width: 400, crop: "scale"},
  {overlay: {font_family: "helvetica", font_size: 80, font_weight: "bold", text: "Sea%20Shell"}, gravity: "north", y: 20, color: "blue"}
  ]})
Java:
cloudinary.url().transformation(new Transformation()
  .width(400).crop("scale").chain()
  .overlay(new TextLayer().fontFamily("helvetica").fontSize(80).fontWeight("bold").text("Sea%20Shell")).gravity("north").y(20).color("blue")).imageTag("sea_shell.jpg");
JS:
cloudinary.imageTag('sea_shell.jpg', {transformation: [
  {width: 400, crop: "scale"},
  {overlay: new cloudinary.TextLayer().fontFamily("helvetica").fontSize(80).fontWeight("bold").text("Sea%20Shell"), gravity: "north", y: 20, color: "blue"}
  ]}).toHtml();
jQuery:
$.cloudinary.image("sea_shell.jpg", {transformation: [
  {width: 400, crop: "scale"},
  {overlay: new cloudinary.TextLayer().fontFamily("helvetica").fontSize(80).fontWeight("bold").text("Sea%20Shell"), gravity: "north", y: 20, color: "blue"}
  ]})
React:
<Image publicId="sea_shell.jpg" >
  <Transformation width="400" crop="scale" />
  <Transformation overlay={{fontFamily: "helvetica", fontSize: 80, fontWeight: "bold", text: "Sea%20Shell"}} gravity="north" y="20" color="blue" />
</Image>
Angular:
<cl-image public-id="sea_shell.jpg" >
  <cl-transformation width="400" crop="scale">
  </cl-transformation>
  <cl-transformation overlay="text:helvetica_80_bold:Sea%20Shell" gravity="north" y="20" color="blue">
  </cl-transformation>
</cl-image>
.Net:
cloudinary.Api.UrlImgUp.Transform(new Transformation()
  .Width(400).Crop("scale").Chain()
  .Overlay(new TextLayer().FontFamily("helvetica").FontSize(80).FontWeight("bold").Text("Sea%20Shell")).Gravity("north").Y(20).Color("blue")).BuildImageTag("sea_shell.jpg")
Android:
MediaManager.get().url().transformation(new Transformation()
  .width(400).crop("scale").chain()
  .overlay(new TextLayer().fontFamily("helvetica").fontSize(80).fontWeight("bold").text("Sea%20Shell")).gravity("north").y(20).color("blue")).generate("sea_shell.jpg");
iOS:
imageView.cldSetImage(cloudinary.createUrl().setTransformation(CLDTransformation()
  .setWidth(400).setCrop("scale").chain()
  .setOverlay("text:helvetica_80_bold:Sea%20Shell").setGravity("north").setY(20).setColor("blue")).generate("sea_shell.jpg")!, cloudinary: cloudinary)
Blue colored Helvetica text overlay

The opacity parameter (or o for URLs) can be set to a value between 0 and 100 to make the text overlay semi-transparent. As you can see in the example below, a semi-transparent red label was added as an overlay:

Ruby:
cl_image_tag("sea_shell.jpg", :transformation=>[
  {:width=>400, :crop=>"scale"},
  {:overlay=>{:font_family=>"helvetica", :font_size=>80, :font_weight=>"bold", :text=>"Sea%20Shell"}, :gravity=>"north", :y=>20, :color=>"#8b0f02", :opacity=>50}
  ])
PHP:
cl_image_tag("sea_shell.jpg", array("transformation"=>array(
  array("width"=>400, "crop"=>"scale"),
  array("overlay"=>array("font_family"=>"helvetica", "font_size"=>80, "font_weight"=>"bold", "text"=>"Sea%20Shell"), "gravity"=>"north", "y"=>20, "color"=>"#8b0f02", "opacity"=>50)
  )))
Python:
CloudinaryImage("sea_shell.jpg").image(transformation=[
  {'width': 400, 'crop': "scale"},
  {'overlay': {'font_family': "helvetica", 'font_size': 80, 'font_weight': "bold", 'text': "Sea%20Shell"}, 'gravity': "north", 'y': 20, 'color': "#8b0f02", 'opacity': 50}
  ])
Node.js:
cloudinary.image("sea_shell.jpg", {transformation: [
  {width: 400, crop: "scale"},
  {overlay: {font_family: "helvetica", font_size: 80, font_weight: "bold", text: "Sea%20Shell"}, gravity: "north", y: 20, color: "#8b0f02", opacity: 50}
  ]})
Java:
cloudinary.url().transformation(new Transformation()
  .width(400).crop("scale").chain()
  .overlay(new TextLayer().fontFamily("helvetica").fontSize(80).fontWeight("bold").text("Sea%20Shell")).gravity("north").y(20).color("#8b0f02").opacity(50)).imageTag("sea_shell.jpg");
JS:
cloudinary.imageTag('sea_shell.jpg', {transformation: [
  {width: 400, crop: "scale"},
  {overlay: new cloudinary.TextLayer().fontFamily("helvetica").fontSize(80).fontWeight("bold").text("Sea%20Shell"), gravity: "north", y: 20, color: "#8b0f02", opacity: 50}
  ]}).toHtml();
jQuery:
$.cloudinary.image("sea_shell.jpg", {transformation: [
  {width: 400, crop: "scale"},
  {overlay: new cloudinary.TextLayer().fontFamily("helvetica").fontSize(80).fontWeight("bold").text("Sea%20Shell"), gravity: "north", y: 20, color: "#8b0f02", opacity: 50}
  ]})
React:
<Image publicId="sea_shell.jpg" >
  <Transformation width="400" crop="scale" />
  <Transformation overlay={{fontFamily: "helvetica", fontSize: 80, fontWeight: "bold", text: "Sea%20Shell"}} gravity="north" y="20" color="#8b0f02" opacity="50" />
</Image>
Angular:
<cl-image public-id="sea_shell.jpg" >
  <cl-transformation width="400" crop="scale">
  </cl-transformation>
  <cl-transformation overlay="text:helvetica_80_bold:Sea%20Shell" gravity="north" y="20" color="#8b0f02" opacity="50">
  </cl-transformation>
</cl-image>
.Net:
cloudinary.Api.UrlImgUp.Transform(new Transformation()
  .Width(400).Crop("scale").Chain()
  .Overlay(new TextLayer().FontFamily("helvetica").FontSize(80).FontWeight("bold").Text("Sea%20Shell")).Gravity("north").Y(20).Color("#8b0f02").Opacity(50)).BuildImageTag("sea_shell.jpg")
Android:
MediaManager.get().url().transformation(new Transformation()
  .width(400).crop("scale").chain()
  .overlay(new TextLayer().fontFamily("helvetica").fontSize(80).fontWeight("bold").text("Sea%20Shell")).gravity("north").y(20).color("#8b0f02").opacity(50)).generate("sea_shell.jpg");
iOS:
imageView.cldSetImage(cloudinary.createUrl().setTransformation(CLDTransformation()
  .setWidth(400).setCrop("scale").chain()
  .setOverlay("text:helvetica_80_bold:Sea%20Shell").setGravity("north").setY(20).setColor("#8b0f02").setOpacity(50)).generate("sea_shell.jpg")!, cloudinary: cloudinary)
Semi transparent text overlay

One of the common examples of text overlay is to add a caption with photo description and credits. The example above added an overlay with a credit to the photographer. This time we used the Doppio font while adding a semi transparent black overlay at the bottom of the photo, underlying the white text.

Ruby:
cl_image_tag("sea_shell.jpg", :transformation=>[
  {:width=>400, :crop=>"scale"},
  {:overlay=>"black_bar", :gravity=>"south", :width=>1.0, :height=>0.12, :flags=>"relative", :opacity=>60},
  {:overlay=>{:font_family=>"One", :font_size=>20, :text=>"Photographer"}, :gravity=>"south_west", :y=>5, :x=>10, :color=>"#eee"}
  ])
PHP:
cl_image_tag("sea_shell.jpg", array("transformation"=>array(
  array("width"=>400, "crop"=>"scale"),
  array("overlay"=>"black_bar", "gravity"=>"south", "width"=>1.0, "height"=>0.12, "flags"=>"relative", "opacity"=>60),
  array("overlay"=>array("font_family"=>"One", "font_size"=>20, "text"=>"Photographer"), "gravity"=>"south_west", "y"=>5, "x"=>10, "color"=>"#eee")
  )))
Python:
CloudinaryImage("sea_shell.jpg").image(transformation=[
  {'width': 400, 'crop': "scale"},
  {'overlay': "black_bar", 'gravity': "south", 'width': 1.0, 'height': 0.12, 'flags': "relative", 'opacity': 60},
  {'overlay': {'font_family': "One", 'font_size': 20, 'text': "Photographer"}, 'gravity': "south_west", 'y': 5, 'x': 10, 'color': "#eee"}
  ])
Node.js:
cloudinary.image("sea_shell.jpg", {transformation: [
  {width: 400, crop: "scale"},
  {overlay: "black_bar", gravity: "south", width: "1.0", height: "0.12", flags: "relative", opacity: 60},
  {overlay: {font_family: "One", font_size: 20, text: "Photographer"}, gravity: "south_west", y: 5, x: 10, color: "#eee"}
  ]})
Java:
cloudinary.url().transformation(new Transformation()
  .width(400).crop("scale").chain()
  .overlay(new Layer().publicId("black_bar")).gravity("south").width(1.0).height(0.12).flags("relative").opacity(60).chain()
  .overlay(new TextLayer().fontFamily("One").fontSize(20).text("Photographer")).gravity("south_west").y(5).x(10).color("#eee")).imageTag("sea_shell.jpg");
JS:
cloudinary.imageTag('sea_shell.jpg', {transformation: [
  {width: 400, crop: "scale"},
  {overlay: new cloudinary.Layer().publicId("black_bar"), gravity: "south", width: "1.0", height: "0.12", flags: "relative", opacity: 60},
  {overlay: new cloudinary.TextLayer().fontFamily("One").fontSize(20).text("Photographer"), gravity: "south_west", y: 5, x: 10, color: "#eee"}
  ]}).toHtml();
jQuery:
$.cloudinary.image("sea_shell.jpg", {transformation: [
  {width: 400, crop: "scale"},
  {overlay: new cloudinary.Layer().publicId("black_bar"), gravity: "south", width: "1.0", height: "0.12", flags: "relative", opacity: 60},
  {overlay: new cloudinary.TextLayer().fontFamily("One").fontSize(20).text("Photographer"), gravity: "south_west", y: 5, x: 10, color: "#eee"}
  ]})
React:
<Image publicId="sea_shell.jpg" >
  <Transformation width="400" crop="scale" />
  <Transformation overlay="black_bar" gravity="south" width="1.0" height="0.12" flags="relative" opacity="60" />
  <Transformation overlay={{fontFamily: "One", fontSize: 20, text: "Photographer"}} gravity="south_west" y="5" x="10" color="#eee" />
</Image>
Angular:
<cl-image public-id="sea_shell.jpg" >
  <cl-transformation width="400" crop="scale">
  </cl-transformation>
  <cl-transformation overlay="black_bar" gravity="south" width="1.0" height="0.12" flags="relative" opacity="60">
  </cl-transformation>
  <cl-transformation overlay="text:Doppio%20One_20:Photographer:%20Jonathan%20Doe" gravity="south_west" y="5" x="10" color="#eee">
  </cl-transformation>
</cl-image>
.Net:
cloudinary.Api.UrlImgUp.Transform(new Transformation()
  .Width(400).Crop("scale").Chain()
  .Overlay(new Layer().PublicId("black_bar")).Gravity("south").Width(1.0).Height(0.12).Flags("relative").Opacity(60).Chain()
  .Overlay(new TextLayer().FontFamily("One").FontSize(20).Text("Photographer")).Gravity("south_west").Y(5).X(10).Color("#eee")).BuildImageTag("sea_shell.jpg")
Android:
MediaManager.get().url().transformation(new Transformation()
  .width(400).crop("scale").chain()
  .overlay(new Layer().publicId("black_bar")).gravity("south").width(1.0).height(0.12).flags("relative").opacity(60).chain()
  .overlay(new TextLayer().fontFamily("One").fontSize(20).text("Photographer")).gravity("south_west").y(5).x(10).color("#eee")).generate("sea_shell.jpg");
iOS:
imageView.cldSetImage(cloudinary.createUrl().setTransformation(CLDTransformation()
  .setWidth(400).setCrop("scale").chain()
  .setOverlay("black_bar").setGravity("south").setWidth(1.0).setHeight(0.12).setFlags("relative").setOpacity(60).chain()
  .setOverlay("text:Doppio%20One_20:Photographer:%20Jonathan%20Doe").setGravity("south_west").setY(5).setX(10).setColor("#eee")).generate("sea_shell.jpg")!, cloudinary: cloudinary)
Credits caption semi-transparent text overlay

Multi-line text justification and wrapping

You may want to embed a longer text in your generated images. If so, you’ll need the text to be automatically wrapped into lines. You’ll also want to control the alignment of your text.

As you can see in the example below, a long text was overlaid over a previously uploaded image named ‘envelope.jpg’. The dynamic text layer is automatically wrapped and also aligned to the center. We specified the fit crop mode and defined a maximum width of 200 pixels, which tells Cloudinary to automatically wrap the actual text content. In addition, we rotated the generated text layer 9 degrees, to better fit in the background image (using the angle parameter, or a in the manipulation URL sample). This time we used the Neucha font, size 16 pixels, with center alignment.

Ruby:
cl_image_tag("envelope.jpg", :transformation=>[
  {:width=>300, :crop=>"scale"},
  {:gravity=>"north", :x=>0, :y=>54, :width=>200, :angle=>9, :overlay=>{:font_family=>"Neucha", :font_size=>16, :text_align=>"center", :text=>"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"}
  ])
PHP:
cl_image_tag("envelope.jpg", array("transformation"=>array(
  array("width"=>300, "crop"=>"scale"),
  array("gravity"=>"north", "x"=>0, "y"=>54, "width"=>200, "angle"=>9, "overlay"=>array("font_family"=>"Neucha", "font_size"=>16, "text_align"=>"center", "text"=>"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")
  )))
Python:
CloudinaryImage("envelope.jpg").image(transformation=[
  {'width': 300, 'crop': "scale"},
  {'gravity': "north", 'x': 0, 'y': 54, 'width': 200, 'angle': 9, 'overlay': {'font_family': "Neucha", 'font_size': 16, 'text_align': "center", 'text': "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"}
  ])
Node.js:
cloudinary.image("envelope.jpg", {transformation: [
  {width: 300, crop: "scale"},
  {gravity: "north", x: 0, y: 54, width: 200, angle: 9, overlay: {font_family: "Neucha", font_size: 16, text_align: "center", text: "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"}
  ]})
Java:
cloudinary.url().transformation(new Transformation()
  .width(300).crop("scale").chain()
  .gravity("north").x(0).y(54).width(200).angle(9).overlay(new TextLayer().fontFamily("Neucha").fontSize(16).textAlign("center").text("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");
JS:
cloudinary.imageTag('envelope.jpg', {transformation: [
  {width: 300, crop: "scale"},
  {gravity: "north", x: 0, y: 54, width: 200, angle: 9, overlay: new cloudinary.TextLayer().fontFamily("Neucha").fontSize(16).textAlign("center").text("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"}
  ]}).toHtml();
jQuery:
$.cloudinary.image("envelope.jpg", {transformation: [
  {width: 300, crop: "scale"},
  {gravity: "north", x: 0, y: 54, width: 200, angle: 9, overlay: new cloudinary.TextLayer().fontFamily("Neucha").fontSize(16).textAlign("center").text("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"}
  ]})
React:
<Image publicId="envelope.jpg" >
  <Transformation width="300" crop="scale" />
  <Transformation gravity="north" x="0" y="54" width="200" angle="9" overlay={{fontFamily: "Neucha", fontSize: 16, textAlign: "center", text: "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" />
</Image>
Angular:
<cl-image public-id="envelope.jpg" >
  <cl-transformation width="300" crop="scale">
  </cl-transformation>
  <cl-transformation gravity="north" x="0" y="54" width="200" angle="9" overlay="text:Neucha_16_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-transformation>
</cl-image>
.Net:
cloudinary.Api.UrlImgUp.Transform(new Transformation()
  .Width(300).Crop("scale").Chain()
  .Gravity("north").X(0).Y(54).Width(200).Angle(9).Overlay(new TextLayer().FontFamily("Neucha").FontSize(16).TextAlign("center").Text("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")
Android:
MediaManager.get().url().transformation(new Transformation()
  .width(300).crop("scale").chain()
  .gravity("north").x(0).y(54).width(200).angle(9).overlay(new TextLayer().fontFamily("Neucha").fontSize(16).textAlign("center").text("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")).generate("envelope.jpg");
iOS:
imageView.cldSetImage(cloudinary.createUrl().setTransformation(CLDTransformation()
  .setWidth(300).setCrop("scale").chain()
  .setGravity("north").setX(0).setY(54).setWidth(200).setAngle(9).setOverlay("text:Neucha_16_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.").setCrop("fit")).generate("envelope.jpg")!, cloudinary: cloudinary)
Rotated multi-line text overlay

Building print material with multiple text layers

All examples above added a single text overlay. You can use Cloudinary’s manipulation URLs to chain multiple overlays, generating a resulting image that is delivered optimized via a CDN to your users.

Cloudinary’s client libraries can be used to build chained transformation URLs with multiple text overlays. You can also directly build these URLs by separating the different components with /.

The following example used the same background envelope.jpg image. This time adding 3 different text overlays. Each text overlay uses a different set of font family, font size, color and positioning. The result is quite cool and professional, isn’t it?

Ruby:
cl_image_tag("envelope.jpg", :transformation=>[
  {:width=>300, :crop=>"scale"},
  {:overlay=>{:font_family=>"Courgette", :font_size=>22, :text=>"Dear%20customer"}, :angle=>9, :opacity=>80, :gravity=>"north_west", :y=>25, :x=>64, :color=>"#671537"},
  {:overlay=>{:font_family=>"Niconne", :font_size=>20, :text=>"Sincerely%20yours"}, :gravity=>"south", :x=>-10, :y=>120, :color=>"#15376f", :angle=>9},
  {:gravity=>"north", :x=>0, :y=>54, :width=>200, :angle=>9, :overlay=>{:font_family=>"Neucha", :font_size=>16, :text=>"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"}
  ])
PHP:
cl_image_tag("envelope.jpg", array("transformation"=>array(
  array("width"=>300, "crop"=>"scale"),
  array("overlay"=>array("font_family"=>"Courgette", "font_size"=>22, "text"=>"Dear%20customer"), "angle"=>9, "opacity"=>80, "gravity"=>"north_west", "y"=>25, "x"=>64, "color"=>"#671537"),
  array("overlay"=>array("font_family"=>"Niconne", "font_size"=>20, "text"=>"Sincerely%20yours"), "gravity"=>"south", "x"=>-10, "y"=>120, "color"=>"#15376f", "angle"=>9),
  array("gravity"=>"north", "x"=>0, "y"=>54, "width"=>200, "angle"=>9, "overlay"=>array("font_family"=>"Neucha", "font_size"=>16, "text"=>"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")
  )))
Python:
CloudinaryImage("envelope.jpg").image(transformation=[
  {'width': 300, 'crop': "scale"},
  {'overlay': {'font_family': "Courgette", 'font_size': 22, 'text': "Dear%20customer"}, 'angle': 9, 'opacity': 80, 'gravity': "north_west", 'y': 25, 'x': 64, 'color': "#671537"},
  {'overlay': {'font_family': "Niconne", 'font_size': 20, 'text': "Sincerely%20yours"}, 'gravity': "south", 'x': -10, 'y': 120, 'color': "#15376f", 'angle': 9},
  {'gravity': "north", 'x': 0, 'y': 54, 'width': 200, 'angle': 9, 'overlay': {'font_family': "Neucha", 'font_size': 16, 'text': "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"}
  ])
Node.js:
cloudinary.image("envelope.jpg", {transformation: [
  {width: 300, crop: "scale"},
  {overlay: {font_family: "Courgette", font_size: 22, text: "Dear%20customer"}, angle: 9, opacity: 80, gravity: "north_west", y: 25, x: 64, color: "#671537"},
  {overlay: {font_family: "Niconne", font_size: 20, text: "Sincerely%20yours"}, gravity: "south", x: -10, y: 120, color: "#15376f", angle: 9},
  {gravity: "north", x: 0, y: 54, width: 200, angle: 9, overlay: {font_family: "Neucha", font_size: 16, text: "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"}
  ]})
Java:
cloudinary.url().transformation(new Transformation()
  .width(300).crop("scale").chain()
  .overlay(new TextLayer().fontFamily("Courgette").fontSize(22).text("Dear%20customer")).angle(9).opacity(80).gravity("north_west").y(25).x(64).color("#671537").chain()
  .overlay(new TextLayer().fontFamily("Niconne").fontSize(20).text("Sincerely%20yours")).gravity("south").x(-10).y(120).color("#15376f").angle(9).chain()
  .gravity("north").x(0).y(54).width(200).angle(9).overlay(new TextLayer().fontFamily("Neucha").fontSize(16).text("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");
JS:
cloudinary.imageTag('envelope.jpg', {transformation: [
  {width: 300, crop: "scale"},
  {overlay: new cloudinary.TextLayer().fontFamily("Courgette").fontSize(22).text("Dear%20customer"), angle: 9, opacity: 80, gravity: "north_west", y: 25, x: 64, color: "#671537"},
  {overlay: new cloudinary.TextLayer().fontFamily("Niconne").fontSize(20).text("Sincerely%20yours"), gravity: "south", x: -10, y: 120, color: "#15376f", angle: 9},
  {gravity: "north", x: 0, y: 54, width: 200, angle: 9, overlay: new cloudinary.TextLayer().fontFamily("Neucha").fontSize(16).text("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"}
  ]}).toHtml();
jQuery:
$.cloudinary.image("envelope.jpg", {transformation: [
  {width: 300, crop: "scale"},
  {overlay: new cloudinary.TextLayer().fontFamily("Courgette").fontSize(22).text("Dear%20customer"), angle: 9, opacity: 80, gravity: "north_west", y: 25, x: 64, color: "#671537"},
  {overlay: new cloudinary.TextLayer().fontFamily("Niconne").fontSize(20).text("Sincerely%20yours"), gravity: "south", x: -10, y: 120, color: "#15376f", angle: 9},
  {gravity: "north", x: 0, y: 54, width: 200, angle: 9, overlay: new cloudinary.TextLayer().fontFamily("Neucha").fontSize(16).text("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"}
  ]})
React:
<Image publicId="envelope.jpg" >
  <Transformation width="300" crop="scale" />
  <Transformation overlay={{fontFamily: "Courgette", fontSize: 22, text: "Dear%20customer"}} angle="9" opacity="80" gravity="north_west" y="25" x="64" color="#671537" />
  <Transformation overlay={{fontFamily: "Niconne", fontSize: 20, text: "Sincerely%20yours"}} gravity="south" x="-10" y="120" color="#15376f" angle="9" />
  <Transformation gravity="north" x="0" y="54" width="200" angle="9" overlay={{fontFamily: "Neucha", fontSize: 16, text: "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" />
</Image>
Angular:
<cl-image public-id="envelope.jpg" >
  <cl-transformation width="300" crop="scale">
  </cl-transformation>
  <cl-transformation overlay="text:Courgette_22:Dear%20customer" angle="9" opacity="80" gravity="north_west" y="25" x="64" color="#671537">
  </cl-transformation>
  <cl-transformation overlay="text:Niconne_20:Sincerely%20yours" gravity="south" x="-10" y="120" color="#15376f" angle="9">
  </cl-transformation>
  <cl-transformation gravity="north" x="0" y="54" width="200" angle="9" overlay="text:Neucha_16: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-transformation>
</cl-image>
.Net:
cloudinary.Api.UrlImgUp.Transform(new Transformation()
  .Width(300).Crop("scale").Chain()
  .Overlay(new TextLayer().FontFamily("Courgette").FontSize(22).Text("Dear%20customer")).Angle(9).Opacity(80).Gravity("north_west").Y(25).X(64).Color("#671537").Chain()
  .Overlay(new TextLayer().FontFamily("Niconne").FontSize(20).Text("Sincerely%20yours")).Gravity("south").X(-10).Y(120).Color("#15376f").Angle(9).Chain()
  .Gravity("north").X(0).Y(54).Width(200).Angle(9).Overlay(new TextLayer().FontFamily("Neucha").FontSize(16).Text("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")
Android:
MediaManager.get().url().transformation(new Transformation()
  .width(300).crop("scale").chain()
  .overlay(new TextLayer().fontFamily("Courgette").fontSize(22).text("Dear%20customer")).angle(9).opacity(80).gravity("north_west").y(25).x(64).color("#671537").chain()
  .overlay(new TextLayer().fontFamily("Niconne").fontSize(20).text("Sincerely%20yours")).gravity("south").x(-10).y(120).color("#15376f").angle(9).chain()
  .gravity("north").x(0).y(54).width(200).angle(9).overlay(new TextLayer().fontFamily("Neucha").fontSize(16).text("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")).generate("envelope.jpg");
iOS:
imageView.cldSetImage(cloudinary.createUrl().setTransformation(CLDTransformation()
  .setWidth(300).setCrop("scale").chain()
  .setOverlay("text:Courgette_22:Dear%20customer").setAngle(9).setOpacity(80).setGravity("north_west").setY(25).setX(64).setColor("#671537").chain()
  .setOverlay("text:Niconne_20:Sincerely%20yours").setGravity("south").setX(-10).setY(120).setColor("#15376f").setAngle(9).chain()
  .setGravity("north").setX(0).setY(54).setWidth(200).setAngle(9).setOverlay("text:Neucha_16: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.").setCrop("fit")).generate("envelope.jpg")!, cloudinary: cloudinary)
Multiple text overlays of multiple lines and styles

Summary

As we already know from many of our customers, adding text overlays to images and photos is useful for many use cases. The addition of dynamic text styles and content that you can use, as an on-the-fly manipulation of images uploaded to Cloudinary, makes the process much simpler and more dynamic. The resulting images can be embedded in your website, mobile application or marketing emails, while ensuring that your users see it exactly as designed without any browser or device-specific customization.

Text overlay URLs with dynamic styles, as well as client library support for generating these URLs using Ruby on Rails, Python & Django, PHP, Node.js, Java and .Net, is available of all Cloudinary plans, including the free plan. If you don’t have an account yet, get a free account and try it out for yourself. We’d also love to hear your feedback on this feature in the comments below, or via Facebook or Twitter.

Recent Blog Posts

Cloudinary Product Gallery Enables Dynamic Buyer Experience

We live in a world where we spend increasingly more time online. As our routines change and adapt to new trends and technologies, we perform more and more of our daily activities in virtual environments. A key example of this is shopping. There are many reasons why online shopping has become so attractive for many buyers. A near endless variety of products is accessible from the palm of your hand. Customer reviews give buyers more confidence in their decisions. It's increasingly easy to search for attractive prices. And the list goes on. But a customer's desire to "touch" or "feel" the product is an interactive experience that can be hard to overcome when shopping online.

Read more
A Guide to Website Image Optimization and Performance

Part 1 of this series delves into the background for this guide. Here in part 2 are the ins and outs.

Wait, hear me out. I know, we just talked about this: Nobody is sheepishly pleading you, “Please, might we have just one more image on the page?” No, I’m not telling you to pick that particular fight. Instead, use a little smoke and mirrors to avoid requests for images that your audience needn’t render right away and might never need at all while loading them asynchronously—only as needed.

Read more
A Guide to Image Optimization for Website Performance

I’ve spent a lot of time thinking about the rules of putting images on the web.

For such a flexible medium as the web, software development can feel like a painstaking, rules-oriented game—an errant comma might break a build, a missing semicolon might wipe out an entire page. For a long time, the laws of image rendering seemed similarly cut-and-dry: For example, if your markups contained an img element , the singular content of its src attribute would be foisted on the audience regardless of their browsing context, period.

Read more
Digital Asset Management Platform: Meeting Customer Expectations

Consumers today expect media-rich experiences. No longer a novelty, it’s second nature to swipe through multiple photos on mobile apps, zoom in on product images for a closer look, visualize online travel reviews, socialize cool video clips while browsing, and encounter brand messages when walking into brick-and-mortar stores. These experiences weave together visual cues and clues with relevant content to create meaning and more authentic connections for customers.

Read more
How to Customize Cloudinary's eCommerce Android App

Recently we added the Cloudinary Demo - eCommerce App to the Google Play Store. This app demonstrates the best practices for optimal delivery of images on a storefront, including category pages, product pages, and a shopping cart. At the time, we published Introducing the Cloudinary Demo Android App, Part 1, which provided an under-the-hood tour of how the eCommerce Android App was designed and how Cloudinary was integrated throughout.

Read more