I am using below code to compare two canvas elements
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, 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, 0, a1.width, a1.height);
var pixels = imageData.data;
var ctx2 = a2.getContext('2d');
var imageData2 = ctx2.getImageData(0, 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);
But it is returning me error like below
Unable to get image data from canvas because the canvas has been tainted by cross-origin data.
How can I get rid of this error?
The reason you get a cross-origin error is because of the use of <svg>
with namespace declarations located at http://www.w3.org/
, which is of a different origin:
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>";
I can tell this method is the one from Drawing DOM objects into a canvas on MDN.
When you re-access the data this way,
var ctx1 = a1.getContext('2d');
var imageData = ctx1.getImageData(0, 0, a1.width, a1.height);
you will hit the error:
Unable to get image data from canvas because the canvas has been tainted by cross-origin data.
You can test this on Chrome:
You can only return the data from the function to avoid getting this error. But because of the asynchronous nature of img.onload
,
img.onload = function () {
ctx.drawImage(img, 0, 0);
DOMURL.revokeObjectURL(url);
};
you have to defer the retrieval of data, forcing you to re-access the data out of the function and causing the error.
Thus, you should use an alternate method of building the canvas with DOM objects that does not rely on <svg>
, like html2canvas.
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");
}
});
See DEMO.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With