从图像(本地文件)中绘制画布后,我尝试使用命令ctx.canvas.toDataURL("image/png")
但是有一个错误:
DOMException: Failed to execute 'toDataURL' on 'HTMLCanvasElement': Tainted canvases may not be exported.
我已经在谷歌搜索了。他们说这是Cross的问题。所以,我添加了命令:
image.crossOrigin = '*';
但这对我的项目毫无用处。实际上,我的项目是在没有任何服务器的本地构建。所以,我不知道为什么存在跨域问题。
function loadImageAsync(url) {
return new Promise(function(resolve, reject) {
var image = new Image();
image.onload = function() {
image.crossOrigin = '*';
resolve(image);
};
image.onerror = function() {
reject(new Error('Could not load image at ' + url));
};
image.src = url;
});
generate() {
var p1 = loadImageAsync(this.textures[1]);
var p2 = loadImageAsync(this.textures[2]);
var p3 = loadImageAsync(this.textures[3]);
var ctx = document.createElement("canvas")
.getContext("2d");
ctx.canvas.width = this.width;
ctx.canvas.height = this.height;
var rows = ~~(this.width / 70);
var cols = ~~(this.height / 70);
Promise.all([p1, p2, p3])
.then(imgs => {
for (let x = 0, i = 0; i < rows; x += 70, i++) {
for (let y = 630, j = 0; j < cols; y -= 70, j++) {
this.resource[i].forEach(item => {
switch (item) {
case 1:
ctx.drawImage(imgs[0], x, y, 70, 70);
break;
case 2:
ctx.drawImage(imgs[1], x, y, 70, 70);
break;
case 3:
ctx.drawImage(imgs[2], x, y, 70, 70);
break;
default:
}
});
}
}
//window.ctx = ctx;
this.image.crossOrigin = '*';
this.image.src = ctx.canvas.toDataURL("image/png");
});
};
答案 0 :(得分:2)
您需要为onload函数之外的图像设置crossOrigin
。
return new Promise(function(resolve, reject) {
var image = new Image();
image.crossOrigin = '*'; //<-- set here
image.onload = function() {
resolve(image);
};
image.onerror = function() {
reject(new Error('Could not load image at ' + url));
};
image.src = url;
});
答案 1 :(得分:0)
加载图片时,如果他们来自其他域,他们将被标记为跨域,除非他们具有CORS权限。这包括从file://
加载文件。如果使用canvas 2d,没有CORS权限的跨域图像会污染画布,如果使用WebGL则根本不可用
如果文件是本地文件,最好使用简单的服务器。 Here's one和here's a bunch more
如果图像实际上是跨域的,那么您需要通过设置img.crossOrigin
来请求CORS权限,并且服务器需要返回图像的正确标头。我相信唯一需要的标题是
Access-Control-Allow-Origin: *
您必须在设置img.crossOrigin
之前设置img.src
。设置img.crossOrigin
告诉浏览器从服务器请求权限。请求在您设置img.src
时发送。
让我们尝试使用imgur URL,我碰巧知道它支持CORS,还有你提到的URL,以及我所知道不支持CORS的网站
[
{ url: "https://i.imgur.com/TSiyiJv.jpg", crossOrigin: "*", },
{ url: "https://newmario.herokuapp.com/img/grassMid.png", crossOrigin: "*", },
{ url: "https://greggman.com/images/echidna.jpg", /* NO CORS */ },
].forEach(loadImage);
function loadImage(info) {
const url = info.url;
const img = new Image()
img.onload = function() {
const ctx = document.createElement("canvas").getContext("2d");
try {
ctx.drawImage(img, 0, 0);
ctx.canvas.toDataURL();
log("got CORS permission for:", url);
} catch(e) {
log("**NO** CORS permission for:", url);
}
}
img.onerror = function() {
log("could not load image:", url);
}
img.crossOrigin = info.crossOrigin;
img.src = url;
}
function log(...args) {
const elem = document.createElement("pre");
elem.textContent = [...args].join(' ');
document.body.appendChild(elem);
}
pre { margin: 0; }
我的结果,imgur图像有效,你的作品,我的没有(如预期的那样)
请注意,有8个案例
| local/remote | crossOrigin | CORS headers | Result
-+-----------------+---------------+---------------+---------------------
1| local | not set | no | can use image
-+-----------------+---------------+---------------+----------------------
2| local | not set | yes | can use image
-+-----------------+---------------+---------------+----------------------
3| local | set | no | image fails to load
-+-----------------+---------------+---------------+----------------------
4| local | set | yes | can use image
-+-----------------+---------------+---------------+----------------------
5| remote | not set | no | can use image in canvas 2d
| | | | but it will dirty the canvas.
| | | | Can't use with WebGL
-+-----------------+---------------+---------------+----------------------
6| remote | not set | yes | can use image in canvas 2d
| | | | but it will dirty the canvas
| | | | Can't use with WebGL
-+-----------------+---------------+---------------+----------------------
7| remote | set | no | image fails to load
-+-----------------+---------------+---------------+----------------------
8| remote | set | yes | can use image
-+-----------------+---------------+---------------+----------------------
答案 2 :(得分:0)
设置useCORS
可以解决此问题
html2Canvas(document.querySelector('#pdfDom'), {useCORS: true}).then((canvas) =>
{
let pageData = canvas.toDataURL('image/jpeg', 1.0);
}