JPEGmini Image Optimization Add-on

Overview

Cloudinary is a cloud-based service that provides an end-to-end image management solution including uploads, storage, manipulations, optimizations and delivery.

Cloudinary offers a very rich set of image manipulation and optimization capabilities. Cloudinary seamlessly applies advanced image size shrinking logic to make sure that your images are as small as possible without degrading their viewing quality. In addition, Cloudinary's image transformation supports controlling the JPG quality level in order to control the balance between image file size and display quality.

JPEGmini is a patent-pending JPEG photo optimization technology, which significantly reduces the size of photographs without affecting their perceptual quality. Cloudinary provides an add-on for using JPEGmini's image optimization capabilities, fully integrated into Cloudinary's image management and manipulation pipeline.

With JPEGmini's image optimization add-on, you can extend Cloudinary's powerful image manipulation and optimization capabilities by automatically converting images to their best matching quality for faster delivery. When using the JPEGmini add-on, your images will be automatically optimized using advanced visual algorithms achieving file size reduction while maintaining a very high visual quality.

Using JPEGmini

Before you start, if you haven't done so already, please do the following:

To simplify the add-on integration, you can use Cloudinary's client libraries for: Ruby on Rails, Python & Django, PHP, Node.js, javascript, jQuery, Angular, Java, .NET, iOS, Android and Scala.

Basic usage

Take a look at the following brown_sheep photo that was uploaded to Cloudinary. This image file weighs 207KB.

JPEG images can be created with different quality levels. There's a trade off between the desired reduction in file size and the deterioration in photo quality. Most websites prefer to aim at high quality of all displayed images, therefore they usually embed JPG images of about 90% quality. However, lower quality may still be adequate for different images.

The Cloudinary URL below dynamically converts the image to the best matching JPG quality using the JPEGmini add-on. While the original and smartly converted images look the same, the JPEGmini optimized one weighs just 115KB. This means that we saved 44% of the original image size. Less bytes mean faster loading time, better user experience and reduced bandwidth costs.

Signed URLs

Cloudinary's dynamic image manipulation URLs are quite powerful and enable agile web and mobile development. However, due to the potential costs of users accessing unplanned dynamic URLs with JPEGmini quality directives, we request that you either sign your image manipulation URLs or eagerly generate the requested derived images using Cloudinary's authenticated API.

The following code example generates an image tag with a signed Cloudinary URL by setting the sign_url parameter to true. In order to smart set the JPG quality, the quality transformation parameter is set to jpegmini. In this example, the JPG quality conversion is applied on a 200x150 resized version of the upload image named brown_sheep.

Ruby:
cl_image_tag("brown_sheep.jpg", :crop => :fill, 
  :width => 200, :height => 150, 
  :quality => "jpegmini",
  :sign_url => true)
PHP:
<?php echo cl_image_tag("brown_sheep.jpg", 
  array("crop" => "fill", "width" => 200, "height" => 150,
        "quality" => "jpegmini",
        "sign_url" => true)); ?>
Python:
cloudinary.CloudinaryImage("brown_sheep.jpg").image(
  crop = "fill", width = 200, height = 150,
  quality = "jpegmini", 
  sign_url = True)
Node.js:
cloudinary.image("brown_sheep.jpg", 
  { crop: "fill", width: 200, height: 150, 
    quality: "jpegmini",
    sign_url: true });
Java:
cloudinary.url().transformation(
  new Transformation().crop("fill").width(200).height(150).quality("jpegmini")).
    signed(true).imageTag("brown_sheep.jpg");

As you can see in the example below, the generated Cloudinary URL includes a signature component ('s--ERIdO8k8--'). Only URLs with a valid signature that matches the requested image manipulation will be approved for on-the-fly image manipulation and delivery.

For more details on signed URLs, see the following blog post: On-the-fly image manipulations secured with signed URLs.

Eager transformations

As an alternative to signed URLs, you can eagerly generate all converted images during upload. This way you already use Cloudinary's authenticated API for requesting JPEGmini image optimization, therefore, accessing the generated images can be done using regular unsigned Cloudinary URLs.

The following code sample uploads a local JPG file to Cloudinary, assigns a custom public ID and eagerly generates the same 200x150 thumbnail that was smartly optimized using JPEGmini as in the signed-URL example above.

Ruby:
Cloudinary::Uploader.upload("local_file.jpg", 
  :public_id => "brown_sheep",
  :eager => { :quality => "jpegmini", :crop => "fill", :width => 200, :height => 150 })
PHP:
\Cloudinary\Uploader::upload("local_file.jpg", 
  array(
    "public_id" = "brown_sheep",
    "eager" => 
      array( "quality" => "jpegmini", "crop" => "fill", "width" => 200, "height" => 150 )
    ));
Python:
cloudinary.uploader.upload("local_file.jpg",
  public_id = "brown_sheep",  
  eager = { 'quality': 'jpegmini', 'crop': "fill", 'width': 200, 'height': 150 })
Node.js:
cloudinary.uploader.upload("local_file.jpg", 
  function(result) { console.log(result); }, 
  { public_id: "brown_sheep", 
    eager: { quality: "jpegmini", crop: "fill", width: 200, height: 150 }});
Java:
cloudinary.uploader().upload("local_file.jpg", 
  ObjectUtils.asMap("public_id", "brown_sheep", "eager",
    Arrays.asList(new Transformation().quality("jpegmini").crop("fill").
      width(200).height(150))));

The resized and optimized image is available for delivery immediately when the upload request completes. Therefore, the optimized version can be accessed using an unsigned URL as in the example below:

Optimize JPG images

Optimizing JPG images using the JPEGmini add-on is done by setting the quality transformation parameter to jpegmini. Smart image conversion can be applied on the resulting image following the image scaling as shown in the code snippet below. In this example we generate a direct Cloudinary manipulation and CDN delivery URL.

Ruby:
cloudinary_url("horses.jpg", :crop => :scale, 
  :width => 400,  
  :quality => "jpegmini",
  :sign_url => true)
PHP:
<?php echo cloudinary_url("horses.jpg", 
  array("crop" => "scale", "width" => 400, 
        "quality" => "jpegmini",
        "sign_url" => true)); ?>
Python:
cloudinary.CloudinaryImage("horses.jpg").build_url(
  crop = "scale", width = 400, 
  quality = "jpegmini", 
  sign_url = True)
Node.js:
cloudinary.url("horses.jpg", 
  { crop: "scale", width: 400,  
    quality: "jpegmini",
    sign_url: true });
Java:
cloudinary.url().transformation(
  new Transformation().crop("scale").width(400).quality("jpegmini")).
    signed(true).generate("horses.jpg");

The following resized and optimized image is generated on-the-fly by Cloudinary and delivered cached via a fast CDN. The size of the optimized thumbnail is 24.9KB, which is 27% less than the 34KB of the non JPEGmini optimized image.

Further image manipulations

Smart image optimization using the JPEGmini Cloudinary add-on can be mixed with any of Cloudinary's rich set of image manipulation capabilities.

For example, the following code first scales an uploaded image to a width of 400 pixels while rounding its corners and increasing color saturation by 50%. Then another uploaded image named logo_jpegmini is added as an overlay. The overlay is resized to a width of 100 pixels, positioned 10 pixels from the bottom right corner of the containing image and is made 80% semi transparent. Finally, the automatic JPEGmini quality conversion is applied on the resulting image.

Ruby:
cl_image_tag("horses.jpg", 
  :transformation => [ 
    { :radius => 20, :crop => "scale", :width => 400, :effect => "saturation:50" }, 
    { :overlay => "logo_jpegmini", :width => 100, 
      :x => 10, :y => 10, 
      :gravity => :south_east, :opacity => 80 },
    { :quality => "jpegmini" } ], 
  :sign_url => true)
PHP:
<?php echo cl_image_tag("horses.jpg", 
  array(
    "transformation" => array( 
      array( "radius" => 20, "crop" => "scale", "width" => 400, 
             "effect" => "saturation:50" ), 
      array( "overlay" => "logo_jpegmini", "width" => 100, 
        "x" => 10, "y" => 10, 
        "gravity" => "south_east", "opacity" => 80 ),
      array( "quality" => "jpegmini" )), 
    "sign_url" => true)); ?>
Python:
cloudinary.CloudinaryImage("horses.jpg").image(
 transformation = [ 
     { 'radius': 20, 'crop': 'scale', 'width': 400, 'effect': "saturation:50" }, 
     { 'overlay': "logo_jpegmini", 'width': 100, 
       'x': 10, 'y': 10, 
       'gravity': "south_east", 'opacity': 80 },
     { 'quality': "jpegmini" }],
   sign_url = True)
Node.js:
cloudinary.image("horses.jpg", 
  { transformation: [ 
    { radius: 20, crop: 'scale', width: 400, effect: "saturation:50" }, 
    { overlay: "logo_jpegmini", width: 100, 
      x: 10, y: 10, 
      gravity: "south_west", opacity: 80 },
    { quality: "jpegmini" }], 
    sign_url: true });
Java:
cloudinary.url().transformation(
  new Transformation().radius(20).crop("scale").width(400).effect("saturation:50").chain().
    overlay("logo_jpegmini").width(100).x(10).y(10).
    gravity("south_east").opacity(80).chain().
      quality("jpegmini")).signed(true).imageTag("horses.jpg");

The following dynamic manipulation URL generates and delivers the combined cropped, overlaid and optimized image: