Cloudinary Blog

Techniques for Image Enhancement With Cloudinary: A Primer

Techniques for Image Enhancement With Cloudinary

Indisputably, visual presentations of events, places, people, and even intangible things make deeper impressions and linger in our minds for longer than words or any other communication medium, hence the meteoric rise through the ages of transmitting ideas and promoting brands in the business sector through images. The recent discovery of the first image of a black hole has generated calls for techniques for enhancing digital images. Specifically, the clamor is for quality-oriented tweaks that would result in optimal display and increased visibility of slightly hidden yet important content.

This post shows you how to enhance images by setting intuitive and effective parameters on Cloudinary with a focus on several key aspects, including brightness, contrast, and sharpness. Also described are sophisticated enhancements you can add with Cloudinary add-on VIESUS and the simple steps for optimizing images on Cloudinary.

Webinar
How to Optimize for Page Load Speed

Image Enhancement Techniques

Adjusting the Brightness and Contrast

One of the image enhancement techniques you can utilize is to have Cloudinary automatically adjust the brightness and contrast of an image, set one of the following values for the effect parameter:

gamma, auto_brightness, auto_contrast, contrast, auto_color, fill_light, vibrance, and improve:outdoor.

In particular:

  • improve:outdoor enhances an image’s colors, contrast, and brightness, as in the code example below:

    Copy to clipboard
    <cl-image public-id="flower.jpg" >
    <cl-transformation effect="improve:outdoor">
    </cl-transformation>
    </cl-image>
  • contrast raises or reduces an image’s contrast level according to the value you specify. The default value is 0; the minimum value is -300; and the maximum value is +100.

    This code shows the syntax for a contrast value of 50:

    Copy to clipboard
    <cl-image public-id="wardrobe.jpg" >
    <cl-transformation effect="contrast:50">
    </cl-transformation>
    </cl-image>

Boosting the Sharpness

But of course, sharp images make a world of a difference to the audience. To sharpen an image, set the sharpen value for the effect parameter, as in this example:

Copy to clipboard
<cl-image public-id="front_face.jpg" >
  <cl-transformation effect="sharpen">
  </cl-transformation>
</cl-image>

Furthermore, to specify the exact effect you desire, add one of the following values to sharpen, preceded by a colon, e.g., sharpen:blur:blur, blur_region, blur_faces, unsharp_mask, pixelate, pixelate_region, pixelate_faces, ordered_dither, vignette, gradient_fade, or tilt_shift.

Set the Color Intensity

Cloudinary offers numerous color-related values for the effect parameter, including the following:

hue, red, green, blue, negate, grayscale, blackwhite, saturation, colorize, assist_colorblind, simulate_colorblind, replace_color, recolor, tint, and auto_color

Note
Try injecting your own image processing by using a custom function

As their names imply, by setting one of those effect values on an image, you can change its color intensity, correct its color imbalance, or apply colorization filters. You can also remove colors, replace them, or fix problems that pertain to colorblindness for accessibility.

This example specifies a saturation value with an intensity of 50 for an image:

Copy to clipboard
<cl-image public-id="sample.jpg" >
  <cl-transformation effect="saturation:50">
  </cl-transformation>
</cl-image>

Applying Advanced Image Enhancements With Cloudinary Add-On VIESUS

With Cloudinary, you can perform numerous basic tasks geared toward beefing up your images: image cropping, resizing images without losing quality, add overlays to them, remove their background, and so forth. For more advanced tasks, tap into Cloudinary’s add-on repository for the VIESUS capabilities that automate those tasks.

All you need to do is set the effect parameter to viesus_correct, after which VIESUS would elevate the visual quality of your image to the maximum. See the examples below.

  • On the Angular Framework

    Copy to clipboard
    <cl-image public-id="gate.jpg" sign-url="true">
    <cl-transformation effect="viesus_correct" width="350" crop="scale">
    </cl-transformation>
    </cl-image>
  • On the Node.js Runtime Environment

    Copy to clipboard
    cloudinary.v2.uploader.upload("local_file.jpg", 
    { public_id: "beach", 
    eager: { effect: "viesus_correct", crop: "scale", width: 400 }}),
    function(error, result) {console.log(result, error); });

For an enlightening example, see the image below for its original version, followed by the VIESUS-enhanced version:

Ruby:
Copy to clipboard
cl_image_tag("golden_gate_side.jpg", :transformation=>[
  {:gravity=>"east", :height=>0.35, :width=>0.8, :crop=>"crop"},
  {:gravity=>"north_east", :overlay=>"viesus_icon", :opacity=>40, :width=>400, :x=>10, :y=>10, :crop=>"scale"},
  {:radius=>20, :width=>600, :crop=>"scale"}
  ])
PHP v1:
Copy to clipboard
cl_image_tag("golden_gate_side.jpg", array("transformation"=>array(
  array("gravity"=>"east", "height"=>"0.35", "width"=>"0.8", "crop"=>"crop"),
  array("gravity"=>"north_east", "overlay"=>"viesus_icon", "opacity"=>40, "width"=>400, "x"=>10, "y"=>10, "crop"=>"scale"),
  array("radius"=>20, "width"=>600, "crop"=>"scale")
  )))
PHP v2:
Copy to clipboard
(new ImageTag('golden_gate_side.jpg'))
  ->resize(Resize::crop()->width(0.8)->height(0.35)->gravity(Gravity::compass(Compass::east())))
  ->overlay(
      Overlay::source(Source::image('viesus_icon')
        ->transformation((new ImageTransformation())
          ->resize(Resize::scale()->width(400))
          ->adjust(Adjust::opacity(40))))
      ->position((new Position())
        ->gravity(Gravity::compass(Compass::northEast()))
        ->offsetX(10)->offsetY(10)))
    ->resize(Resize::scale()->width(600))
    ->roundCorners(RoundCorners::byRadius(20));
Python:
Copy to clipboard
CloudinaryImage("golden_gate_side.jpg").image(transformation=[
  {'gravity': "east", 'height': "0.35", 'width': "0.8", 'crop': "crop"},
  {'gravity': "north_east", 'overlay': "viesus_icon", 'opacity': 40, 'width': 400, 'x': 10, 'y': 10, 'crop': "scale"},
  {'radius': 20, 'width': 600, 'crop': "scale"}
  ])
Node.js:
Copy to clipboard
cloudinary.image("golden_gate_side.jpg", {transformation: [
  {gravity: "east", height: "0.35", width: "0.8", crop: "crop"},
  {gravity: "north_east", overlay: "viesus_icon", opacity: 40, width: 400, x: 10, y: 10, crop: "scale"},
  {radius: 20, width: 600, crop: "scale"}
  ]})
Java:
Copy to clipboard
cloudinary.url().transformation(new Transformation()
  .gravity("east").height(0.35).width(0.8).crop("crop").chain()
  .gravity("north_east").overlay(new Layer().publicId("viesus_icon")).opacity(40).width(400).x(10).y(10).crop("scale").chain()
  .radius(20).width(600).crop("scale")).imageTag("golden_gate_side.jpg");
JS:
Copy to clipboard
cloudinary.imageTag('golden_gate_side.jpg', {transformation: [
  {gravity: "east", height: "0.35", width: "0.8", crop: "crop"},
  {gravity: "north_east", overlay: new cloudinary.Layer().publicId("viesus_icon"), opacity: 40, width: 400, x: 10, y: 10, crop: "scale"},
  {radius: 20, width: 600, crop: "scale"}
  ]}).toHtml();
jQuery:
Copy to clipboard
$.cloudinary.image("golden_gate_side.jpg", {transformation: [
  {gravity: "east", height: "0.35", width: "0.8", crop: "crop"},
  {gravity: "north_east", overlay: new cloudinary.Layer().publicId("viesus_icon"), opacity: 40, width: 400, x: 10, y: 10, crop: "scale"},
  {radius: 20, width: 600, crop: "scale"}
  ]})
React:
Copy to clipboard
<Image publicId="golden_gate_side.jpg" >
  <Transformation gravity="east" height="0.35" width="0.8" crop="crop" />
  <Transformation gravity="north_east" overlay="viesus_icon" opacity="40" width="400" x="10" y="10" crop="scale" />
  <Transformation radius="20" width="600" crop="scale" />
</Image>
Vue.js:
Copy to clipboard
<cld-image publicId="golden_gate_side.jpg" >
  <cld-transformation gravity="east" height="0.35" width="0.8" crop="crop" />
  <cld-transformation gravity="north_east" :overlay="viesus_icon" opacity="40" width="400" x="10" y="10" crop="scale" />
  <cld-transformation radius="20" width="600" crop="scale" />
</cld-image>
Angular:
Copy to clipboard
<cl-image public-id="golden_gate_side.jpg" >
  <cl-transformation gravity="east" height="0.35" width="0.8" crop="crop">
  </cl-transformation>
  <cl-transformation gravity="north_east" overlay="viesus_icon" opacity="40" width="400" x="10" y="10" crop="scale">
  </cl-transformation>
  <cl-transformation radius="20" width="600" crop="scale">
  </cl-transformation>
</cl-image>
.NET:
Copy to clipboard
cloudinary.Api.UrlImgUp.Transform(new Transformation()
  .Gravity("east").Height(0.35).Width(0.8).Crop("crop").Chain()
  .Gravity("north_east").Overlay(new Layer().PublicId("viesus_icon")).Opacity(40).Width(400).X(10).Y(10).Crop("scale").Chain()
  .Radius(20).Width(600).Crop("scale")).BuildImageTag("golden_gate_side.jpg")
Android:
Copy to clipboard
MediaManager.get().url().transformation(new Transformation()
  .gravity("east").height(0.35).width(0.8).crop("crop").chain()
  .gravity("north_east").overlay(new Layer().publicId("viesus_icon")).opacity(40).width(400).x(10).y(10).crop("scale").chain()
  .radius(20).width(600).crop("scale")).generate("golden_gate_side.jpg");
iOS:
Copy to clipboard
imageView.cldSetImage(cloudinary.createUrl().setTransformation(CLDTransformation()
  .setGravity("east").setHeight(0.35).setWidth(0.8).setCrop("crop").chain()
  .setGravity("north_east").setOverlay("viesus_icon").setOpacity(40).setWidth(400).setX(10).setY(10).setCrop("scale").chain()
  .setRadius(20).setWidth(600).setCrop("scale")).generate("golden_gate_side.jpg")!, cloudinary: cloudinary)
Golden Gate

Ruby:
Copy to clipboard
cl_image_tag("golden_gate_side.jpg", :sign_url=>true, :transformation=>[
  {:effect=>"viesus_correct", :gravity=>"east", :height=>0.35, :width=>0.8, :crop=>"crop"},
  {:gravity=>"north_east", :overlay=>"viesus_icon", :opacity=>40, :width=>400, :x=>10, :y=>10, :crop=>"scale"},
  {:radius=>20, :width=>600, :crop=>"scale"}
  ])
PHP v1:
Copy to clipboard
cl_image_tag("golden_gate_side.jpg", array("sign_url"=>true, "transformation"=>array(
  array("effect"=>"viesus_correct", "gravity"=>"east", "height"=>"0.35", "width"=>"0.8", "crop"=>"crop"),
  array("gravity"=>"north_east", "overlay"=>"viesus_icon", "opacity"=>40, "width"=>400, "x"=>10, "y"=>10, "crop"=>"scale"),
  array("radius"=>20, "width"=>600, "crop"=>"scale")
  )))
PHP v2:
Copy to clipboard
(new ImageTag('golden_gate_side.jpg'))
  ->resize(Resize::crop()->width(0.8)->height(0.35)->gravity(Gravity::compass(Compass::east())))
  ->adjust(Adjust::viesusCorrect())
  ->overlay(
      Overlay::source(Source::image('viesus_icon')
        ->transformation((new ImageTransformation())
          ->resize(Resize::scale()->width(400))
          ->adjust(Adjust::opacity(40))))
      ->position((new Position())
        ->gravity(Gravity::compass(Compass::northEast()))
        ->offsetX(10)->offsetY(10)))
    ->resize(Resize::scale()->width(600))
    ->roundCorners(RoundCorners::byRadius(20))
    ->signUrl(true);
Python:
Copy to clipboard
CloudinaryImage("golden_gate_side.jpg").image(sign_url=True, transformation=[
  {'effect': "viesus_correct", 'gravity': "east", 'height': "0.35", 'width': "0.8", 'crop': "crop"},
  {'gravity': "north_east", 'overlay': "viesus_icon", 'opacity': 40, 'width': 400, 'x': 10, 'y': 10, 'crop': "scale"},
  {'radius': 20, 'width': 600, 'crop': "scale"}
  ])
Node.js:
Copy to clipboard
cloudinary.image("golden_gate_side.jpg", {sign_url: true, transformation: [
  {effect: "viesus_correct", gravity: "east", height: "0.35", width: "0.8", crop: "crop"},
  {gravity: "north_east", overlay: "viesus_icon", opacity: 40, width: 400, x: 10, y: 10, crop: "scale"},
  {radius: 20, width: 600, crop: "scale"}
  ]})
Java:
Copy to clipboard
cloudinary.url().transformation(new Transformation()
  .effect("viesus_correct").gravity("east").height(0.35).width(0.8).crop("crop").chain()
  .gravity("north_east").overlay(new Layer().publicId("viesus_icon")).opacity(40).width(400).x(10).y(10).crop("scale").chain()
  .radius(20).width(600).crop("scale")).signed(true).imageTag("golden_gate_side.jpg");
JS:
Copy to clipboard
cloudinary.imageTag('golden_gate_side.jpg', {signUrl: true, transformation: [
  {effect: "viesus_correct", gravity: "east", height: "0.35", width: "0.8", crop: "crop"},
  {gravity: "north_east", overlay: new cloudinary.Layer().publicId("viesus_icon"), opacity: 40, width: 400, x: 10, y: 10, crop: "scale"},
  {radius: 20, width: 600, crop: "scale"}
  ]}).toHtml();
jQuery:
Copy to clipboard
$.cloudinary.image("golden_gate_side.jpg", {transformation: [
  {effect: "viesus_correct", gravity: "east", height: "0.35", width: "0.8", crop: "crop"},
  {gravity: "north_east", overlay: new cloudinary.Layer().publicId("viesus_icon"), opacity: 40, width: 400, x: 10, y: 10, crop: "scale"},
  {radius: 20, width: 600, crop: "scale"}
  ]})
React:
Copy to clipboard
<Image publicId="golden_gate_side.jpg" signUrl="true">
  <Transformation effect="viesus_correct" gravity="east" height="0.35" width="0.8" crop="crop" />
  <Transformation gravity="north_east" overlay="viesus_icon" opacity="40" width="400" x="10" y="10" crop="scale" />
  <Transformation radius="20" width="600" crop="scale" />
</Image>
Vue.js:
Copy to clipboard
<cld-image publicId="golden_gate_side.jpg" signUrl="true">
  <cld-transformation effect="viesus_correct" gravity="east" height="0.35" width="0.8" crop="crop" />
  <cld-transformation gravity="north_east" :overlay="viesus_icon" opacity="40" width="400" x="10" y="10" crop="scale" />
  <cld-transformation radius="20" width="600" crop="scale" />
</cld-image>
Angular:
Copy to clipboard
<cl-image public-id="golden_gate_side.jpg" sign-url="true">
  <cl-transformation effect="viesus_correct" gravity="east" height="0.35" width="0.8" crop="crop">
  </cl-transformation>
  <cl-transformation gravity="north_east" overlay="viesus_icon" opacity="40" width="400" x="10" y="10" crop="scale">
  </cl-transformation>
  <cl-transformation radius="20" width="600" crop="scale">
  </cl-transformation>
</cl-image>
.NET:
Copy to clipboard
cloudinary.Api.UrlImgUp.Transform(new Transformation()
  .Effect("viesus_correct").Gravity("east").Height(0.35).Width(0.8).Crop("crop").Chain()
  .Gravity("north_east").Overlay(new Layer().PublicId("viesus_icon")).Opacity(40).Width(400).X(10).Y(10).Crop("scale").Chain()
  .Radius(20).Width(600).Crop("scale")).Signed(true).BuildImageTag("golden_gate_side.jpg")
Android:
Copy to clipboard
MediaManager.get().url().transformation(new Transformation()
  .effect("viesus_correct").gravity("east").height(0.35).width(0.8).crop("crop").chain()
  .gravity("north_east").overlay(new Layer().publicId("viesus_icon")).opacity(40).width(400).x(10).y(10).crop("scale").chain()
  .radius(20).width(600).crop("scale")).signed(true).generate("golden_gate_side.jpg");
iOS:
Copy to clipboard
imageView.cldSetImage(cloudinary.createUrl().setTransformation(CLDTransformation()
  .setEffect("viesus_correct").setGravity("east").setHeight(0.35).setWidth(0.8).setCrop("crop").chain()
  .setGravity("north_east").setOverlay("viesus_icon").setOpacity(40).setWidth(400).setX(10).setY(10).setCrop("scale").chain()
  .setRadius(20).setWidth(600).setCrop("scale")).generate("golden_gate_side.jpg", signUrl: true)!, cloudinary: cloudinary)
Golden Gate Enhanced

Image Optimization

Optimization techniques for images abound on Cloudinary. Setting them up for automation opens up endless possibilities for transformations.

Below are two examples.

Intelligent Content-Aware Encoding

A simply way of leveraging q_auto is to specify the value auto for an image’s quality parameter, like this:

Copy to clipboard
<cl-image public-id="man.jpg" >
  <cl-transformation quality="auto">
  </cl-transformation>
</cl-image>

Afterwards, q_auto selects the optimal quality-compression level and encoding settings based on the content and format of the image, also the browser in which it is being displayed.

Alternatively, you can set a numerical value, e.g., 60, for the quality parameter, like this:

Copy to clipboard
<cl-image public-id="train.jpg" >
  <cl-transformation quality="60">
  </cl-transformation>
</cl-image>

Here are the value choices for q_auto:

  • q_auto:best: This is the least-aggressive setting, which compresses files as much as possible without compromising their visual quality.
  • q_auto:good: This setting ensures an optimal balance between file size and visual quality, delivering relatively small files.
  • q_auto:eco: This setting delivers smaller files at the cost of a slightly lower visual quality, detectable only on close inspection.
  • q_auto:low: This is the most aggressive setting, which delivers the smallest files at the expense of lower visual quality.

Dynamic Format Selection

Once specified for the fetch-format parameter of your images, as in the following example, f_auto selects the best format for delivering them.

Copy to clipboard
<cl-image public-id="beach_huts.jpg" >
  <cl-transformation width="600" crop="scale">
  </cl-transformation>
  <cl-transformation quality="auto" fetch-format="auto">
  </cl-transformation>
</cl-image>

For more details on image Optimization, see the related Cloudinary documentation.

Trying Things Out

Choices make for flexibility. Do try out the options described in this post and you’ll soon zero in on the ones that best meet your requirements. From then on, enhancing images would be a breeze.


Further Reading on Image Optimization

Recent Blog Posts

Optimize Media to Get Ready for Google’s Core Web Vitals

For years, Google has been updating its search algorithm to prioritize end-user experience, displaying the most relevant and helpful content at the top of search results. The latest—and maybe the most significant—update so far is Core Web Vitals (CWVs), which are new metrics announced a year ago that will, starting in June, begin determining search rankings. With this update, Google is being abundantly clear that visual experience of webpages is paramount.

Read more
Compressing, Resizing, and Optimizing Videos in Laravel

Videos are large media files—in most cases, at least four times larger than images—and are often created for ads, marketing campaigns, and instructional content to convey as much information as possible in a short time. Ensuring that videos do not buffer all the time and that the user’s data is protected from rapid consumption due to heavy page weight must be the modus operandi for all website builders and e-business owners.

Read more
Five Ways to Effectively Manage Online Media

The digital economy is driven by highly visual experiences. After all, viewers process images 60,000 times faster than text. Therefore, it’s no surprise that top-notch visual media has been an essential component of a captivating e-commerce experience for years. Nor is it surprising that visual media’s importance only rose during the COVID-19 pandemic, a reality for all retailers, including our client Levi’s.

Read more
Creating an API With Python Flask to Upload Files to Cloudinary

Code

Cloudinary offers SDKs for many programming languages and frameworks. Even though it also offers an Upload API endpoint for both back-end and front-end code, most developers find the SDKs very helpful. If you're working with a powerful back-end framework like Python Flask, you'll be happy to hear that a Python SDK is now available.
This tutorial walks you through the process of building an API to upload images to Cloudinary. You can also upload other file types, including video and even nonmedia files, with the API.

Read more
How to Use the Cloudinary Media Editor Widget

At Cloudinary, we manage the entire pipeline of media assets for thousands of customers of varying sizes from numerous verticals.

As part of our commitment to support the entire flow of media assets, we are now introducing an intuitive media editing widget: an out­-of­-the-­box, interactive UI providing your users with a set of common image editing actions for immediate use on your website or web app. The widget is interactive and simple, built on Cloudinary's transformation capabilities, and requiring only a few lines of code to integrate. Afterwards, you can seamlessly and effortlessly add content to your site or app with no need for in-house image editing capabilities.

Read more
Shoppable Video Is Becoming Popular in E-Commerce

As pandemic restrictions necessitated, many shopping trips in 2020 took place outside the traditional brick-and-mortar store, or at least void of the physical aisle-browsing experience. Same-day curbside pickup became a safe and convenient alternative, and e-commerce transactions skyrocketed as consumers shopped online. In fact, Digital Commerce 360 estimates that, compared to 2019, e-commerce transactions grew by more than 40% last year.

Read more