我正在使用下面的代码来比较两个画布元素
@H_502_2@function createImage(html,can) {
var canvas = $( "#" + can );
var ctx = canvas[0].getContext("2d");
var data = "<svg xmlns='http://www.w3.org/2000/svg' width='1000' height='1000'>" +
"<foreignObject width='100%' height='100%'>" +
"<div xmlns='http://www.w3.org/1999/xhtml'>" +
html +
"</div>" +
"</foreignObject>" +
"</svg>";
var DOMURL = self.URL || self.webkitURL || self;
var img = new Image();
img.crossOrigin = '';
var svg = new Blob([data],{ type: "image/svg+xml;charset=utf-8" });
var url = DOMURL.createObjectURL(svg);
img.onload = function () {
ctx.drawImage(img,0);
DOMURL.revokeObjectURL(url);
};
img.src = url;
//return img.src;
return canvas[0];
}
var a1 = createImage("<span style='font-size:34px'><i><b>Hello</b></i></span>","can1");
var a2 = createImage("<span style='font-size:34px'><i><b>Hello</b></i></span>","can2");
setTimeout(function() {
var ctx1 = a1.getContext('2d');
var imageData = ctx1.getImageData(0,a1.width,a1.height);
var pixels = imageData.data;
var ctx2 = a2.getContext('2d');
var imageData2 = ctx2.getImageData(0,a2.width,a2.height);
var pixels2 = imageData2.data,count;
for(var i = 0,il = pixels.length; i < il; i++) {
if(pixels[i] == pixels2[i]){
count++;
}
}
if(count === pixels.length && count === pixels2.length){
alert("Match");
}
},5000);
但它正在回报我错误如下
Unable to get image data from canvas because the canvas has been tainted by cross-origin data.
如何摆脱这个错误?
解决方法
你得到交叉起始错误的原因是因为使用了< svg>命名空间声明位于http://www.w3.org/,其起源不同:
@H_502_2@var data = "<svg xmlns='http://www.w3.org/2000/svg' width='1000' height='1000'>" +
"<foreignObject width='100%' height='100%'>" +
"<div xmlns='http://www.w3.org/1999/xhtml'>" +
html +
"</div>" +
"</foreignObject>" +
"</svg>";
我可以说这个方法是从Drawing DOM objects into a canvas on MDN开始的.
当您以这种方式重新访问数据时,
@H_502_2@var ctx1 = a1.getContext('2d'); var imageData = ctx1.getImageData(0,a1.height);你会打错误:
Unable to get image data from canvas because the canvas has been tainted by cross-origin data.
您可以在Chrome上测试:
> Your original version带有错误
> Another version with namespace declarations removed,由于缺少命名空间声明,它不会引发错误,同时也是空白的
您只能从函数返回数据,以避免得到此错误.但是由于img.onload的异步性质,
@H_502_2@img.onload = function () { ctx.drawImage(img,0); DOMURL.revokeObjectURL(url); };您必须延迟检索数据,强制您重新访问该函数中的数据并导致错误.
因此,您应该使用不依赖于< svg>(如html2canvas)的DOM对象来构建画布的备用方法.
@H_502_2@function createImage(html) { var dfd = new $.Deferred(); var el = document.createElement("div"); el.innerHTML = html; el.style.display = 'inline-block'; document.body.appendChild(el); html2canvas(el,{ onrendered: function(canvas) { document.body.appendChild(canvas); document.body.removeChild(el); dfd.resolve(canvas.toDataURL()); } }); return dfd; } $.when( createImage("<span style='font-size:34px'><i><b>Hello</b></i></span>"),createImage("<span style='font-size:34px'><i><b>Hello</b></i></span>") ).done(function(a1,a2){ if (a1 === a2) { alert("Match"); } });见DEMO.