CanvasContext2D drawImage() issue [onload and CORS]

CanvasContext2D drawImage() issue [onload and CORS]



I am trying to paint an image on a canvas before I get its dataURL(), but the data returned is like empty.


dataURL()



When I check it in the console, I see there is a lot of A in the string : ("data:image/png;base64,iVBO..some random chars... bQhfoAAAAAAAAAA... a lot of A ...AAAASUVORK5CYII=")


A


"data:image/png;base64,iVBO..some random chars... bQhfoAAAAAAAAAA... a lot of A ...AAAASUVORK5CYII="



When I try to append the canvas to the document, nothing is drawn either and I don't have any error thrown in the console.



What is the problem here ?



Here is my code :


var img = new Image();
img.src = "http://somerandomWebsite/picture.png";
var canvas = document.createElement('canvas');
canvas.width = img.width;
canvas.height = img.height;
var context = canvas.getContext('2d');
context.drawImage(img, 0,0); // this doesn't seem to work
var dataURL = canvas.toDataURL(); // this will give me a lot of "A"
doSomething(dataURL);



Also, when doing a quick refresh, the image gets drawn correctly onto the canvas but I've got an error message in the console and dataURL is empty.


dataURL



The message in Firefox is : "SecurityError: The operation is insecure.",

in Chrome it is "Uncaught SecurityError: Failed to execute 'toDataURL' on 'HTMLCanvasElement': Tainted canvases may not be exported.",

and on IE I just get "SecurityError".



What does it mean ?





This post is meant to be a canonical one for the 20 or so a week we get about this particular issue. Please let me know if it can be improved.
– Kaiido
Oct 1 '15 at 6:20





Isn't just the point of loading images before doing anything with them more relevant ? And if you think useful to refer to toDataURL, you should mention the (possible) CORS issue. Anyway +1 for the wiki idea / effort.
– GameAlchemist
Oct 1 '15 at 9:04






@GameAlchemist you're right, I tried to combine both issues, since they're really similar and often come in pair. I talked about the CORS issue in the answer. Don't know how search engines will deal with that though, maybe I should add the "canvas is tainted" message error into the question. Anyway, I asked that the question is converted to wiki too, this way, you'll be able to edit it.
– Kaiido
Oct 1 '15 at 14:02




1 Answer
1



You have to wait that your image has loaded before you can paint it on the canvas.



To do so, simply use the load event handler of your <img> element :


load


<img>


// create a new image
var img = new Image();
// declare a function to call once the image has loaded
img.onload = function()
var canvas = document.createElement('canvas');
canvas.width = img.width;
canvas.height = img.height;
var context = canvas.getContext('2d');
context.drawImage(img, 0,0);
var dataURL = canvas.toDataURL();
// now you can do something with the dataURL
doSomething(dataURL);

// now set the image's src
img.src = "http://somerandomWebsite/picture.png";



Also, for the canvas' context.toDataURL() and context.getImageData to work properly, you have to get your image resource in a cross-origin compliant way, otherwise the canvas is "tainted" which means that any method to get pixels data will be blocked.


context.toDataURL()


context.getImageData


img.crossOrigin


"use-credentials"


img.crossOrigin


"anonymous"



Nota Bene : CORS header is sent by the server, the cross-origin attribute will only let it know that you want to use CORS to get the image data, in no way you can circumvent it if the server is not set properly.

Also some UserAgents (IE & Safari) still haven't implemented this attribute.


cross-origin



Edge Case : If some of your images are from your server and some are from a CORS compliant one, then you may want to use the onerror event handler which should fire if you set the cross-origin attribute to "anonymous" on a non CORS server.


onerror


cross-origin


"anonymous"


function corsError()
this.crossOrigin='';
this.src='';
this.removeEventListener('error', corsError, false);

img.addEventListener('error', corsError, false);



Thanks for contributing an answer to Stack Overflow!



But avoid



To learn more, see our tips on writing great answers.



Some of your past answers have not been well-received, and you're in danger of being blocked from answering.



Please pay close attention to the following guidance:



But avoid



To learn more, see our tips on writing great answers.



Required, but never shown



Required, but never shown




By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Popular posts from this blog

𛂒𛀶,𛀽𛀑𛂀𛃧𛂓𛀙𛃆𛃑𛃷𛂟𛁡𛀢𛀟𛁤𛂽𛁕𛁪𛂟𛂯,𛁞𛂧𛀴𛁄𛁠𛁼𛂿𛀤 𛂘,𛁺𛂾𛃭𛃭𛃵𛀺,𛂣𛃍𛂖𛃶 𛀸𛃀𛂖𛁶𛁏𛁚 𛂢𛂞 𛁰𛂆𛀔,𛁸𛀽𛁓𛃋𛂇𛃧𛀧𛃣𛂐𛃇,𛂂𛃻𛃲𛁬𛃞𛀧𛃃𛀅 𛂭𛁠𛁡𛃇𛀷𛃓𛁥,𛁙𛁘𛁞𛃸𛁸𛃣𛁜,𛂛,𛃿,𛁯𛂘𛂌𛃛𛁱𛃌𛂈𛂇 𛁊𛃲,𛀕𛃴𛀜 𛀶𛂆𛀶𛃟𛂉𛀣,𛂐𛁞𛁾 𛁷𛂑𛁳𛂯𛀬𛃅,𛃶𛁼

Edmonton

Crossroads (UK TV series)