Cannot get Image Data from a canvas

1.2k views Asked by At

The following function should get image data (using context.getImageData() from an exisitng canvas, containing an image (already loaded on the webpage), and a second canvas that is not shown on the page.

The first canvas' data is "got"as expected, and alert(data1.data.length) pops up with a reasonable number. However the second canvas' data is not "got" got, and the function breaks before the alert(data2.data.length); line. That is the only line that does not seem to work in the whole function, and is my problem.

function operateImage(){

    var operand = new Image();
    var data1, data2;
    //exisiting canvas
    var c =document.getElementById("edit_canvas");
    var ctx=c.getContext("2d");

    var operation = document.getElementById("operation").value;

    //make a new temporary canvas and store the input image
    var hiddenCanvas = document.createElement('canvas');
    var hiddenCtx = hiddenCanvas.getContext('2d');
    operand.src = document.getElementById("operation_image").value; 
    hiddenCanvas.width = operand.width;
    hiddenCanvas.height = operand.height;

    hiddenCtx.drawImage(operand,0,0);
    //get image data objects from both canvases
    data1 = ctx.getImageData(0,0,c.width,c.height);
    alert(data1.data.length);
    data2 = hiddenCtx.getImageData(0,0,hiddenCanvas.width,hiddenCanvas.height);
    alert(data2.data.length);

    /*pass the two image data objects to another function for processing*/
}

After the function gets the image data it will pass them to another function depending on the operation value. (which will AND, OR, XOR, or NOT the contents of the pixel data arrays together)

Edit: This is an error message I get: " Uncaught SecurityError: Failed to execute 'getImageData' on 'CanvasRenderingContext2D': The canvas has been tainted by cross-origin data."

1

There are 1 answers

0
Gio On BEST ANSWER

There is nothing wrong with your code, but it's failing because the source image (operand.src) is on a different domain, and cross-origin operations are not allowed. More specifically, you cannot getImageData from a canvas where you have drawn an image with a different origin.

Unfortunately there is no solution to this unless you have access to the server where the source image is coming from. The server needs to set a HTTP header like this:

Access-Control-Allow-Origin: *

And, on the client side, you need to allow cross-origin sources before drawing to your hidden canvas:

operand.crossOrigin = 'anonymous';

Setting these values (* and 'anonymous') completely disables the cross-origin checks, which may not be what you want. You could set values that match the specific domain(s) that you want to use.