Cloudinary Blog

Introducing a Text-Overlay Creator

A New, Simple Tool for Creating Text Overlays for Images

Many Cloudinary users desire a UI for tasks like creating text overlays for images, which they then embed on webpages or download for marketing campaigns. Generating such overlays with the Cloudinary Media Library UI involves a bit of a learning curve, especially if they require multiple fonts or text lines, which even experienced users might find challenging to implement.

Let me showcase below a simple tool that I recently built for easily creating text overlays, including those with multiple lines and fonts.

Building Overlays in the Current Way

To create text overlays for an image in Cloudinary, you normally do that by editing the URL, as in this example:

Ruby:
Copy to clipboard
cl_image_tag("flowers.jpg", :transformation=>[
  {:width=>500, :crop=>"scale"},
  {:overlay=>{:font_family=>"Arial", :font_size=>80, :text=>"Flowers"}}
  ])
PHP v1:
Copy to clipboard
cl_image_tag("flowers.jpg", array("transformation"=>array(
  array("width"=>500, "crop"=>"scale"),
  array("overlay"=>array("font_family"=>"Arial", "font_size"=>80, "text"=>"Flowers"))
  )))
PHP v2:
Copy to clipboard
(new ImageTag('flowers.jpg'))
  ->resize(Resize::scale()->width(500))
  ->overlay(Overlay::source(Source::text('Flowers', (new TextStyle('Arial', 80)))));
Python:
Copy to clipboard
CloudinaryImage("flowers.jpg").image(transformation=[
  {'width': 500, 'crop': "scale"},
  {'overlay': {'font_family': "Arial", 'font_size': 80, 'text': "Flowers"}}
  ])
Node.js:
Copy to clipboard
cloudinary.image("flowers.jpg", {transformation: [
  {width: 500, crop: "scale"},
  {overlay: {font_family: "Arial", font_size: 80, text: "Flowers"}}
  ]})
Java:
Copy to clipboard
cloudinary.url().transformation(new Transformation()
  .width(500).crop("scale").chain()
  .overlay(new TextLayer().fontFamily("Arial").fontSize(80).text("Flowers"))).imageTag("flowers.jpg");
JS:
Copy to clipboard
cloudinary.imageTag('flowers.jpg', {transformation: [
  {width: 500, crop: "scale"},
  {overlay: new cloudinary.TextLayer().fontFamily("Arial").fontSize(80).text("Flowers")}
  ]}).toHtml();
jQuery:
Copy to clipboard
$.cloudinary.image("flowers.jpg", {transformation: [
  {width: 500, crop: "scale"},
  {overlay: new cloudinary.TextLayer().fontFamily("Arial").fontSize(80).text("Flowers")}
  ]})
React:
Copy to clipboard
<Image publicId="flowers.jpg" >
  <Transformation width="500" crop="scale" />
  <Transformation overlay={{fontFamily: "Arial", fontSize: 80, text: "Flowers"}} />
</Image>
Vue.js:
Copy to clipboard
<cld-image publicId="flowers.jpg" >
  <cld-transformation width="500" crop="scale" />
  <cld-transformation :overlay="{fontFamily: 'Arial', fontSize: 80, text: 'Flowers'}" />
</cld-image>
Angular:
Copy to clipboard
<cl-image public-id="flowers.jpg" >
  <cl-transformation width="500" crop="scale">
  </cl-transformation>
  <cl-transformation overlay="text:Arial_80:Flowers">
  </cl-transformation>
</cl-image>
.NET:
Copy to clipboard
cloudinary.Api.UrlImgUp.Transform(new Transformation()
  .Width(500).Crop("scale").Chain()
  .Overlay(new TextLayer().FontFamily("Arial").FontSize(80).Text("Flowers"))).BuildImageTag("flowers.jpg")
Android:
Copy to clipboard
MediaManager.get().url().transformation(new Transformation()
  .width(500).crop("scale").chain()
  .overlay(new TextLayer().fontFamily("Arial").fontSize(80).text("Flowers"))).generate("flowers.jpg");
iOS:
Copy to clipboard
imageView.cldSetImage(cloudinary.createUrl().setTransformation(CLDTransformation()
  .setWidth(500).setCrop("scale").chain()
  .setOverlay("text:Arial_80:Flowers")).generate("flowers.jpg")!, cloudinary: cloudinary)
Flowers

The above URL contains the following parameters:

  • flowers.jpg: the image name
  • w_500: the width of the overlay on the image
  • l_text: the type of the overlay, in this case text
    • Arial: the font face
    • 80: the font size

The above setup is a cinch to master. However, creating a text overlay, e.g., Happy New Year!, with a custom font takes more steps:

  1. Encode the text for the URL, i.e., Happy%20New%20Year%21.
  2. Locate your font file. Let’s say it’s fonts/Roboto-Thin.ttf.
  3. Build the full URL in the correct syntax, as follows:

Ruby:
Copy to clipboard
cl_image_tag("sample.jpg", :overlay=>{:public_id=>"fonts", :text=>"Roboto-Thin.ttf_30"})
PHP v1:
Copy to clipboard
cl_image_tag("sample.jpg", array("overlay"=>array("public_id"=>"fonts", "text"=>"Roboto-Thin.ttf_30")))
PHP v2:
Copy to clipboard
(new ImageTag('sample.jpg'))
  ->overlay(Overlay::source(Source::text('Roboto-Thin.ttf_30', (new TextStyle('fonts')))));
Python:
Copy to clipboard
CloudinaryImage("sample.jpg").image(overlay={'public_id': "fonts", 'text': "Roboto-Thin.ttf_30"})
Node.js:
Copy to clipboard
cloudinary.image("sample.jpg", {overlay: {public_id: "fonts", text: "Roboto-Thin.ttf_30"}})
Java:
Copy to clipboard
cloudinary.url().transformation(new Transformation().overlay(new TextLayer().text("Roboto-Thin.ttf_30").publicId("fonts"))).imageTag("sample.jpg");
JS:
Copy to clipboard
cloudinary.imageTag('sample.jpg', {overlay: new cloudinary.TextLayer().text("Roboto-Thin.ttf_30").publicId("fonts")}).toHtml();
jQuery:
Copy to clipboard
$.cloudinary.image("sample.jpg", {overlay: new cloudinary.TextLayer().text("Roboto-Thin.ttf_30").publicId("fonts")})
React:
Copy to clipboard
<Image publicId="sample.jpg" >
  <Transformation overlay={{text: "Roboto-Thin.ttf_30", publicId: "fonts"}} />
</Image>
Vue.js:
Copy to clipboard
<cld-image publicId="sample.jpg" >
  <cld-transformation :overlay="{text: 'Roboto-Thin.ttf_30', publicId: 'fonts'}" />
</cld-image>
Angular:
Copy to clipboard
<cl-image public-id="sample.jpg" >
  <cl-transformation overlay="text:fonts:Roboto-Thin.ttf_30:Happy%20New%20Year%21">
  </cl-transformation>
</cl-image>
.NET:
Copy to clipboard
cloudinary.Api.UrlImgUp.Transform(new Transformation().Overlay(new TextLayer().Text("Roboto-Thin.ttf_30").PublicId("fonts"))).BuildImageTag("sample.jpg")
Android:
Copy to clipboard
MediaManager.get().url().transformation(new Transformation().overlay(new TextLayer().text("Roboto-Thin.ttf_30").publicId("fonts"))).generate("sample.jpg");
iOS:
Copy to clipboard
imageView.cldSetImage(cloudinary.createUrl().setTransformation(CLDTransformation().setOverlay("text:fonts:Roboto-Thin.ttf_30:Happy%20New%20Year%21")).generate("sample.jpg")!, cloudinary: cloudinary)
Sample

To color the text yellow and position the overlay in the top-left corner, make the URL read like this:

Ruby:
Copy to clipboard
cl_image_tag("sample.jpg", :overlay=>{:public_id=>"fonts", :text=>"Roboto-Thin.ttf_30"}, :gravity=>"north_west", :color=>"#FFF000")
PHP v1:
Copy to clipboard
cl_image_tag("sample.jpg", array("overlay"=>array("public_id"=>"fonts", "text"=>"Roboto-Thin.ttf_30"), "gravity"=>"north_west", "color"=>"#FFF000"))
PHP v2:
Copy to clipboard
(new ImageTag('sample.jpg'))
  ->overlay(
      Overlay::source(Source::text('Roboto-Thin.ttf_30', (new TextStyle('fonts')))
        ->textColor(Color::rgb('FFF000')))
      ->position((new Position())
        ->gravity(Gravity::compass(Compass::northWest()))
  ));
Python:
Copy to clipboard
CloudinaryImage("sample.jpg").image(overlay={'public_id': "fonts", 'text': "Roboto-Thin.ttf_30"}, gravity="north_west", color="#FFF000")
Node.js:
Copy to clipboard
cloudinary.image("sample.jpg", {overlay: {public_id: "fonts", text: "Roboto-Thin.ttf_30"}, gravity: "north_west", color: "#FFF000"})
Java:
Copy to clipboard
cloudinary.url().transformation(new Transformation().overlay(new TextLayer().text("Roboto-Thin.ttf_30").publicId("fonts")).gravity("north_west").color("#FFF000")).imageTag("sample.jpg");
JS:
Copy to clipboard
cloudinary.imageTag('sample.jpg', {overlay: new cloudinary.TextLayer().text("Roboto-Thin.ttf_30").publicId("fonts"), gravity: "north_west", color: "#FFF000"}).toHtml();
jQuery:
Copy to clipboard
$.cloudinary.image("sample.jpg", {overlay: new cloudinary.TextLayer().text("Roboto-Thin.ttf_30").publicId("fonts"), gravity: "north_west", color: "#FFF000"})
React:
Copy to clipboard
<Image publicId="sample.jpg" >
  <Transformation overlay={{text: "Roboto-Thin.ttf_30", publicId: "fonts"}} gravity="north_west" color="#FFF000" />
</Image>
Vue.js:
Copy to clipboard
<cld-image publicId="sample.jpg" >
  <cld-transformation :overlay="{text: 'Roboto-Thin.ttf_30', publicId: 'fonts'}" gravity="north_west" color="#FFF000" />
</cld-image>
Angular:
Copy to clipboard
<cl-image public-id="sample.jpg" >
  <cl-transformation overlay="text:fonts:Roboto-Thin.ttf_30:Happy%20New%20Year%21" gravity="north_west" color="#FFF000">
  </cl-transformation>
</cl-image>
.NET:
Copy to clipboard
cloudinary.Api.UrlImgUp.Transform(new Transformation().Overlay(new TextLayer().Text("Roboto-Thin.ttf_30").PublicId("fonts")).Gravity("north_west").Color("#FFF000")).BuildImageTag("sample.jpg")
Android:
Copy to clipboard
MediaManager.get().url().transformation(new Transformation().overlay(new TextLayer().text("Roboto-Thin.ttf_30").publicId("fonts")).gravity("north_west").color("#FFF000")).generate("sample.jpg");
iOS:
Copy to clipboard
imageView.cldSetImage(cloudinary.createUrl().setTransformation(CLDTransformation().setOverlay("text:fonts:Roboto-Thin.ttf_30:Happy%20New%20Year%21").setGravity("north_west").setColor("#FFF000")).generate("sample.jpg")!, cloudinary: cloudinary)
Sample 2

To add an overlay with multiple lines, you must construct chained transformations with multiple components, each implementing a specific section of the overlay. The more requirements for the overlay, the more complex the related image URL. Even though the Media Library UI offers shortcuts, becoming adept with the procedure takes time and practice. Also, nontechnical professionals, who are often tasked with creating text overlays, might take longer to familiarize with the URL format and the UI.

Creating Overlays With an Intuitive Tool

For a simpler alternative, leverage this text-overlay tool, an HTML-JavaScript app through which you can input the following details for an overlay:

  • The text
  • The font face
  • The font size
  • The position of the text line

You can set up a maximum of three such overlays, each one with its own text, font face, font size, and position.

Example

Suppose you’d like to create a three-line text overlay with the following properties for an image and position the lines at different places of the image:

Text Color (RGB) Size
Have no fear. . . FFF000 (yellow) 30
A COVID-19 vaccine is here! 000FFF (blue) 35
Let’s hope 2021 will turn out to be better than 2020. F0F0F0 (gray) 30

Step 1: Identify the Image

Choose an image from your Cloudinary account’s Media Library by clicking INSERT IMAGE at the top, which then takes you to the library, in which you can search or navigate to the image. See the demo below.

Step 2: Input the Text Lines and Specify Their Font Details

Type the text to be overlaid in the text fields. Note that those fields are optional, i.e., you can input between one to three lines of text.

Afterwards, choose the font face and enter the font size you desire.

Step 3: Position the Overlay

Specify the position of the overlay by clicking the PICK button. Alternatively, enter the X and Y coordinates. In this example, the top-left corner is the original position (X=0,Y=0).

In the demo below, I selected the position for the first text line by clicking the image. I then adjusted the position and, with that as the basis, set the position of the second and third text lines.

Step 4: Preview the Image

Verify the setup by clicking the PREVIEW button. To make changes, click CLEAR and edit the settings.

Step 5: Generate the Image With Overlay

Once you are happy with the result, click GENERATE to create the image with the overlay. As reference, the tool displays the Cloudinary URL, with which you can embed the image into a webpage or marketing material.

Cloudinary URL

Wrapping Up

With the simple tool described above, you can see your multiline or multifont overlay settings at a glance, configure or edit them with ease, and avoid the complex and often time-consuming process of programmatically creating transformations. Since I built the tool on the existing widgets, I’ll enhance it or add features to it from time to time to improve its usability and robustness. If you like what you've seen, please vote for this tool in our Product Roadmap.

Do give the tool a try. Any problems, please open an issue on GitHub.

Recent Blog Posts

Our $2B Valuation

By
Blackstone Growth Invests in Cloudinary

When we started our journey in 2012, we were looking to improve our lives as developers by making it easier for us to handle the arduous tasks of handling images and videos in our code. That initial line of developer code has evolved into a full suite of media experience solutions driven by a mission that gradually revealed itself over the course of the past 10 years: help companies unleash the full potential of their media to create the most engaging visual experiences.

Read more
Direct-to-Consumer E-Commerce Requires Compelling Visual Experiences

When brands like you adopt a direct–to-consumer (DTC) e-commerce approach with no involvement of retailers or marketplaces, you gain direct and timely insight into evolving shopping behaviors. Accordingly, you can accommodate shoppers’ preferences by continually adjusting your product offering and interspersing the shopping journey with moments of excitement and intrigue. Opportunities abound for you to cultivate engaging customer relationships.

Read more
Automatically Translating Videos for an International Audience

No matter your business focus—public service, B2B integration, recruitment—multimedia, in particular video, is remarkably effective in communicating with the audience. Before, making video accessible to diverse viewers involved tasks galore, such as eliciting the service of production studios to manually dub, transcribe, and add subtitles. Those operations were costly and slow, especially for globally destined content.

Read more
Cloudinary Helps Minted Manage Its Image-Generation Pipeline at Scale

Shoppers return time and again to Minted’s global online community of independent artists and designers because they know they can count on unique, statement-making products of the highest quality there. Concurrently, the visual imagery on Minted.com must do justice to the designs into which the creators have poured their hearts and souls. For Minted’s VP of Engineering David Lien, “Because we are a premium brand, we need to ensure that every single one of our product images matches the selected configuration exactly. For example, if you pick an 18x24 art print on blue canvas, we will show that exact combination on the hero images in the PDF.”

Read more
Highlights on ImageCon 2021 and a Preview of ImageCon 2022

New year, same trend! Visual media will continue to play a monumental role in driving online conversions. To keep up with visual-experience trends and best practices, Cloudinary holds an annual conference called ImageCon, a one-of-a-kind event that helps attendees create the most engaging visual experiences possible.

Read more