所以我尝试使用电子构建一个应用程序,该程序非常基本,用户应该上传几张图片,他们按下按钮,我将它们绘制到 <canvas>
中元素,他们应该能够下载它,我遇到的问题是,当我尝试制作可下载按钮时,会抛出安全错误,我做了一些研究,发现这是 HTML5 的一个功能,我的想法是我无法添加 crossOrigin = 'Anonymous' 因为用户将从自己的计算机加载图片,所以我的问题是...
a)- 有没有办法“欺骗系统”并能够下载 Canvas 的内容?,
b)- 如果 (a) 不可行...是否有替代方案可以类似于 Canvas 元素?
我已经使用 FileReader() 来获取用户选择的图片,并且我已经将其绘制到 Canvas 中,它看起来很棒,我遇到的问题是我无法下载该内容我是为了那个安全错误而创建的。无法调用 .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);
}
}
这是一个简单的函数,用于查看是否可以从 Canvas 中获取 Url:
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
您可以使用for
包含要处理的 IIFE 的循环 files
来自 input type="file"
的对象元素,new Image
, onload
事件<img>
元素,URL.createObjectURL()
, Array.prototype.sort()
确定最大width
两张上传的图像; Promise.all()
, Array.prototype.forEach()
处理img
元素; canvas.toBlob()
polyfill 创建 objectURL
图像的; <a>
元素具有download
属性设置为 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)
})
})
}
<a download="" href="" style="display:none">download</a>
<input type="file" accept="image/*" multiple />
<br>
<canvas></canvas>
关于javascript - 无法下载 Canvas 内容,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36880509/