无法下载画布内容

时间:2016-04-27 04:45:34

标签: javascript html5 canvas

所以我尝试使用电子构建应用程序,该程序非常基本,用户应该上传几张图片,按下按钮,我将它们绘制成<canvas>元素,他们应该能够下载它,我遇到的问题是,当我尝试制作可下载的按钮,抛出安全错误时,我做了一些研究,发现它是HTML5的一个功能,我认为我无法添加crossOrigin ='匿名',因为用户将从自己的计算机加载图片,所以我的问题是......

a) - 有没有办法“欺骗系统”并能够下载画布的内容?,

b) - 如果(a)不可行......是否有替代方案可以与画布元素相似?

我已经在使用FileReader()来获取用户选择的图片了,我已经将它绘制到画布中了,它看起来很棒,我的问题是我无法下载内容我为那个安全错误创建了。无法调用.toDataURL,因为那是抛出错误的那个。

从输入读取图片的代码:

 function handleBox1(evt) {
    var files = evt.target.files; // FileList object

    for (var i = 0, f; f = files[i]; i++) {
      // Only process image files.
      if (!f.type.match('image.*')) {
        continue;
      }
      var reader = new FileReader();

      reader.onload = (function(theFile) {
        return function(e) {

            $('#imgBox1').attr("src",e.target.result);              

        };
      })(f);
      // Read in the image file as a data URL.
      reader.readAsDataURL(f);
    }
}

这是一个简单的函数,看看我是否可以从画布中获取Url:

descargar = function(){
  var w=window.open('about:blank','image from canvas');
  w.document.write("<img src='"+ totem.toDataURL("image/png")+ "' alt='from canvas'/>");
}

1 个答案:

答案 0 :(得分:1)

  

用户应该上传几张图片,我将它们绘制成一张    元素,他们应该能够下载它

您可以利用包含IIFE的for循环来处理来自files元素的input type="file"对象,new Imageonload <img>元素事件,URL.createObjectURL()Array.prototype.sort(),以确定上传的两张图片中最大的width; Promise.all()Array.prototype.forEach()来处理img元素; canvas.toBlob() polyfill用于创建objectURL图像;将<a>属性设置为download的{​​{1}}元素表示从两个图像创建的单个图像;下载图像完成后,在objectURL objectURL元素处撤消click

a
// if (!HTMLCanvasElement.prototype.toBlob) {
Object.defineProperty(HTMLCanvasElement.prototype, 'toBlob', {
  value: function(callback, type, quality) {

    var binStr = atob(this.toDataURL(type, quality).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], {
      type: type || 'image/png'
    }));
  }
});
//}

var input = document.querySelector("input");
var canvas = document.querySelector("canvas");
var a = document.querySelector("a");
var ctx = canvas.getContext("2d");
var urls = [];

input.onchange = function(e) {
  var images = [];

  for (var i = 0; i < e.target.files.length; i++) {
    (function(j) {
      // var reader = new FileReader();
      // reader.onload = function(event) {
        var img = new Image;
        img.onload = function() {
          images.push(Promise.resolve(this));
          if (images.length === e.target.files.length) {
            Promise.all(images)
              .then(function(data) {
                data.sort(function(a, b) {
                  return a.naturalHeight < b.naturalHeight;
                })
                data.forEach(function(el, index) {
                  if (index === 0) {
                    canvas.width = el.naturalWidth;
                    canvas.height = el.naturalHeight 
                                    + data[index + 1].naturalHeight;
                    ctx.drawImage(el, 0, 0);
                  } else {
                    ctx.drawImage(el, 0, canvas.height - el.naturalHeight);
                  }

                });
                canvas.toBlob(function(blob) {
                  var url = URL.createObjectURL(blob);
                  console.log(blob);
                  a.href = url;
                  a.style.display = "block";
                  urls.push(url);
                });
              })
          }
        }
        img.src = URL.createObjectURL(e.target.files[j]);
      // }
      // reader.readAsDataURL(e.target.files[j]);
    }(i))
  }
}

a.onclick = function() {
  setTimeout(function() {
    urls.forEach(function(obj) {
      URL.revokeObjectURL(obj)
    })
  })
}