Trying to compare two Canvas elements

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?

Answers


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.


Need Your Help

Is there a way to document cuda's “.cu” file use doxygen

cuda doxygen

As the cuda's ".cu" file is basically c, Is there a way we can use doxygen to generate documentation for ".cu" files? I noticed that NVIDIA use doxygen to generate cuda's docuementation. However wh...

Java for loop to get X

java loops for-loop

I need help with a for loop I have for an assignment.

Rails, Node.js cross-server authentication

ruby-on-rails session mongodb node.js devise

So I'm making a rails app that also utilizes node.js for realtime features. What is the best way to authenticate the users on the node app, if they were created with devise on rails? I've been thin...