On the fly clientside image to webp converter...but png's are not transparent

cocco picture cocco · Aug 18, 2013 · Viewed 7.4k times · Source

this is a working code to convert jpg or png to webp

google's new image format that is in average 30-40% smaller than jpg's or png's

1.Open with Chrome

2.Set The quality

3.Drop an image inside the page

4.Wait (depends on the size .. try small images first)

5.Hover the image to see the size difference

6.To properly save it as webp just click on it

Basycally chrome adde the possibility to add image/webp and the quality to the toDataURL function

canvas.toDataURL('image/webp',quality(0-1))

The compression is fantastic.But i have a small problem... png's are not transparent..

what could it be? maybe set the canvas to transparent? how?

<!doctype html>
<html>
<head>
<meta charset="utf-8">
<style>
html,body{
 width:100%;
 height:100%;
 margin:0;
 padding:0;
 display:-webkit-flex;
 display: flex;
}
a{margin: auto;}
.imG{
 max-width:800px;
 max-height:400px;
}
form{
 position:fixed;
 bottom:0px;left:0px;
}
</style>
<script>
(function(W){
 W.URL=W.URL||W.webkitURL;
 var D;
 function init(){
  D=W.document;
  D.body.addEventListener('dragstart',pdrop,false);
  D.body.addEventListener('dragenter',pdrop,false)
  D.body.addEventListener('dragover',pdrop,false);
  D.body.addEventListener('dragleave',pdrop,false);
  D.body.addEventListener('dragend',pdrop,false);
  D.body.addEventListener('drop',drop,false);
 }
 function readablizeBytes(bytes) {
  var s=['bytes','kB','MB','GB','TB','PB'],m=Math,e=m.floor(m.log(bytes)/m.log(1024));
  return (bytes/Math.pow(1024,e)).toFixed(2)+" "+s[e];
 }
 function pdrop(e){
  e.stopPropagation();
  e.preventDefault();
 }
 function drop(e){
  e.stopPropagation();
  e.preventDefault();
  console.log(e.dataTransfer.files[0]);
  var f=e.dataTransfer.files[0];
  var i=document.createElement('img');
  i.onload=function(e){
   window.URL.revokeObjectURL(this.src);
   var b=document.createElement('canvas');
   b.width=this.width;b.height=this.height;
   var c=b.getContext("2d");
   c.drawImage(this,0,0);
   this.onload=function(){
    this.className='imG';
    var d=document.createElement('a');
    g=f.name.split('.');g.pop();
    d.download=g.join('')+'.webp';
    d.href=this.src;
    d.title=readablizeBytes(atob(this.src.split(',')[1]).length)+' vs '+readablizeBytes(f.size);
    d.appendChild(this);
    D.body.appendChild(d);
   }
   this.src=b.toDataURL('image/webp',D.getElementsByName('o')[0].innerText*0.01);
  };
  i.src=window.URL.createObjectURL(f);
 }
 W.addEventListener('load',init,false);
})(window)
</script>
<title>Image To Google's webp format</title>
</head>
<body>
<form onsubmit="return false" oninput="o.value=v.valueAsNumber">
 <label for="q">Choose the quality and then drop a image</label>
 <input name="v" id="q" type="range" min="0" max="100" value="0"> 
 <output for="q" name="o">0</output>/100
</form>
</body>
</html>

ps.:for best results use jpg's and reload the page every time as it just appends every new image

Answer

user1693593 picture user1693593 · Sep 11, 2013

Canvas status

This is an known issue with Chrome.

From the comments from the link above it's stated:

WebCore discards the alpha channel in toDataURL("image/webp") and encodes the image from the RGB pixels because WEBP never supported alpha channel. toDataURL("image/webp") has been that way since http://trac.webkit.org/changeset/99319 (shipped over a year ago).

WEBP only recently added support for alpha channel and there is no way to select that in a toDataURL. We could force it one way or the other, I suppose, but should the default encoding be 1) no-alpha as now, or 2) alpha as requesting in this bug?

The issue has currently not been solved but will likely be addressed in near future.

Possible work-around

For a possible work-around you can use a custom implementation of the WEBP format which states it supports the alpha channel. It can convert PNG (and JPEG) to WEBP format.

The solution is called WEBPJS and can be found here (and examples can be found here).

(but there is also the possibility that Chrome won't be able to decode webp images even if they contain alpha channel..).

Conclusion

webp images with alpha channel has poor support at the moment even with Google's (the inventor) own Chrome, and lack support in other browsers. My advice is that you put this on ice until support is improved and instead use PNG as this has wide support.

Use tools such as tinypng.com to reduce the sizes of the files.