Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Download Canvas as PNG in fabric.js giving network Error

Tags:

I want to download Canvas as PNG using fabric.js. While downloading I want to scale the image. So I use multiplier property of toDataURL() function. But I get Failed-Network Error

PS: If I dont give multiplier property,it is downloading but I do want to use multiplier property since I have to scale the image

This is what I am doing:

HTML Code:

<canvas width="400" height="500" id="canvas" ></canvas>  <a id='downloadPreview' href="javascript:void(0)"> Download Image </a> 

JS

document.getElementById("downloadPreview").addEventListener('click', downloadCanvas, false);  var _canvasObject = new fabric.Canvas('canvas');  var downloadCanvas =    function(){     var link = document.createElement("a");  link.href = _canvasObject.toDataURL({format: 'png', multiplier: 4});       link.download = "helloWorld.png";      link.click();  } 
like image 987
Abhinav Avatar asked May 10 '16 10:05

Abhinav


Video Answer


1 Answers

The problem you are facing is not directly related to fabricjs, (nor canvas and not even javascript btw), but comes from limitations some browsers (including Chrome) does have on the maximum length for the src attribute of an Anchor Element (<a>) with the donwload attribute.

When this limit is reached, then the only thing you've got is this uncatchable "Network Error" in the console ; the download as failed, but you as the developer can't know about it.

As proposed in this (you-refused-to-mark-as-) duplicate, the solution is either to directly get a Blob when available (for canvas, you may call its toBlob() method, or to first convert your dataURI to a Blob, and then create an object URL from this Blob.

Fabricjs doesn't seem to have a toBlob function implemented yet, so in your exact case, you'll have to do the later.
You can find many scripts to convert dataURI to Blob, one is available in MDN's polyfill to Canvas.toBlob() method.

Then it would look like this :

// edited from https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/toBlob#Polyfill function dataURIToBlob(dataURI, callback) {   var binStr = atob(dataURI.split(',')[1]),     len = binStr.length,     arr = new Uint8Array(len);    for (var i = 0; i < len; i++) {     arr[i] = binStr.charCodeAt(i);   }    callback(new Blob([arr])); }  var callback = function(blob) {     var a = document.createElement('a');     a.download = fileName;     a.innerHTML = 'download';     // the string representation of the object URL will be small enough to workaround the browser's limitations     a.href = URL.createObjectURL(blob);     // you must revoke the object URL,      //   but since we can't know when the download occured, we have to attach it on the click handler..     a.onclick = function() {       // ..and to wait a frame       requestAnimationFrame(function() {           URL.revokeObjectURL(a.href);         });         a.removeAttribute('href')       };     };  dataURIToBlob(yourDataURL, callback); 
like image 140
Kaiido Avatar answered Oct 02 '22 14:10

Kaiido