当前位置: 首页 > 知识库问答 >
问题:

下载画布作为PNG在fabric.js给网络错误

燕和同
2023-03-14

我想使用fabric将画布下载为PNG。js。下载时,我想缩放图像。所以我使用了函数的属性。但我收到失败的网络错误

PS:如果我没有提供乘法器属性,它正在下载,但我确实想使用乘法器属性,因为我必须缩放图像

这就是我正在做的:

超文本标记语言代码:

<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();

}

共有3个答案

祁乐邦
2023-03-14

由于前两个答案仅适用于具有base64数据的DataURL,并且由于href属性太大,与“网络错误”相关的更一般问题引用了此答案,因此我使用的代码如下:

// must be called in a click handler or some other user action
var download = function(filename, dataUrl) {
    var element = document.createElement('a')

    var dataBlob = dataURLtoBlob(dataUrl)
    element.setAttribute('href', URL.createObjectURL(dataBlob))
    element.setAttribute('download', filename)

    element.style.display = 'none'
    document.body.appendChild(element)

    element.click()

    var clickHandler;
    element.addEventListener('click', clickHandler=function() {
        // ..and to wait a frame
        requestAnimationFrame(function() {
            URL.revokeObjectURL(element.href);
        })

        element.removeAttribute('href')
        element.removeEventListener('click', clickHandler)
    })

    document.body.removeChild(element)
}


// from Abhinav's answer at  https://stackoverflow.com/questions/37135417/download-canvas-as-png-in-fabric-js-giving-network-error/
var dataURLtoBlob = function(dataurl) {
    var parts = dataurl.split(','), mime = parts[0].match(/:(.*?);/)[1]
    if(parts[0].indexOf('base64') !== -1) {
        var bstr = atob(parts[1]), n = bstr.length, u8arr = new Uint8Array(n)
        while(n--){
            u8arr[n] = bstr.charCodeAt(n)
        }

        return new Blob([u8arr], {type:mime})
    } else {
        var raw = decodeURIComponent(parts[1])
        return new Blob([raw], {type: mime})
    }
}

使用这些函数,您可以将代码更改为:

document.getElementById("downloadPreview").addEventListener('click', function() {
  var dataURL = _canvasObject.toDataURL({format: 'png', multiplier: 4})
  download("hellowWorld.png", dataURL)
})
宓诚
2023-03-14

我明白了按照凯多的建议解决了

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});
}

注意:从HTML5/Javascript获得上述函数-DataURL到Blob

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();
} 
谷梁嘉悦
2023-03-14

您面临的问题与fabricjs(也不是canvas,甚至不是javascript btw)没有直接关系,而是来自一些浏览器(包括Chrome)对锚元素的src属性的最大长度的限制(

当达到这个限制时,你唯一能得到的就是控制台中这个不可跟踪的“网络错误”;下载失败了,但作为开发人员,您无法知道这一点。

正如在这个(you-拒绝-to-mark-as-)副本中建议的那样,解决方案是在可用时直接获取Blob(对于画布,您可以调用其toBlob()方法,或者首先将您的dataURI转换为Blob,然后从此Blob创建对象URL。

Fabricjs似乎还没有实现toBlob函数,因此在您的确切情况下,您必须稍后执行。
您可以找到许多将dataURI转换为Blob的脚本,其中一个在MDN的pol填充到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);

 类似资料:
  • 问题内容: 我想使用fabric.js将Canvas下载为PNG。下载时,我想缩放图像。所以我使用函数的属性。但我收到失败网络错误 PS: 如果我不提供财产,它正在下载,但是我 确实 想使用财产,因为我必须缩放图像 这就是我在做什么: HTML代码: JS 问题答案: 您面临的问题与fabric.js(也不是canvas,甚至不是javascriptbtw)都没有直接关系,而是由于某些浏览器(包括

  • 我想使用Fabric.js在我的web应用程序中实现eraser。在Fabric.js中有没有实现橡皮擦的方法?例如,如在MS Paint?

  • 问题内容: 我正在尝试将canvas元素另存为png图像。这是我现在的代码,但是不幸的是,它不起作用: 我想看看Python中的解决方案。我还希望在屏幕快照的末尾看到不需要裁剪的解决方案。 问题答案: 您可以调用将画布作为PNG base64字符串获取。这是一个工作示例:

  • 问题内容: 我正在尝试将HTML5画布转换为图像。这是我到目前为止所得到的: 但是问题是我得到了以下代码: 我想要用户可以下载的普通图像路径! 有什么帮助吗? 问题答案: 信息: IE10 +完全不支持以下方法。其他人已经完成了工作并实现了跨浏览器解决方案。 这就是其中之一。 首先,将生成的数据URL添加到标签的属性中。但是,在某些浏览器上,仅此一项就不会触发下载。相反,它将在新页面中打开链接的图

  • 我有一个画布元素,其中有一个绘图,我想创建一个按钮,当点击它时,它将把图像保存为一个png文件。因此它应该打开“保存、打开、关闭”对话框... 我使用这个代码 但当我在IE9中测试它时,一个新窗口打开了,上面写着“网页无法显示”,其url是: 有人知道怎么解决这个吗?

  • 问题内容: 我想将以Base64编码的PNG图像加载到canvas元素。我有以下代码: 在Chrome 8中,我收到错误消息: 在Firefox的Firebug中,这是:“对象的类型与与该对象关联的参数的预期类型不兼容”代码:“ 17” 在那个base64中,是我在GIMP中制作的5x5px黑色PNG正方形,并将其转换为GNU / Linux程序base64中的base64。 问题答案: 从外观上