Abh*_*nav 22 html javascript canvas fabricjs
我想使用fabric.js将Canvas下载为PNG.在下载时我想缩放图像.所以我使用multiplier了toDataURL()函数的属性.但我得到了失败 - 网络错误
PS:如果我不给multiplier属性,它正在下载,但我确实想要使用multiplier属性,因为我必须缩放图像
这就是我在做的事情:
HTML代码:
<canvas width="400" height="500" id="canvas" ></canvas>
<a id='downloadPreview' href="javascript:void(0)"> Download Image </a>
Run Code Online (Sandbox Code Playgroud)
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();
}
Run Code Online (Sandbox Code Playgroud)
Kai*_*ido 39
您遇到的问题与fabricjs(也不是画布,甚至不是javascript btw)没有直接关系,而是来自某些浏览器(包括Chrome)对于具有donwload src的Anchor Element(<a>)属性的最大长度的限制属性.
当达到这个限制时,你唯一得到的就是控制台中无法捕获的"网络错误"; 下载失败,但你作为开发人员无法了解它.
正如在此(你拒绝标记为 副本)中提出的那样,解决方案是在可用时直接获取Blob(对于画布,可以调用其toBlob()方法,或者首先将dataURI转换为Blob,以及然后从此Blob 创建一个对象URL.
Fabricjs似乎还没有toBlob实现一个功能,所以在你的确切情况下,你将不得不做以后的事情.
您可以找到许多脚本来将dataURI转换为Blob,其中一个脚本可以在MDN的polyfill to Canvas.toBlob()方法中使用.
然后它看起来像这样:
// 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);
Run Code Online (Sandbox Code Playgroud)
Abh*_*nav 15
我知道了.按照Kaiido的建议解决了这个问题
function dataURLtoBlob(dataurl) {
var arr = dataurl.split(','), mime = arr[0].match(/:(.*?);/)[1],
bstr = atob(arr[1]), n = bstr.length, u8arr = new Uint8Array(n);
while(n--){
u8arr[n] = bstr.charCodeAt(n);
}
return new Blob([u8arr], {type:mime});
}
Run Code Online (Sandbox Code Playgroud)
注意:从HTML5/Javascript - DataURL到Blob&Blob到DataURL获得上述功能
var downloadCanvas = function(){
var link = document.createElement("a");
var imgData = _canvasObject.toDataURL({ format: 'png',
multiplier: 4});
var strDataURI = imgData.substr(22, imgData.length);
var blob = dataURLtoBlob(imgData);
var objurl = URL.createObjectURL(blob);
link.download = "helloWorld.png";
link.href = objurl;
link.click();
}
Run Code Online (Sandbox Code Playgroud)