无法下载画布内容 [英] Can't download canvas content
问题描述
所以我试图使用电子建立一个应用程序,该程序是相当基本的,用户应该上传一对夫妇的照片,他们按一个按钮,我把它们绘制到< 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
在点击
的
// 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屋!