5

I have two Set of Code for testing html5 canvas

Set 1 - Work perfectly

<img id="preview" src="http://www.gravatar.com/avatar/0e39d18b89822d1d9871e0d1bc839d06?s=128&d=identicon&r=PG">
<canvas id="myCanvas"/>

var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
var img = document.getElementById("preview");
ctx.drawImage(img, 10, 10);
alert(c.toDataURL());

Set 2 - Show exception error (Uncaught SecurityError: Failed to execute 'toDataURL' on 'HTMLCanvasElement': tainted canvases may not be exported. )

<img id="preview1" src="http://www.gravatar.com/avatar/0e39d18b89822d1d9871e0d1bc839d06?s=128&d=identicon&r=PG">

function getBase64() {
    var img = new Image();
    img =  document.getElementById("preview1");
    var canvas = document.createElement("canvas");
    canvas.width =img.width;
    canvas.height =img.width;
    var ctx = canvas.getContext("2d");
    ctx.drawImage(img, 0, 0);
    var dataURL = canvas.toDataURL("image/png"); //This line of code will throw exception
    alert(  dataURL.replace(/^data:image\/(png|jpg);base64,/, "")); 
}

I have no idea why in Set 1 toDataURL is not throwing any exception where Set toDataURL will throw exception and both are using same set of image.The different is in the first set i hardcode the canvas in HTML , and second set i create it through javascript.

My objective for Set 2 code is to get 64 base encode of the image.

abc cba
  • 2,563
  • 11
  • 29
  • 50

2 Answers2

13

You can just use crossOrigin Attribute.

var img= new Image();
img.setAttribute('crossOrigin', 'anonymous');
img.src = url;
Shady Mohamed Sherif
  • 15,003
  • 4
  • 45
  • 54
7

This is a CORS issue - Gravatar sends the correct headers, you just need to put the correct attribute in:

<img id="preview1" crossorigin="anonymous" src="http://www.gravatar.com/avatar/0e39d18b89822d1d9871e0d1bc839d06?s=128&d=identicon&r=PG">

function getBase64() {
    var img = document.getElementById("preview1");
    var canvas = document.createElement("canvas");
    canvas.width = img.width;
    canvas.height = img.width;
    var ctx = canvas.getContext("2d");
    ctx.drawImage(img, 0, 0);
    var dataURL = canvas.toDataURL("image/png");
    alert(dataURL.replace(/^data:image\/(png|jpg);base64,/, "")); 
}
getBase64();

Note that your first example also failed when I tested it, just as it should.

Qantas 94 Heavy
  • 15,750
  • 31
  • 68
  • 83
  • 1
    is it ? mine first example is working find . thx for your answer . by adding crossorigin it work for the second – abc cba Nov 17 '13 at 07:25
  • In my case I still had to add headers to apache htaccess, however this was required to make them work in Chrome on localhost – Dima Jan 08 '16 at 19:42
  • 1
    The important part is the: **** attribute. You can also set it using plain JS as it's explained in the following answer: **img.setAttribute('crossOrigin', 'anonymous');** – Patricio Córdova Apr 19 '16 at 05:25