34

I'm loading an image in js and draw it into a canvas. After drawing, i retrieve imageData from the canvas:

var img = new Image();
img.onload = function() {
    canvas.drawImage(img, 0, 0);
    originalImageData = canvas.getImageData(0,0,width, height)); //chrome fails
}
img.src = 'picture.jpeg';

This works perfectly both in Safari and Firefox, but fails in Chrome with the following message:

Unable to get image data from canvas because the canvas has been tainted by cross-origin data.

The javascript file and the image are located in the same directory, so i don't understand the behavior of chorme.

Samuel Müller
  • 1,167
  • 1
  • 10
  • 12
  • 1
    possible duplicate of [context.getImageData() on localhost?](http://stackoverflow.com/questions/8688600/context-getimagedata-on-localhost) – mplungjan Apr 02 '12 at 07:18
  • 3
    If this is not from a web server you get this issue it seems – mplungjan Apr 02 '12 at 07:19
  • And...if you want to do cross origin `` stuff, use `.crossOrigin`. See http://blog.chromium.org/2011/07/using-cross-domain-images-in-webgl-and.html – ebidel Apr 02 '12 at 18:29
  • 5
    Actually this shouldn't be a cross origin issue since the js and image file are located in the same directory. And setting the crossOrigin flag doesn't work. All i want to do is run this locally in my browser, but chrome thinks its a cross-origin resource sharing policy issue... – Samuel Müller Apr 03 '12 at 07:40
  • @sam I am experiencing the same issue, and I believe this is a bug (although I'm not sure where to report it). – snapfractalpop Feb 19 '13 at 20:21
  • meaning that js and image in different dir can be done?I try it but it doesn't work – Huei Tan Mar 18 '13 at 13:13

6 Answers6

25

To enable CORS (Cross-Origin Resource Sharing) for your images pass the HTTP header with the image response:

Access-Control-Allow-Origin: *

The origin is determined by domain and protocol (e.g. http and https are not the same) of the webpage and not the location of the script.

If you are running locally using file:// this is generally always seen as a cross domain issue; so its better to go via

http://localhost/
Ben Adams
  • 3,281
  • 23
  • 26
  • 2
    is right, using file:// is seen as a cross domain issue. The same code using file:// shows this error and using http:// it works fine. Thanks. – pocjoc May 20 '13 at 19:53
14

To solve the cross domain issue with file://, you can start chrome with the parameter

--allow-file-access-from-files
Markus Madeja
  • 848
  • 7
  • 10
  • 1
    Thanks Markus! This solution works for me much quicker. To explain it a little bit, you need to exit chrome first and if you are running on Mac, open terminal and run ```open /Applications/Google\ Chrome.app --args --allow-file-access-from-files``` command – yeelan Apr 08 '15 at 21:54
6
var img = new Image();
img.onload = function() {
    canvas.drawImage(img, 0, 0);
    originalImageData = canvas.getImageData(0,0,width, height)); //chrome will not fail
}
img.crossOrigin = 'http://profile.ak.fbcdn.net/crossdomain.xml';//crossdomain xml file, this is facebook example
img.src = 'picture.jpeg';

Hope this helps

  • 3
    `http://profile.ak.fbcdn.net/crossdomain.xml` is not a valid value for the [crossorigin attribute](http://www.w3.org/TR/html5/infrastructure.html#cors-settings-attribute) and `crossdomain.xml` files are a thing used by Adobe Flash, not CORS. – Quentin Nov 24 '15 at 10:03
3
var canvas = document.createElement("canvas");
var ctx = canvas.getContext("2d");
var img = new Image();
img.crossOrigin = "anonymous";
img.onload = function() {
  canvas.width = img.width;
  canvas.height = img.height;
  ctx.drawImage(img, 0, 0);
  originalImageData = ctx.canvas.toDataURL();
}
img.src = 'picture.jpeg';

hope this helps.

code.rider
  • 1,891
  • 18
  • 21
0

If the server response headers contains Access-Control-Allow-Origin: *, then you can fix it from client side: Add an attribute to the image or video.

<img src="..." crossorigin="Anonymous" />
<video src="..." crossorigin="Anonymous"></video>

Otherwise you have to use server side proxy.

Jeff Tian
  • 5,210
  • 3
  • 51
  • 71
0

Make sure you are serving the local files rather than browsing to them. If you are on OSX you already have a Python Server installed. Simply cd into your web site’s directory in the command line, run python -m SimpleHTTPServer, then go to http://localhost:8000/ in the browser.

Alternately, you can use Node. Run npm install -g http-server, then http-server. This will serve your index page on port 8080, i.e. browse to http://localhost:8080/.

Reggie Pinkham
  • 11,985
  • 4
  • 38
  • 36