Cloudinary Blog
Learn more...

JPEG-XR conversion with auto browser detection, optimize images for IE users

JPEG-XR Post Sites and apps are including more and more high-quality images. The more you can compress images to reduce their size in bytes, the smaller your bandwidth, the faster your site will load and the happier your users will be. But when compressing images, you need to make sure you maintain high visual quality.

Most web sites and mobile apps use the popular JPEG format to display their images and user uploaded photos. The JPEG format has efficient built-in compression that reduces image size while maintaining a reasonable visual quality. But you can reach much better results using more modern image file formats.

A few years ago Google introduced the WebP image format, which is supported mainly by the popular Chrome browser. Cloudinary, a cloud-based image management platform, has supported automatic conversion to the WebP format for some time, and this has proved to be extremely useful in reducing image file size while ensuring the resulting images look great.

In 2009, Microsoft introduced its own modern image format. It is called JPEG-XR, and has been supported by Internet Explorer since version 9. The JPEG-XR format allows saving and delivering high quality photos using significantly less bytes. This format supports both lossy and lossless compression, and includes an alpha channel for supporting semi-transparent pixels.

In this blog post we show how Cloudinary’s cloud service can convert images on-the-fly to the JPEG-XR format, with automatic delivery of JPEG-XR images to users of supported browsers.

On-the-fly JPEG-XR conversion

The following photo was uploaded to Cloudinary, and assigned the identifier seagull. The original image is a 1,000x667 JPEG photo, and it weighs 107KB. Note that in the sample images below we show 500x334 scaled-down versions so they fit better in this post.

Ruby:
cl_image_tag("seagull.jpg")
PHP:
cl_image_tag("seagull.jpg")
Python:
CloudinaryImage("seagull.jpg").image()
Node.js:
cloudinary.image("seagull.jpg")
Java:
cloudinary.url().imageTag("seagull.jpg")
jQuery:
$.cloudinary.image("seagull.jpg")
.Net:
cloudinary.Api.UrlImgUp.BuildImageTag("seagull.jpg")
Seagull JPEG
107KB JPEG

Cloudinary makes it possible to modify images on-the-fly using dynamic URLs with parameters that define image manipulations. Simply setting the format parameter in the URL to the desired file type, or changing the file extension to the image URL, instructs Cloudinary to convert the image and display it to users in the target format.

The JPEG-XR format has multiple possible file extensions: .jxr, .hdp and .wdp. The latter is the commonly used one. Setting the format parameter or the URL's file extension to wdp tells Cloudinary to convert the original image to the JPEG-XR format.

Ruby:
cl_image_tag("seagull.wdp")
PHP:
cl_image_tag("seagull.wdp")
Python:
CloudinaryImage("seagull.wdp").image()
Node.js:
cloudinary.image("seagull.wdp")
Java:
cloudinary.url().imageTag("seagull.wdp")
jQuery:
$.cloudinary.image("seagull.wdp")
.Net:
cloudinary.Api.UrlImgUp.BuildImageTag("seagull.wdp")
Seagull JPEG-XR
71KB JPEG-XR - Viewable only in IE 9+

The resulting WDP looks great and weighs only 71KB. This means that we saved 34% of the original file size.

Note that to see our sample JPEG-XR images, you should open this blog post in Internet Explorer.

Cropping, resizing and manipulating JPEG-XR images

Cloudinary supports a rich set of image manipulation capabilities that allow you to dynamically adapt your images to your site’s graphic design, and any desktop or mobile device. The following dynamic manipulation URL and sample code generates a 250x300 cropped version of the original seagull while increasing color saturation by 150%

Ruby:
cl_image_tag("seagull.jpg", :width=>250, :height=>300, :crop=>:fill, :effect=>"saturation:150")
PHP:
cl_image_tag("seagull.jpg", array("width"=>250, "height"=>300, "crop"=>"fill", "effect"=>"saturation:150"))
Python:
CloudinaryImage("seagull.jpg").image(width=250, height=300, crop="fill", effect="saturation:150")
Node.js:
cloudinary.image("seagull.jpg", {width: 250, height: 300, crop: "fill", effect: "saturation:150"})
Java:
cloudinary.url().transformation(new Transformation().width(250).height(300).crop("fill").effect("saturation:150")).imageTag("seagull.jpg")
jQuery:
$.cloudinary.image("seagull.jpg", {width: 250, height: 300, crop: "fill", effect: "saturation:150"})
.Net:
cloudinary.Api.UrlImgUp.Transform(new Transformation().Width(250).Height(300).Crop("fill").Effect("saturation:150")).BuildImageTag("seagull.jpg")
Seagull thumbnail JPEG
19.6KB JPEG

Setting the file format to wdp generates a JPEG-XR version of the same file. The resulting image looks almost identical to the original JPEG but weighs less.

Ruby:
cl_image_tag("seagull.wdp", :width=>250, :height=>300, :crop=>:fill, :effect=>"saturation:150")
PHP:
cl_image_tag("seagull.wdp", array("width"=>250, "height"=>300, "crop"=>"fill", "effect"=>"saturation:150"))
Python:
CloudinaryImage("seagull.wdp").image(width=250, height=300, crop="fill", effect="saturation:150")
Node.js:
cloudinary.image("seagull.wdp", {width: 250, height: 300, crop: "fill", effect: "saturation:150"})
Java:
cloudinary.url().transformation(new Transformation().width(250).height(300).crop("fill").effect("saturation:150")).imageTag("seagull.wdp")
jQuery:
$.cloudinary.image("seagull.wdp", {width: 250, height: 300, crop: "fill", effect: "saturation:150"})
.Net:
cloudinary.Api.UrlImgUp.Transform(new Transformation().Width(250).Height(300).Crop("fill").Effect("saturation:150")).BuildImageTag("seagull.wdp")
Seagull thumbnail JPEG-XR
16.9KB JPEG-XR - Viewable only in IE 9+

Similar to JPEG, the JPEG-XR has a quality level you can control. While the default quality level is 70, you can set a custom quality level using the quality parameter (when constructing an image URL using Cloudinary’s client libraries), or q when constructing a URL directly. The following URL and sample code sets the JPEG-XR quality to 50:

Ruby:
cl_image_tag("seagull.wdp", :quality=>50, :width=>250, :height=>300, :crop=>:fill, :effect=>"saturation:150")
PHP:
cl_image_tag("seagull.wdp", array("quality"=>50, "width"=>250, "height"=>300, "crop"=>"fill", "effect"=>"saturation:150"))
Python:
CloudinaryImage("seagull.wdp").image(quality=50, width=250, height=300, crop="fill", effect="saturation:150")
Node.js:
cloudinary.image("seagull.wdp", {quality: 50, width: 250, height: 300, crop: "fill", effect: "saturation:150"})
Java:
cloudinary.url().transformation(new Transformation().quality(50).width(250).height(300).crop("fill").effect("saturation:150")).imageTag("seagull.wdp")
jQuery:
$.cloudinary.image("seagull.wdp", {quality: 50, width: 250, height: 300, crop: "fill", effect: "saturation:150"})
.Net:
cloudinary.Api.UrlImgUp.Transform(new Transformation().Quality(50).Width(250).Height(300).Crop("fill").Effect("saturation:150")).BuildImageTag("seagull.wdp")
Seagull JPEG-XR quality 50
10.9KB JPEG-XR 50% Quality - Viewable only in IE 9+

It's hard to tell the difference between the 50%-quality JPEG-XR and the higher quality image. This new file weighs only 10.9KB, saving 44% of the original JPEG file.

As mentioned above, the JPEG-XR format includes an alpha channel and supports semi-transparent pixels. This means you can use JPEG-XR to generate semi-transparent images and place them on non-white background. This will save image size and bandwidth because the image contains less pixels.

The following URL creates a circular shape around the same image, by setting the radius parameter to max. As you can see below, the JPEG result on the left has a white background, while the JPEG-XR image on the right has a transparent background. On Firefox, you’d be forced to use PNG for this semi-transparent image, which would have been approximately 10 times the size of this JPEG-XR.

Ruby:
cl_image_tag("seagull.wdp", :radius=>"max", :width=>250, :height=>300, :crop=>:fill, :effect=>"saturation:150")
PHP:
cl_image_tag("seagull.wdp", array("radius"=>"max", "width"=>250, "height"=>300, "crop"=>"fill", "effect"=>"saturation:150"))
Python:
CloudinaryImage("seagull.wdp").image(radius="max", width=250, height=300, crop="fill", effect="saturation:150")
Node.js:
cloudinary.image("seagull.wdp", {radius: "max", width: 250, height: 300, crop: "fill", effect: "saturation:150"})
Java:
cloudinary.url().transformation(new Transformation().radius("max").width(250).height(300).crop("fill").effect("saturation:150")).imageTag("seagull.wdp")
jQuery:
$.cloudinary.image("seagull.wdp", {radius: "max", width: 250, height: 300, crop: "fill", effect: "saturation:150"})
.Net:
cloudinary.Api.UrlImgUp.Transform(new Transformation().Radius("max").Width(250).Height(300).Crop("fill").Effect("saturation:150")).BuildImageTag("seagull.wdp")

Seagull non-transparent JPEG Seagull semi-transparent JPEG-XR - Viewable only in IE 9+

                                                  JPEG                                                                       JPEG-XR (IE 9+ only)

Automatic delivery of JPEG-XR and WebP according to user browsers

Users are visiting your site or application using various browsers, but it’s likely that most of them are using either Chrome or Internet Explorer. Optimally, you would want every user to get the image that best matches the capabilities of their current browser. Cloudinary takes care of that automatically.

By setting the format parameter to auto, or f_auto for delivery URLs, Cloudinary dynamically delivers the best matching format: WebP for Chrome and supported Android browsers, JPEG-XR for supported Internet Explorer browsers, and JPEG for all other browsers. The relevant image format is delivered to users via fast CDN.

By dynamically selecting the image format, Cloudinary allows you to deliver high quality images with minimal bandwidth use, and with a very minimal development effort.

Ruby:
cl_image_tag("seagull.jpg", :width=>250, :height=>250, :crop=>:fill)
PHP:
cl_image_tag("seagull.jpg", array("width"=>250, "height"=>250, "crop"=>"fill"))
Python:
CloudinaryImage("seagull.jpg").image(width=250, height=250, crop="fill")
Node.js:
cloudinary.image("seagull.jpg", {width: 250, height: 250, crop: "fill"})
Java:
cloudinary.url().transformation(new Transformation().width(250).height(250).crop("fill")).imageTag("seagull.jpg")
jQuery:
$.cloudinary.image("seagull.jpg", {width: 250, height: 250, crop: "fill"})
.Net:
cloudinary.Api.UrlImgUp.Transform(new Transformation().Width(250).Height(250).Crop("fill")).BuildImageTag("seagull.jpg")
Automatic format WebP, JPEG-XR and JPEG
Auto WebP/JPEG-XR/JPEG

The image above is displayed using different formats according to the user’s specific browser. A WebP image is dynamically shown to Chrome users, and a JPEG-XR image is shown to IE users, significantly saving bandwidth and improving user experience for both.

Summary

Image optimization has become a must for speeding load times of modern sites and apps. Modern and efficient image formats, like WebP and JPEG-XR provide a great solution that combines high visual quality with a high compression rate. However, because these formats are only supported by specific browsers, delivering them is a challenge for developers.

Cloudinary is a cloud-based image management service that aims to simplify image-related development work by taking care of all image-related activities on a website. As a dynamic JPEG-XR converter, which can deliver JPEG-XR to users with Internet Explorer, WebP for users of Chrome, and other image formats for other browsers, Cloudinary allows web developers to improve user experience with only a few lines of code. a very small effort.

Automatic conversion and delivery of the JPEG-XR format is available for all of Cloudinary's plans, including the free plan. If you already have a Cloudinary account and you use the f_auto parameter, JPEG-XR images are already automatically generated and delivered to your Internet Explorer users! Enjoy the reduced bandwidth and faster user experience.

Reduce size of animated GIFs, automatically convert to WebM and MP4

Animated GIF to WebM and MP4

Short animated GIF-based video sequences seem to be spreading like wildfire around the web.

Media and news sites display short video segments, social apps allow their users to share animated GIFs with their friends, and while the dated animated GIF format is very useful for this purpose, it has one significant disadvantage - its huge file size.

Animated GIFs are not optimized for captured videos, resulting in large files, heavy bandwidth utilization, slow loading times, and sub-optimal user experience. Also, resizing and manipulating animated GIFs to match the graphic design of your site or app might be a lengthy, cpu-intensive process, as it consists of dozens or even hundreds of frames being manipulated individually.

→ Read the full post

How to automatically adapt website images to Retina and HiDPI devices

Jul 24, 2014 by Nadav Soferman

DPR Post Web development was much simpler only a few years ago, when we were building HTML pages that included images and photos, and all elements shared the same resolution units. If for example, you aimed at a standard 1024x768 screen, you knew these were exactly the number of pixels available for displaying HTML elements and images.

In 2010, Apple introduced the iPhone 4 with Retina display. In order to simplify things for developers, the logical screen resolution remained the same as previous iPhone models (640x960) while the physical screen resolution was exactly doubled (1280x1920). This means that if, for example, you embed an image tag in your HTML page with width of 200 pixels and height of 300 pixels, and you display a double-size image of 400x600 pixels, the Retina display shows all pixels of the larger image, resulting in a much clearer visual result and without performing browser-side down-scaling.

→ Read the full post

Automatic image moderation, removing adult or inappropriate photos using WebPurify and Cloudinary

Jul 22, 2014 by Nadav Soferman

WebPurify moderation add-on If your web or mobile application involves user-generated content, you may encounter users who upload inappropriate photos or images to your application. These could be images which offend other users - adult content, violent photos, etc. - or images which cause your site to violate laws or regulations.

There are two ways to identify and remove such images: you can either require approval of each image before it is displayed to your users, or display images immediately after upload, and then quickly remove them from your site as soon as a moderator has found them to be inappropriate.

→ Read the full post

Direct upload made easy, from browser or mobile app to the cloud

Jul 16, 2014 by Nadav Soferman

Unsigned upload Handling user uploaded images on your website can be a time consuming task. In this post, we'll show how Cloudinary's cloud-based image management service can help you turn user uploading into a lightweight operation that bypasses your servers altogether.

How do you handle user uploads today? If images are uploaded directly to your servers, this requires some heavy server-side processing, bandwidth and storage space. One way to offload images is to transfer them to cloud storage. But if you're handling the upload operation on your own servers (and then transferring them to the cloud), this is still wasteful of server resources.

→ Read the full post

Keep.com, releasing the image processing bottleneck

Jul 10, 2014 by Itai Lahan

Keep & Cloudinary Cloudinary is passionate about its users. We built our cloud-based image management features around real-world pain points, and it's gratifying to see our customers use those features to solve major business challenges.

One example is Keep.com, an innovative online commerce startup, which the Huffington Post has called "the only fashion app worth getting". We wanted to share the story of how Keep used Cloudinary to remove a major bottleneck in the development of their website and business.

→ Read the full post

Image manipulation recipes in the cloud. The Cloudinary Cookbook

Jun 26, 2014 by Nadav Soferman

Cloudinary Cookbook How do you crop an image to a custom shape? How do you add a shadow effect to an image with transparency? How do you add text overlay to an image without using HTML?

If you build or maintain a website with a lot of images, you've probably had many questions like these. Most developers who work with images have scripts or tools that can achieve dozens if not hundreds of image manipulations - from basics like crop and resize, to advanced stuff like shadow and transparency, watermarks, face detection, etc. But how do you mix and match these manipulations correctly to solve a problem or achieve a certain effect?

→ Read the full post

Animated WebP - how to convert animated GIF to WebP and save up to 90% bandwidth

Jun 16, 2014 by Nadav Soferman

Animated WebP Fashion isn't something you'd expect to repeat itself in the technology world - technology advances quickly and hardly ever circles back. But where animated GIFs are involved, it seems like the 90s are here again. Animated GIFs are everywhere, and not only on strange, cheezy web sites - they've become mainstream. You now see short videos shared and played as animated GIFs in reputed sites such as Gawker and TechCrunch.

→ Read the full post

Centralized control for image upload - image size, format, thumbnail generation, tagging and more

Jun 09, 2014 by Nadav Soferman

Upload presets There are many options to consider when allowing a user to upload an image to your website or mobile app. You might wish to limit the size and format of the uploaded images. You may want to apply specific manipulations to the images, such as cropping, resizing and adapting the image to your site's look & feel. Beyond that, it's common to create a variety of thumbnails from a newly uploaded image.

→ Read the full post

Optimize your JPEG images without compromising quality with JPEGmini and Cloudinary

May 29, 2014 by Nadav Soferman

JPEGmini Image optimization is an important step to reducing page load times, improving user experience and reducing bandwidth costs. When using the JPEG image format, which is best used for photos, the most common optimization is controlling the JPEG quality level.

By lowering JPEG quality, say to 90%, 80% or even 50%, you'll get much smaller JPEG files. But will image quality be good enough? JPEG optimization is tricky because if quality is too low, you'll get blurry images, pixelation and visible compression artifacts; if it's too high, images will look good but take too long to load.

→ Read the full post
More posts...