所以我尝试使用电子构建应用程序,该程序非常基本,用户应该上传几张图片,按下按钮,我将它们绘制成<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'/>");
}
答案 0 :(得分:1)
用户应该上传几张图片,我将它们绘制成一张 元素,他们应该能够下载它
您可以利用包含IIFE的for
循环来处理来自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
的{{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)
})
})
}