无法下载画布内容 [英] Can't download canvas content

查看:127
本文介绍了无法下载画布内容的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以我试图使用电子建立一个应用程序,该程序是相当基本的,用户应该上传一对夫妇的照片,他们按一个按钮,我把它们绘制到< canvas> code>元素,他们应该能够下载它,我有的问题是,当我试图做一个可下载的按钮,一个安全错误抛出,我做了一些研究,发现它是HTML5的一个功能,认为我不能添加crossOrigin ='匿名',因为用户将从自己的计算机加载图片,所以我的问题是...



a) - 是否有一种方法来欺骗系统并能够下载画布的内容?



b) - if(a)不可能...有一个替代,可以工作类似于一个canvas元素?



我已经在使用FileReader()来获取用户选择的图片了,我已经把它绘制到画布上,看起来不错,我有,我无法下载我为该安全错误创建的内容。



从输入中读取图片的代码:

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

for(var i = 0,f; f = files [i]; i ++){
//仅处理映像文件。
if(!f.type.match('image。*')){
continue;
}
var reader = new FileReader();

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

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

};
})(f);
//作为数据URL读入图像文件。
reader.readAsDataURL(f);
}
}

这是一个简单的函数,画布上的网址:

  descargar = function(){
var w = window.open('about:空白','来自画布的图像');
w.document.write(< img src ='+ totem.toDataURL(image / png)+'alt ='from canvas'/>);
}


解决方案


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


您可以使用包含IIFE的循环处理文件从文件元素, FileReader() new Image < img> 元素,的array_prototype.sort()确定两个上传的图像中最大的 width ; Promise.all() Array.prototype.forEach()来处理 img 元素; canvas.toBlob() polyfill以创建 objectURL 的图像; < a> 元素下载属性设置为 objectURL 表示从两个图像创建的单个图像;在下载图片后撤消 objectURL 点击



< pre class =snippet-code-js lang-js prettyprint-override> // if(!HTMLCanvasElement.prototype.toBlob){Object.defineProperty(HTMLCanvasElement.prototype,'toBlob',{value:函数(回调,类型,质量){var binStr = atob(this.toDataURL(type,quality).split(',')[1]),len = binStr.length,arr = new Uint8Array(len); for var i = 0; i pre>

 < a download =href =style =display:none> download< ; / a>< input type =fileaccept =image / *multiple />< br>< canvas>< / canvas>  


So Im trying to build an app using electron, the program is pretty basic, the user should upload a couple of pictures, they press a button, I draw them into a <canvas> element and they should be able to download it, the problem that Im having is that when I try to make a downloadable button, a security error is thrown, I did some research and find out that it's a feature of HTML5, the think is that i can't add the crossOrigin = 'Anonymous' because the user is going to load the picture from its own computer, so my question is...

a)- is there a way to "cheat the system" and be able to download the content of the canvas?,

b)- if (a) is not posible...is there an alternative that could work similary to a canvas element?

I'm already using FileReader() to get the picture the user selected, and i'm already drawing that into the canvas, and it looks great, the problem that I have is that i can't download the content that I created for that security error. the .toDataURL can't be called because that's the one that throws the error.

The code to read the pictures from the inputs:

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

this is a simple function to see if I could get the Url from the canvas:

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

解决方案

the user should upload a couple of pictures, I draw them into a element and they should be able to download it

You can utilize for loop containing an IIFE to process files object from input type="file" element, FileReader(), new Image, onload event of <img> element, Array.prototype.sort() to determine greatest width of the two uploaded images; Promise.all(), Array.prototype.forEach() to process img elements; canvas.toBlob() polyfill to create an objectURL of of image; <a> element having download attribute set to objectURL representing single image created from two images; revoke objectURL at click of a element after download of image completes.

// 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 = event.target.result;
      }
      reader.readAsDataURL(e.target.files[j]);
    }(i))
  }
}

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

<a download="" href="" style="display:none">download</a>
<input type="file" accept="image/*" multiple />
<br>
<canvas></canvas>

这篇关于无法下载画布内容的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆