Cloudinary Blog

Embed Images in Email Campaigns at Scale

By Sourav Kundu
Embed Images in Email Campaigns at Scale

tl;dr

Cloudinary is a powerful media management solution for email marketing campaigns of any size. With features such as advanced image optimization and on-the-fly image transformation, backed by a global CDN, Cloudinary provides the base for a seamless user experience in your email campaigns leading to increased conversion and performance.


We live in an era of information overload and attention is the real currency. Marketers are constantly looking for new ways to reach you, to advertise products and services that they think could improve your lives.

SnapChat and Instagram Stories are the newest channels marketers are trying to leverage. But there’s one tried-and-true channel that has proven its dominance for reaching your audience… and it’s none other than email marketing.

There are times when Marketing and IT must work together to implement multiple email marketing campaigns under a predefined budget.

Here’s the catch - our email database is really big. Large enough that any traditional email marketing software, such as Aweber or MailChimp, would cost at least five times more than what we had budgeted.

Clearly, we needed a more feasible solution.

If you are in a similar situation, your options include:

  • Engaging with a marketing automation system such as Marketo and HubSpot
  • Sending emails from your company’s email account

Let’s say you’ve implemented an email delivery solution. The next thing you need to figure out is where to host the images for the HTML used in your email.

Since we know that attention is the real currency, emails must:

  1. Be well-designed
  2. Carry a visual impact
  3. Look seamless across all devices - mobile, tablet and desktop
  4. Load fast

Here’s the deal - points one and two depend on your team’s creativity, and is subjective in nature.

What we can control are points three and four. And that’s where Cloudinary comes in.

Cloudinary is end-to-end, cloud-based solution that enables you to optimize, and transform images on-the-fly. It is designed for almost any service (product, website or app) that requires reliable image delivery.

Too complex? Think of Cloudinary as the perfect email image hosting solution.

I’ve personally used Cloudinary for my email marketing campaigns, and wanted to share how it could help you with yours.

While I’m not going to dive into all the features Cloudinary has to offer, I will discuss the features that:

  • Help improve user experience
  • Reduce resource consumption
  • Do a combination of both

Let’s take a look at these features, shall we?

On-the-Fly Image Optimization

We all need high-quality images for email marketing that load fast. One of the very basic, yet fundamentally important, features Cloudinary offers is on-the-fly image transformation capabilities.

For starters, every image you upload is optimized and stored in Cloudinary’s servers. Only the optimized version of the image (which, by the way has negligible loss in quality) is served to the end user. This approach saves bandwidth costs for both you and the end user. Plus, the email loads faster on the user’s device (mobile or desktop), resulting in a better user experience.

On-Demand Image Resizing and Transformation

Mobile screens are smaller, and therefore can benefit from use of smaller images. You don’t need a 1080p image for a email that’s primarily going to be viewed on a phone.

Whatever the device, Cloudinary enables me to configure the image resolution by defining the single parameter in the request URL. I don’t need to upload two (or more) versions of the image to Cloudinary. By changing just one parameter in the URL, I can quickly test which resolution works best. This is incredibly useful in A/B testing and designing emails.

For example, I use this simple command to resize the image:

Ruby:
Copy to clipboard
cl_image_tag("sample.jpg", :transformation=>[
  {:width=>300, :crop=>"scale"},
  {:opacity=>50}
  ])
PHP v1:
Copy to clipboard
cl_image_tag("sample.jpg", array("transformation"=>array(
  array("width"=>300, "crop"=>"scale"),
  array("opacity"=>50)
  )))
PHP v2:
Copy to clipboard
(new ImageTag('sample.jpg'))
  ->resize(Resize::scale()->width(300))
  ->adjust(Adjust::opacity(50));
Python:
Copy to clipboard
CloudinaryImage("sample.jpg").image(transformation=[
  {'width': 300, 'crop': "scale"},
  {'opacity': 50}
  ])
Node.js:
Copy to clipboard
cloudinary.image("sample.jpg", {transformation: [
  {width: 300, crop: "scale"},
  {opacity: 50}
  ]})
Java:
Copy to clipboard
cloudinary.url().transformation(new Transformation()
  .width(300).crop("scale").chain()
  .opacity(50)).imageTag("sample.jpg");
JS:
Copy to clipboard
cloudinary.imageTag('sample.jpg', {transformation: [
  {width: 300, crop: "scale"},
  {opacity: 50}
  ]}).toHtml();
jQuery:
Copy to clipboard
$.cloudinary.image("sample.jpg", {transformation: [
  {width: 300, crop: "scale"},
  {opacity: 50}
  ]})
React:
Copy to clipboard
<Image publicId="sample.jpg" >
  <Transformation width="300" crop="scale" />
  <Transformation opacity="50" />
</Image>
Vue.js:
Copy to clipboard
<cld-image publicId="sample.jpg" >
  <cld-transformation width="300" crop="scale" />
  <cld-transformation opacity="50" />
</cld-image>
Angular:
Copy to clipboard
<cl-image public-id="sample.jpg" >
  <cl-transformation width="300" crop="scale">
  </cl-transformation>
  <cl-transformation opacity="50">
  </cl-transformation>
</cl-image>
.NET:
Copy to clipboard
cloudinary.Api.UrlImgUp.Transform(new Transformation()
  .Width(300).Crop("scale").Chain()
  .Opacity(50)).BuildImageTag("sample.jpg")
Android:
Copy to clipboard
MediaManager.get().url().transformation(new Transformation()
  .width(300).crop("scale").chain()
  .opacity(50)).generate("sample.jpg");
iOS:
Copy to clipboard
imageView.cldSetImage(cloudinary.createUrl().setTransformation(CLDTransformation()
  .setWidth(300).setCrop("scale").chain()
  .setOpacity(50)).generate("sample.jpg")!, cloudinary: cloudinary)
Flowers

The w_300 tells the Cloudinary API to resize the image to a width of 300px. The height is adjusted automatically, thus maintaining the aspect ratio of the image.

There are tons of other image transformation features mentioned in Cloudinary’s documentation.

Changing the Image, But Keeping the Same URL

This feature is a lifesaver when it comes to email marketing. Imagine spending hours crafting the perfect email, designing it over the course of a week. You embed the image in the email’s HTML file. Everything looks good.

On the day the campaign kicks off, you’re a bit nervous and after several checks, you press the send (or schedule) button. You grab a coffee and moments later you realize that the header image has a unexcusable, hair-raising typo. Think “End of Season Sale. Grab yourself a umbrella.”

If you’ve scheduled the campaign, there’s still hope. You can pause and fix the error. But what if your campaign is already being sent?

Here’s what I did:

  • Quickly fix the image.
  • Head over to Cloudinary’s dashboard and update the image.
  • Continue enjoying the coffee.

Winning the Battle Against Broken CSS Support

Here’s the deal - CSS support is shaky in most email clients. Some work, some don’t. There just isn’t seamless support for CSS in them.

When experimenting with Cloudinary, I found two particularly useful, on-the-fly image transformation features.

Opacity Transformation

The first feature is opacity transformation. In simple terms, this feature enables you to change the opacity of the image, on-the-fly.

If you’re using a background image in your email, opacity plays a major role in the contrast.

You might wonder - which email client does not support CSS opacity? You’d be surprised.

Note
MailChimp has this handy resource on CSS compatibility in various email clients.

The following email clients do not support CSS opacity:

  1. Gmail and Yahoo! web clients
  2. Microsoft Outlook 2000 - 2013 (desktop versions for Windows)
  3. Windows Live Mail (for those still on Windows 7)
  4. Gmail app for Android and iOS phones

The only desktop clients that do support CSS opacity are Apple Mail and Outlook 2013 for Mac.

This is where Cloudinary comes in.

In Cloudinary, you can easily transform the opacity of the image by adding the o_XX parameter. XX represents the digits of the opacity percentage.

For example, to display an image at 50 percent opacity, we add the parameter o_50 in the following URL:

Ruby:
Copy to clipboard
cl_image_tag("sample.jpg", :opacity=>50)
PHP v1:
Copy to clipboard
cl_image_tag("sample.jpg", array("opacity"=>50))
PHP v2:
Copy to clipboard
(new ImageTag('sample.jpg'))
  ->adjust(Adjust::opacity(50));
Python:
Copy to clipboard
CloudinaryImage("sample.jpg").image(opacity=50)
Node.js:
Copy to clipboard
cloudinary.image("sample.jpg", {opacity: 50})
Java:
Copy to clipboard
cloudinary.url().transformation(new Transformation().opacity(50)).imageTag("sample.jpg");
JS:
Copy to clipboard
cloudinary.imageTag('sample.jpg', {opacity: 50}).toHtml();
jQuery:
Copy to clipboard
$.cloudinary.image("sample.jpg", {opacity: 50})
React:
Copy to clipboard
<Image publicId="sample.jpg" >
  <Transformation opacity="50" />
</Image>
Vue.js:
Copy to clipboard
<cld-image publicId="sample.jpg" >
  <cld-transformation opacity="50" />
</cld-image>
Angular:
Copy to clipboard
<cl-image public-id="sample.jpg" >
  <cl-transformation opacity="50">
  </cl-transformation>
</cl-image>
.NET:
Copy to clipboard
cloudinary.Api.UrlImgUp.Transform(new Transformation().Opacity(50)).BuildImageTag("sample.jpg")
Android:
Copy to clipboard
MediaManager.get().url().transformation(new Transformation().opacity(50)).generate("sample.jpg");
iOS:
Copy to clipboard
imageView.cldSetImage(cloudinary.createUrl().setTransformation(CLDTransformation().setOpacity(50)).generate("sample.jpg")!, cloudinary: cloudinary)
Flowers Example of an image at 50 percent opacity, transformed dynamically

Now you can forget about the compatibility issues and design the newsletter!

CSS Sprite Generation

You can combine multiple logos into a single sprite image by using Cloudinary’s sprite-generation capabilities. This makes image management easier and gives better performance.

The sprite generation feature is useful in the email footers, where you want to showcase your clientele or partners. It helps establish trust in the product you’re marketing and uplifts your brand’s image.

For example, let’s say you’re a cloud-aggregator startup, specializing in managed CMS hosting. In other words you help setup and manage your client’s websites in cloud hosting companies.

In this role, you support the top four cloud hosting companies - AWS, Microsoft Azure, Google Cloud and IBM Cloud. You upload their logos in Cloudinary with a common tag - let’s say “supported_cloud”.

With Cloudinary’s sprite generation feature, you could display a single image that combines all the images with the supported_cloud tag. The, with a few CSS commands, you can display the logos in various sections of the footer.

Cloud Services

This improves user experience by reducing network overhead and bypassing download limitations.

On-the-Fly Image Transformation

Image transformation comes in handy when you need to add a watermark to your images. A classic example would be screenshots of your SaaS dashboard, used in a drip email campaign.

And the best part? I don’t have to add the watermark to the image myself. All I need to do is configure the image URL and Cloudinary serves the watermarked version of the image to the end user.

Advanced Reporting

Cloudinary provides an intuitive dashboard that gives you a bird’s-eye view of your image stats. Dashboard Screenshot of the Cloudinary Dashboard Report (Demo)

How many images were transformed on-the-fly? Storage quota consumed? Bandwidth used? These stats are presented in a beautiful graph. You can breakdown the report by month, or more granularly at a daily level. Interestingly I find that the bandwidth consumption correlates with the open-rate of my mailing lists.

Account Details Download API information in one-click from the Cloudinary dashboard

Note
Cloudinary displays your account details at the very top of the dashboard. Developers also can download the API access credentials in Python or YML in a single click.

Browser-based Image Format

This feature is, by far, one of my favorite things in Cloudinary. Browsers have evolved tremendously over the years. From being able to view simple text documents, to images and video. Today I am writing this article on Google Docs.

Each browser now supports a distinct type of image, that’s only applicable to, or supported by, that browser. For example, Google introduced the WebP image format back in 2010, which offers significant saving compared to JPEG. Only Google Chrome supports the WebP.

JPG Image
16.9KB JPG
WebP Automatic Image
6.9KB WebP

Similarly Microsoft announced JPEG-XR format in 2009, which offers better image compression than the original JPEG. It is supported in Internet Explorer 9 or above.

Here’s how Cloudinary creates the magic. With the Automatic Format Selection feature, Cloudinary automatically serves different formats of the image, based on the requesting browser. For example, it serves the WebP version of the image to Google Chrome users and JPEG-XR version of the image to Internet Explorer 9+ users. If the browser does not support these modern image formats, the default optimized JPEG is served.

Cloudinary does all of this on-the-fly, without us having to manually convert or upload multiple versions of the image. Simply add f_auto parameter to the requesting URL and the corresponding format would be served in the browser.

Ruby:
Copy to clipboard
cl_image_tag("sample.jpg", :width=>300, :opacity=>50, :crop=>"scale")
PHP v1:
Copy to clipboard
cl_image_tag("sample.jpg", array("width"=>300, "opacity"=>50, "crop"=>"scale"))
PHP v2:
Copy to clipboard
(new ImageTag('sample.jpg'))
  ->resize(Resize::scale()->width(300))
  ->adjust(Adjust::opacity(50));
Python:
Copy to clipboard
CloudinaryImage("sample.jpg").image(width=300, opacity=50, crop="scale")
Node.js:
Copy to clipboard
cloudinary.image("sample.jpg", {width: 300, opacity: 50, crop: "scale"})
Java:
Copy to clipboard
cloudinary.url().transformation(new Transformation().width(300).opacity(50).crop("scale")).imageTag("sample.jpg");
JS:
Copy to clipboard
cloudinary.imageTag('sample.jpg', {width: 300, opacity: 50, crop: "scale"}).toHtml();
jQuery:
Copy to clipboard
$.cloudinary.image("sample.jpg", {width: 300, opacity: 50, crop: "scale"})
React:
Copy to clipboard
<Image publicId="sample.jpg" >
  <Transformation width="300" opacity="50" crop="scale" />
</Image>
Vue.js:
Copy to clipboard
<cld-image publicId="sample.jpg" >
  <cld-transformation width="300" opacity="50" crop="scale" />
</cld-image>
Angular:
Copy to clipboard
<cl-image public-id="sample.jpg" >
  <cl-transformation width="300" opacity="50" crop="scale">
  </cl-transformation>
</cl-image>
.NET:
Copy to clipboard
cloudinary.Api.UrlImgUp.Transform(new Transformation().Width(300).Opacity(50).Crop("scale")).BuildImageTag("sample.jpg")
Android:
Copy to clipboard
MediaManager.get().url().transformation(new Transformation().width(300).opacity(50).crop("scale")).generate("sample.jpg");
iOS:
Copy to clipboard
imageView.cldSetImage(cloudinary.createUrl().setTransformation(CLDTransformation().setWidth(300).setOpacity(50).setCrop("scale")).generate("sample.jpg")!, cloudinary: cloudinary)
Flowers Using the Automatic Format Selection feature in Cloudinary, this same image would be served as WebP in Google Chrome or as JPEG in Firefox.

Browser-dependent image format rendering saves a lot of bandwidth when the email is viewed in a web browser, or when the HTML version of the email is viewed online.

Compress GIFs On-the-Fly

We started this article with the premise that attention is the most valuable currency in today’s world. When it comes to email marketing, getting someone to open the email depends on the quality of the subject line.

Our goal is to grab the user’s attention, right after he or she opens the email. That’s where an image comes in. A good header image can do wonders. What if we could take that one step further? What if we could crunch more relevant information into a single place, without requiring the user to scroll down?

That’s where videos come in. But unfortunately, videos are not supported in emails. That’s why you should use GIFs. You can keep the same information, and do away with the heavy size or the technical complexities of implementing the video.

Cloudinary supports animated GIFs, and with a few parameters, you can create winning emails!

Ruby:
Copy to clipboard
cl_image_tag("kitten_fighting.gif")
PHP v1:
Copy to clipboard
cl_image_tag("kitten_fighting.gif")
PHP v2:
Copy to clipboard
(new ImageTag('kitten_fighting.gif'));
Python:
Copy to clipboard
CloudinaryImage("kitten_fighting.gif").image()
Node.js:
Copy to clipboard
cloudinary.image("kitten_fighting.gif")
Java:
Copy to clipboard
cloudinary.url().imageTag("kitten_fighting.gif");
JS:
Copy to clipboard
cloudinary.imageTag('kitten_fighting.gif').toHtml();
jQuery:
Copy to clipboard
$.cloudinary.image("kitten_fighting.gif")
React:
Copy to clipboard
<Image publicId="kitten_fighting.gif" >

</Image>
Vue.js:
Copy to clipboard
<cld-image publicId="kitten_fighting.gif" >

</cld-image>
Angular:
Copy to clipboard
<cl-image public-id="kitten_fighting.gif" >

</cl-image>
.NET:
Copy to clipboard
cloudinary.Api.UrlImgUp.BuildImageTag("kitten_fighting.gif")
Android:
Copy to clipboard
MediaManager.get().url().generate("kitten_fighting.gif");
iOS:
Copy to clipboard
imageView.cldSetImage(cloudinary.createUrl().generate("kitten_fighting.gif")!, cloudinary: cloudinary)
Kitten Animated GIF served by Cloudinary

You can apply almost all the transformation effects to the GIFs (plus a few special ones). In our example, let’s serve the browser optimized format of the GIF.

Consider the following URL:

Ruby:
Copy to clipboard
cl_image_tag("kitten_fighting.gif", :fetch_format=>:auto)
PHP v1:
Copy to clipboard
cl_image_tag("kitten_fighting.gif", array("fetch_format"=>"auto"))
PHP v2:
Copy to clipboard
(new ImageTag('kitten_fighting'))
  ->delivery(Delivery::format(Format::auto()));
Python:
Copy to clipboard
CloudinaryImage("kitten_fighting.gif").image(fetch_format="auto")
Node.js:
Copy to clipboard
cloudinary.image("kitten_fighting.gif", {fetch_format: "auto"})
Java:
Copy to clipboard
cloudinary.url().transformation(new Transformation().fetchFormat("auto")).imageTag("kitten_fighting.gif");
JS:
Copy to clipboard
cloudinary.imageTag('kitten_fighting.gif', {fetchFormat: "auto"}).toHtml();
jQuery:
Copy to clipboard
$.cloudinary.image("kitten_fighting.gif", {fetch_format: "auto"})
React:
Copy to clipboard
<Image publicId="kitten_fighting.gif" >
  <Transformation fetchFormat="auto" />
</Image>
Vue.js:
Copy to clipboard
<cld-image publicId="kitten_fighting.gif" >
  <cld-transformation fetchFormat="auto" />
</cld-image>
Angular:
Copy to clipboard
<cl-image public-id="kitten_fighting.gif" >
  <cl-transformation fetch-format="auto">
  </cl-transformation>
</cl-image>
.NET:
Copy to clipboard
cloudinary.Api.UrlImgUp.Transform(new Transformation().FetchFormat("auto")).BuildImageTag("kitten_fighting.gif")
Android:
Copy to clipboard
MediaManager.get().url().transformation(new Transformation().fetchFormat("auto")).generate("kitten_fighting.gif");
iOS:
Copy to clipboard
imageView.cldSetImage(cloudinary.createUrl().setTransformation(CLDTransformation().setFetchFormat("auto")).generate("kitten_fighting.gif")!, cloudinary: cloudinary)
Kitten

If you’re in Google Chrome or Opera, the f_auto parameter would have converted the GIF into an animated WebP file.

The Round-Up

Here’s a quick round-up of what we’ve covered so far:

  • Cloudinary automatically optimizes all the images on-the-fly.
  • You can resize and apply other on-demand transformation effects to your images.
  • You can change the image, while retaining the same URL.
  • Cloudinary’s opacity transformation and sprite generation features enables you to seamlessly design email campaigns that looks the same across all clients.
  • With on-the-fly image transformation, you can generate watermarked versions of images, which are excellent to prevent email spams.
  • Cloudinary’s advanced analytics and reporting enables you to track your usage at all times.
  • Browser-based image format reporting delivers the image in the most optimal format, that is supported by the web browser.
  • Cloudinary also can optimize and apply various transformation effects to animated GIF images.

We’ve only begun to learn about Cloudinary’s amazing suite of image transformation features. What we’ve discussed in the context of email marketing barely scratches the surface of the robust feature set offered by Cloudinary.

The good news is that all of these features would be applicable in multiple scenarios, in one way or the other. Did you know that Cloudinary serves these images via a global network of content delivery networks such as Akamai, Amazon Cloudfront and Fastly?

If you are looking to take your email marketing to the next level, Cloudinary is an excellent partner. The free Cloudinary account provides you enough quota to test the service and even possibly launch a trial email campaign.

Have you considered using Cloudinary in your email marketing programme? Let us know!

Sourav Kundu Sourav Kundu is an avid marketer with a passion for all things digital. From email marketing to app re-engagement campaigns, he loves putting on multiple hats during the workday. He's available for consultation over Twitter or his website.

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