Cloudinary Blog

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

Animated GIF? Convert to WebM or MP4 | Cloudinary Blog

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.

Given that animated GIFs are now used mainly for short videos, why not reduce the size of animated GIFs by using modern video formats instead? All modern browsers support the HTML5 video tag and embedding short videos as MP4 or WebM would allow you to display the same animated content, while consuming less bandwidth, improving page load times and saving computing resources on your servers.

However, before you can embed animated GIFs as a modern video formats, you'll first need to convert all uploaded GIF files to video file formats. Not all browsers support all video formats - some support only the MP4 container format while others support the WebM container format instead. You'll need to selectively convert the animated GIFs to the appropriate format for the user's browser.

Cloudinary's cloud-based image management service takes care of these challenges - it performs automatic conversion from animated GIF to the MP4 and WebM formats to reduce size of animated GIFs, while supporting all modern browsers. Cloudinary also helps with dynamic resizing, cropping and manipulating these short videos to match your graphic design.

Conversion from animated GIF to MP4 and WebM videos

Cloudinary is a cloud-based image management service, which allows you to upload images to the cloud directly from the browser or mobile app. After a file is uploaded, you can access it using a dynamic URL, and Cloudinary can perform image manipulations on-the-fly, based on parameters you define in the URL (you can easily construct these dynamic URLs using our client libraries for all popular development frameworks).

Your users or staff can upload animated GIFs to Cloudinary, and then in the dynamic URL, you can set the format to either webm or mp4 to automatically convert the original animated image to a modern video format.

For example, the following animated GIF was uploaded to Cloudinary and assigned the kitten_fighting identifier.

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

</Image>
Angular:
<cl-image public-id="kitten_fighting.gif" >

</cl-image>
.Net:
cloudinary.Api.UrlImgUp.BuildImageTag("kitten_fighting.gif")
Android:
MediaManager.get().url().generate("kitten_fighting.gif");
iOS:
imageView.cldSetImage(cloudinary.createUrl().generate("kitten_fighting.gif")!, cloudinary: cloudinary)
https://res.cloudinary.com/demo/image/upload/kitten_fighting.gif

This high quality GIF weighs 6.3MB, which is quite a lot, and takes time to download. If your site has many such large animated files, it will load slowly, which negatively affects user experience.

Setting the format to mp4 dynamically converts the original GIF to the MP4 video format. The generated image is cached persistently and delivered via a CDN:

The automatically-generated MP4 video weighs 311KB, which is only 5% of the original GIF. This means that you save 95% of bandwidth and load time, while showing the same animation to your users.

Converting to the WebM video format can also be done by setting the format to webm. The automatically-generated video shown below weighs only 467KB.

If you decide to display animation using video files, you might prefer to display a single frame with a play button; clicking the play button starts the actual video. Cloudinary can do this dynamically - the following image is a 150x100 thumbnail, with a semi-transparent overlay of a previously uploaded play button image. The thumbnail is converted to the JPG format and weighs only 5.6KB.

Ruby:
cl_image_tag("kitten_fighting.jpg", :transformation=>[
  {:width=>150, :height=>100, :gravity=>"north", :crop=>"fill"},
  {:overlay=>"play_button", :width=>0.4, :flags=>"relative", :opacity=>60}
  ])
PHP:
cl_image_tag("kitten_fighting.jpg", array("transformation"=>array(
  array("width"=>150, "height"=>100, "gravity"=>"north", "crop"=>"fill"),
  array("overlay"=>"play_button", "width"=>0.4, "flags"=>"relative", "opacity"=>60)
  )))
Python:
CloudinaryImage("kitten_fighting.jpg").image(transformation=[
  {'width': 150, 'height': 100, 'gravity': "north", 'crop': "fill"},
  {'overlay': "play_button", 'width': 0.4, 'flags': "relative", 'opacity': 60}
  ])
Node.js:
cloudinary.image("kitten_fighting.jpg", {transformation: [
  {width: 150, height: 100, gravity: "north", crop: "fill"},
  {overlay: "play_button", width: "0.4", flags: "relative", opacity: 60}
  ]})
Java:
cloudinary.url().transformation(new Transformation()
  .width(150).height(100).gravity("north").crop("fill").chain()
  .overlay(new Layer().publicId("play_button")).width(0.4).flags("relative").opacity(60)).imageTag("kitten_fighting.jpg");
JS:
cloudinary.imageTag('kitten_fighting.jpg', {transformation: [
  {width: 150, height: 100, gravity: "north", crop: "fill"},
  {overlay: new cloudinary.Layer().publicId("play_button"), width: "0.4", flags: "relative", opacity: 60}
  ]}).toHtml();
jQuery:
$.cloudinary.image("kitten_fighting.jpg", {transformation: [
  {width: 150, height: 100, gravity: "north", crop: "fill"},
  {overlay: new cloudinary.Layer().publicId("play_button"), width: "0.4", flags: "relative", opacity: 60}
  ]})
React:
<Image publicId="kitten_fighting.jpg" >
  <Transformation width="150" height="100" gravity="north" crop="fill" />
  <Transformation overlay="play_button" width="0.4" flags="relative" opacity="60" />
</Image>
Angular:
<cl-image public-id="kitten_fighting.jpg" >
  <cl-transformation width="150" height="100" gravity="north" crop="fill">
  </cl-transformation>
  <cl-transformation overlay="play_button" width="0.4" flags="relative" opacity="60">
  </cl-transformation>
</cl-image>
.Net:
cloudinary.Api.UrlImgUp.Transform(new Transformation()
  .Width(150).Height(100).Gravity("north").Crop("fill").Chain()
  .Overlay(new Layer().PublicId("play_button")).Width(0.4).Flags("relative").Opacity(60)).BuildImageTag("kitten_fighting.jpg")
Android:
MediaManager.get().url().transformation(new Transformation()
  .width(150).height(100).gravity("north").crop("fill").chain()
  .overlay(new Layer().publicId("play_button")).width(0.4).flags("relative").opacity(60)).generate("kitten_fighting.jpg");
iOS:
imageView.cldSetImage(cloudinary.createUrl().setTransformation(CLDTransformation()
  .setWidth(150).setHeight(100).setGravity("north").setCrop("fill").chain()
  .setOverlay("play_button").setWidth(0.4).setFlags("relative").setOpacity(60)).generate("kitten_fighting.jpg")!, cloudinary: cloudinary)
https://res.cloudinary.com/demo/image/upload/w_150,h_100,c_fill,g_north/l_play_button,w_0.4,fl_relative,o_60/kitten_fighting.jpg

Resizing and cropping animated GIFs and converting to videos

Your users might upload photos and animations of various dimensions and aspect ratios. Most websites and mobile applications need to resize and crop user-uploaded content to match their graphic design. For example, you might want to create a uniform square thumbnail for all uploaded animations.

Cloudinary can resize and crop animated GIFs in the cloud using dynamic manipulation and delivery URLs. The following example creates a 150x150 centered cropped and resized thumbnail of the original animated GIF:

Ruby:
cl_image_tag("kitten_fighting.gif", :width=>150, :height=>150, :crop=>"fill")
PHP:
cl_image_tag("kitten_fighting.gif", array("width"=>150, "height"=>150, "crop"=>"fill"))
Python:
CloudinaryImage("kitten_fighting.gif").image(width=150, height=150, crop="fill")
Node.js:
cloudinary.image("kitten_fighting.gif", {width: 150, height: 150, crop: "fill"})
Java:
cloudinary.url().transformation(new Transformation().width(150).height(150).crop("fill")).imageTag("kitten_fighting.gif");
JS:
cloudinary.imageTag('kitten_fighting.gif', {width: 150, height: 150, crop: "fill"}).toHtml();
jQuery:
$.cloudinary.image("kitten_fighting.gif", {width: 150, height: 150, crop: "fill"})
React:
<Image publicId="kitten_fighting.gif" >
  <Transformation width="150" height="150" crop="fill" />
</Image>
Angular:
<cl-image public-id="kitten_fighting.gif" >
  <cl-transformation width="150" height="150" crop="fill">
  </cl-transformation>
</cl-image>
.Net:
cloudinary.Api.UrlImgUp.Transform(new Transformation().Width(150).Height(150).Crop("fill")).BuildImageTag("kitten_fighting.gif")
Android:
MediaManager.get().url().transformation(new Transformation().width(150).height(150).crop("fill")).generate("kitten_fighting.gif");
iOS:
imageView.cldSetImage(cloudinary.createUrl().setTransformation(CLDTransformation().setWidth(150).setHeight(150).setCrop("fill")).generate("kitten_fighting.gif")!, cloudinary: cloudinary)
https://res.cloudinary.com/demo/image/upload/w_150,h_150,c_fill/kitten_fighting.gif

While this high quality animated GIF is optimized, it still weighs 2.5MB, which seems like an overkill for such a small animation.

Converting to WebM or MP4 videos creates much smaller files while maintaining the same visual quality of the animation. The following dynamic URL dynamically creates the same 150x150 cropped version of the animation, while converting to the MP4 video format, by setting the file extension to mp4. The generated MP4 looks great, and weighs only 106KB, which means we reduced the file size by 96%.

HTML5 video tag with multiple MP4 and WebM sources

Not all browsers support all video formats, but most modern browsers support the HTML5 video tag, which allows you to specify multiple source types for the same video. This means that you can specify both the dynamic Cloudinary URL which converts the animation to MP4, and the alternative URL which converts it to WebM, so each browser can find a supported video format. Chrome supports both MP4 and WebM; Firefox fully supports only WebM, and Internet Explorer supports only MP4.

The following HTML snippet creates a 320x180 auto-play video tag. Both MP4 and WebM URLs are specified. In addition, the still-frame JPG poster is specified and an alternative HTML content linking to the original GIF is included.

<video width="320" height="180" autoplay loop muted="muted" 
  poster="https://res.cloudinary.com/demo/image/upload/kitten_fighting.jpg">

  <source type="video/mp4"
      src="https://res.cloudinary.com/demo/image/upload/kitten_fighting.mp4">
        
  <source type="video/webm"
      src="https://res.cloudinary.com/demo/image/upload/kitten_fighting.webm">
        
  Your browser does not support HTML5 video tag. 
        
  <a href="https://res.cloudinary.com/demo/image/upload/kitten_fighting.gif">Click here to view original GIF</a> 

</video>

Summary

Animated GIFs recently became a significant part of the media we see on the web. While it appears innocent to the regular user, the bandwidth involved in delivering these animations is significant, and major server resources are needed to resize and crop the animated files.

Converting uploaded animated GIF files to video files offers the same visual results, for considerably less bandwidth, making your site or app load faster, and your users happier. Cloudinary takes care of this process for you, in three steps: Cloudinary performs automatic cloud-based conversion to MP4 and WebM using dynamic URLs. Then it performs simple and fast resizing, cropping and other manipulations as needed, which are handled by our cloud service and do not consume your server resources. Finally, Cloudinary optimizes delivery of the resulting videos via fast CDN.

Another alternative to animated GIF is the Animated WebP format, which is supported by recent versions of the Chrome browser. In addition to MP4 and WebM, Cloudinary also supports automatic conversion to the WebP format, and can do this selectively for browsers that support WebP, while serving other formats to other browsers. For more details see our blog post about our support for Animated WebP.

Conversion of animated GIF to MP4 and WebM, as well as all further manipulations, are available in all Cloudinary plans, including the free plan. Please let us know if you have any feedback on this new feature or the rest of Cloudinary's animation and video conversion capabilities.

Recent Blog Posts

CoreMedia Adds Cloudinary to its CoreMedia Studio Platform

Today we’re pleased to announce a new technology partnership with CoreMedia, a leading Content Experience Platform provider. CoreMedia users can now leverage Cloudinary’s web-based digital asset management (DAM) solution to organize, search, manage and optimize their media assets, including images and videos, and to orchestrate, preview and deliver digital experiences consistently and optimized across all channels and browsers. The official press release is available here.

Read more
Facial-Surveillance System for Restricted Zones

In Africa, where Internet access and bandwidth are limited, it’s not cost-effective or feasible to establish and maintain a connectivity for security and surveillance applications. That challenge makes it almost impossible to build a service that detects, with facial-recognition technology, if someone entering a building is authorized to do so. To meet the final-year research requirement for my undergraduate studies, I developed a facial-surveillance system. Armed with a background in computer vision, I decided to push the limits and see if I could build a surveillance system that does not require recording long video footage.

Read more
Complex Networks Case Study

Complex Networks has been using Cloudinary since 2014 to manage and optimize images across seven websites and two mobile apps, making editorial workflow more efficient, improving page performance and load time, and increasing user engagement. Cloudinary was instrumental in enabling Complex Networks to redesign its web properties. Without the flexibility that Cloudinary offers to both creative and development teams, it would not have been possible for Complex Networks to achieve such a fast time to market.

Read more
Automate Placeholder Generation and Accelerate Page Loads

If you run a Google search on LQIP you’ll see very few relevant articles, very little guidance, and definitely no Wikipedia articles. In this post, we’ll discuss some of the feedback on LQIP we have gathered from the community and suggest and open for conversation a few approaches based on the built-in capabilities of the Cloudinary service. Specifically, we’ll explain what LQIP are, where they are best used, and how you can leverage them to accelerate page loads and optimize user experience.

Read more
Best Practices for Optimizing Web Page Speed

If you're like most consumers today, you engage more with pictures or videos on a website than text. The stats don't lie - four times as many visitors would rather watch a video about a product than read about it, and sites with compelling images average twice as many views as text-heavy ones.

Read more
A day of fun with Girls Who Code and Cloudinary

During both my computer science studies and work in the tech field, there have not been a lot of women present. While our ranks have grown, women still make up only a small percentage. In many ways, I think the traditionally male-dominated world can be intimidating to women and girls who may be interested in pursuing these types of tech careers.

Read more