context.drawImage() doesn't work in html canvas? [duplicate] - javascript

I am trying to paint an image on a canvas before I get its dataURL(), but the data returned is like empty.
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=")
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.
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 ?

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 :
// 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.
If your image comes from the same server, no problem.
If your image is served from an external server, be sure that it allows yours in its cross-origin headers and set the img.crossOrigin to "use-credentials".
If the server does allow anonymous requests, you can set the img.crossOrigin to "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.
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.
function corsError(){
this.crossOrigin='';
this.src='';
this.removeEventListener('error', corsError, false);
}
img.addEventListener('error', corsError, false);

Related

No image width, canvas / constructor javascript / game [duplicate]

I am trying to paint an image on a canvas before I get its dataURL(), but the data returned is like empty.
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=")
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.
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 ?
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 :
// 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.
If your image comes from the same server, no problem.
If your image is served from an external server, be sure that it allows yours in its cross-origin headers and set the img.crossOrigin to "use-credentials".
If the server does allow anonymous requests, you can set the img.crossOrigin to "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.
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.
function corsError(){
this.crossOrigin='';
this.src='';
this.removeEventListener('error', corsError, false);
}
img.addEventListener('error', corsError, false);

canvas empty after adding image [duplicate]

I am trying to paint an image on a canvas before I get its dataURL(), but the data returned is like empty.
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=")
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.
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 ?
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 :
// 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.
If your image comes from the same server, no problem.
If your image is served from an external server, be sure that it allows yours in its cross-origin headers and set the img.crossOrigin to "use-credentials".
If the server does allow anonymous requests, you can set the img.crossOrigin to "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.
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.
function corsError(){
this.crossOrigin='';
this.src='';
this.removeEventListener('error', corsError, false);
}
img.addEventListener('error', corsError, false);

Resize cordova.camera image before sending to server [duplicate]

I am trying to paint an image on a canvas before I get its dataURL(), but the data returned is like empty.
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=")
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.
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 ?
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 :
// 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.
If your image comes from the same server, no problem.
If your image is served from an external server, be sure that it allows yours in its cross-origin headers and set the img.crossOrigin to "use-credentials".
If the server does allow anonymous requests, you can set the img.crossOrigin to "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.
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.
function corsError(){
this.crossOrigin='';
this.src='';
this.removeEventListener('error', corsError, false);
}
img.addEventListener('error', corsError, false);

Image onload is not getting called

I am trying to read an Image from external URL as Data URL.
Here is my code
var canvas = document.createElement('canvas'),
ctx = canvas.getContext('2d'),
img = new Image();
img.onload = function(){
canvas.height = img.height;
canvas.width = img.width;
ctx.drawImage(img, 0, 0);
console.log(canvas.toDataURL("image/jpeg"));
canvas = null;
};
img.crossOrigin = 'anonymous';
img.src = "http://pierre.chachatelier.fr/programmation/images/mozodojo-original-image.jpg";
Here onload of Image is not getting called.
But when I Remove img.crossOrigin = 'anonymous'; onload is getting called and browser throws error SecurityError: The operation is insecure.
This error is from Mozilla.
Chrome giving error -
Uncaught SecurityError: Failed to execute 'toDataURL' on 'HTMLCanvasElement': Tainted canvases may not be exported.
Can't test on IE as on a Linux machine
I can't find what else is wrong with the code.
You can only apply canvas.toDataURL("image/jpeg") to a file that exists in your project. According to my idea, you can use remote image from other website to convert it to base64 image. One solution is, to save the image from the website you want to get it, then apply canvas.toDataURL() to that saved image.
I changed my code. Now I am sending the bytes from server instead of Image url using code :
URL u = new URL(url);
InputStream is = u.openStream();
byte[] = IOUtils.toByteArray(is);

CORS error depending on an image parameters setting order

I'm using a canvas to display an image and get info on a specific portion of that image using getImageData(). Depending the order in which I set the image parameters, it works or not.
The method is called with onload on the document body. Here is the code:
function draw() {
var canvas = document.getElementById("canvas");
if (canvas.getContext) {
var ctx = canvas.getContext("2d");
var img = new Image();
img.src = "url_to_image";
img.crossOrigin = "anonymous";
canvas.width = img.width;
canvas.height = img.height;
ctx.drawImage( img, 0, 0 );
var data = document.getElementById('canvas').getContext('2d').getImageData( 310, 320, 1, 1 ).data
}
}
This triggers the following crossOrigin error:
Cross-origin image load denied by Cross-Origin Resource Sharing policy.
The server from which I get back the image is configured to set me back an Access-Control-Allow-Origin:* response header with the image.
However, everything works just fine if I just set the img.crossOrigin before the image.src doing :
img.crossOrigin = "anonymous";
img.src = "url_to_image";
This seems very peculiar to me. Anybody have an idea of what is happening?
.crossOrigin must come before .src
That's because .src actually starts the download.
The browser must know if anonymous access is allowed when it starts the download or it will default to not allowing cross origin access.
Cross Origin sharing is almost fully supported in modern browsers (FF,Chrome,Safari,Opera,Android). The mini version of Opera is the only major non-supporting browser.
And, as you've discovered, the server delivering the data must be configured to send appropriate headers to let the browser know that cross sharing is allowed.

Categories