why do not save pictures from the Canvas? [duplicate] - javascript

So I'm using google maps and I get the picture so it looks like this
<img id="staticMap"
src="http://maps.googleapis.com/maps/api/staticmap?center=Brooklyn+Bridge,New+York,NY&zoom=13&size=600x300&maptype=roadmap
&markers=color:blue%7Clabel:S%7C40.702147,-74.015794&markers=color:green%7Clabel:G%7C40.711614,-74.012318
&markers=color:red%7Ccolor:red%7Clabel:C%7C40.718217,-73.998284&sensor=false">
I need to save it. I have found this:
function getBase64FromImageUrl(URL) {
var img = new Image();
img.src = URL;
img.onload = function() {
var canvas = document.createElement("canvas");
canvas.width = this.width;
canvas.height = this.height;
var ctx = canvas.getContext("2d");
ctx.drawImage(this, 0, 0);
var dataURL = canvas.toDataURL("image/png");
alert(dataURL.replace(/^data:image\/(png|jpg);base64,/, ""));
};
}
But I get this problem:
Uncaught SecurityError: Failed to execute 'toDataURL' on 'HTMLCanvasElement': tainted canvases may not be exported.
I searched for fixes. I found a sample here How to use CORS but still I can't tie these 2 pieces of code together to make it work. Maybe I'm doing it the wrong way and there is a simpler way to do it? I'm trying to save this pic so that I can transfer the data to my server. So maybe someone did something like this and knows how to make .toDataURL() work as I need it?

Unless google serves this image with the correct Access-Control-Allow-Origin header, then you wont be able to use their image in canvas. This is due to not having CORS approval. You can read more about this here, but it essentially means:
Although you can use images without CORS approval in your canvas,
doing so taints the canvas. Once a canvas has been tainted, you can no
longer pull data back out of the canvas. For example, you can no
longer use the canvas toBlob(), toDataURL(), or getImageData()
methods; doing so will throw a security error.
This protects users from having private data exposed by using images
to pull information from remote web sites without permission.
I suggest just passing the URL to your server-side language and using curl to download the image. Be careful to sanitise this though!
EDIT:
As this answer is still the accepted answer, you should check out #shadyshrif's answer, which is to use:
var img = new Image();
img.setAttribute('crossOrigin', 'anonymous');
img.src = url;
This will only work if you have the correct permissions, but will at least allow you to do what you want.

Just use the crossOrigin attribute and pass 'anonymous' as the second parameter
var img = new Image();
img.setAttribute('crossOrigin', 'anonymous');
img.src = url;

This method will prevent you from getting an 'Access-Control-Allow-Origin' error from the server you are accessing to.
var img = new Image();
var timestamp = new Date().getTime();
img.setAttribute('crossOrigin', 'anonymous');
img.src = url + '?' + timestamp;

Try the code below ...
<img crossOrigin="anonymous"
id="imgpicture"
fall-back="images/penang realty,Apartment,house,condominium,terrace house,semi d,detached,
bungalow,high end luxury properties,landed properties,gated guarded house.png"
ng-src="https://www.google.com/images/branding/googlelogo/2x/googlelogo_color_272x92dp.png"
height="220"
width="200"
class="watermark">

In my case I was using the WebBrowser control (forcing IE 11) and I could not get past the error. Switching to CefSharp which uses Chrome solved it for me.

I had the same error message. I had the file in a simple .html, when I passed the file to php in Apache it worked
html2canvas(document.querySelector('#toPrint')).then(canvas => {
let pdf = new jsPDF('p', 'mm', 'a4');
pdf.addImage(canvas.toDataURL('image/png'), 'PNG', 0, 0, 211, 298);
pdf.save(filename);
});

if the picture from the 3rd party site didn't set the header for cors ("access-control-allow-origin"), you can never download the picture file through chrome,
even if you use the setAttribute('crossOrigin', 'anonymous');
Here are some suggestions
hack chrome (use an extension, this will only work on your machine)
proxy the image through a service running on your site. The browser will see the domain as your site. This requires your service to request the image from the 3rd party.

By using fabric js we can solve this security error issue in IE.
function getBase64FromImageUrl(URL) {
var canvas = new fabric.Canvas('c');
var img = new Image();
img.onload = function() {
var canvas1 = document.createElement("canvas");
canvas1.width = this.width;
canvas1.height = this.height;
var ctx = canvas.getContext('2d');
ctx.drawImage(this, 0, 0);
var dataURL = canvas.toDataURL({format: "png"});
};
img.src = URL;
}

Related

Store animated GIF image in local Storage using pure JavaScript

I have a requirement where I need to store the GIF image in local storage. I have been trying to do this using following code:
function imgToURI(image) {
var canvasTemp = document.createElement('canvas');
canvasTemp.width = image.naturalWidth; // or 'width' if you want a special/scaled size
canvasTemp.height = image.naturalHeight; // or 'height' if you want a special/scaled size
canvasTemp.getContext('2d').drawImage(image, 0, 0);
var dataUri = canvasTemp.toDataURL('image/gif');
// Modify Data URI beginning
dataUri = 'data:image/gif;' + dataUri.substring(15);
return dataUri;
}
window.onload = function () {
var img = new Image();
img.src = 'http://pop.h-cdn.co/assets/16/33/480x264/gallery-1471381857-gif-season-2.gif';
localStorage.setItem('test', imgToURI(img));
};
The above code outputs data:image/gif; in local storage. Also I can't find any errors on console.
I have been trying a lot but don't know why image is not getting stored. Please let me know if you have solution to above problem.
maybe when your code is executed the image was not loaded yet. So only the string 'data:image/gif will be saved
var img = new Image();
img.addEventListener('load', function() {
localStorage.setItem('test', imgToURI(img));
}, false);
img.src = 'http://pop.h-cdn.co/assets/16/33/480x264/gallery-1471381857-gif-season-2.gif';
this code will attempt to save the image only if its loaded completely
EDIT
You are having this error because the image the image is not coming from your server: this CORS issue. you can try this but you have to trust the server who host the image
just before the addEventListener
img.setAttribute('crossOrigin', 'anonymous');
It can be due to Cross-Origin request not allowing you to get the canvas data. You have to make sure to use an image from a "trusted" source (server which allows Cross-Origin on your domain), so that your canvas doesn't get tainted.

Overlay two images to one img src [duplicate]

So I'm using google maps and I get the picture so it looks like this
<img id="staticMap"
src="http://maps.googleapis.com/maps/api/staticmap?center=Brooklyn+Bridge,New+York,NY&zoom=13&size=600x300&maptype=roadmap
&markers=color:blue%7Clabel:S%7C40.702147,-74.015794&markers=color:green%7Clabel:G%7C40.711614,-74.012318
&markers=color:red%7Ccolor:red%7Clabel:C%7C40.718217,-73.998284&sensor=false">
I need to save it. I have found this:
function getBase64FromImageUrl(URL) {
var img = new Image();
img.src = URL;
img.onload = function() {
var canvas = document.createElement("canvas");
canvas.width = this.width;
canvas.height = this.height;
var ctx = canvas.getContext("2d");
ctx.drawImage(this, 0, 0);
var dataURL = canvas.toDataURL("image/png");
alert(dataURL.replace(/^data:image\/(png|jpg);base64,/, ""));
};
}
But I get this problem:
Uncaught SecurityError: Failed to execute 'toDataURL' on 'HTMLCanvasElement': tainted canvases may not be exported.
I searched for fixes. I found a sample here How to use CORS but still I can't tie these 2 pieces of code together to make it work. Maybe I'm doing it the wrong way and there is a simpler way to do it? I'm trying to save this pic so that I can transfer the data to my server. So maybe someone did something like this and knows how to make .toDataURL() work as I need it?
Unless google serves this image with the correct Access-Control-Allow-Origin header, then you wont be able to use their image in canvas. This is due to not having CORS approval. You can read more about this here, but it essentially means:
Although you can use images without CORS approval in your canvas,
doing so taints the canvas. Once a canvas has been tainted, you can no
longer pull data back out of the canvas. For example, you can no
longer use the canvas toBlob(), toDataURL(), or getImageData()
methods; doing so will throw a security error.
This protects users from having private data exposed by using images
to pull information from remote web sites without permission.
I suggest just passing the URL to your server-side language and using curl to download the image. Be careful to sanitise this though!
EDIT:
As this answer is still the accepted answer, you should check out #shadyshrif's answer, which is to use:
var img = new Image();
img.setAttribute('crossOrigin', 'anonymous');
img.src = url;
This will only work if you have the correct permissions, but will at least allow you to do what you want.
Just use the crossOrigin attribute and pass 'anonymous' as the second parameter
var img = new Image();
img.setAttribute('crossOrigin', 'anonymous');
img.src = url;
This method will prevent you from getting an 'Access-Control-Allow-Origin' error from the server you are accessing to.
var img = new Image();
var timestamp = new Date().getTime();
img.setAttribute('crossOrigin', 'anonymous');
img.src = url + '?' + timestamp;
Try the code below ...
<img crossOrigin="anonymous"
id="imgpicture"
fall-back="images/penang realty,Apartment,house,condominium,terrace house,semi d,detached,
bungalow,high end luxury properties,landed properties,gated guarded house.png"
ng-src="https://www.google.com/images/branding/googlelogo/2x/googlelogo_color_272x92dp.png"
height="220"
width="200"
class="watermark">
In my case I was using the WebBrowser control (forcing IE 11) and I could not get past the error. Switching to CefSharp which uses Chrome solved it for me.
I had the same error message. I had the file in a simple .html, when I passed the file to php in Apache it worked
html2canvas(document.querySelector('#toPrint')).then(canvas => {
let pdf = new jsPDF('p', 'mm', 'a4');
pdf.addImage(canvas.toDataURL('image/png'), 'PNG', 0, 0, 211, 298);
pdf.save(filename);
});
if the picture from the 3rd party site didn't set the header for cors ("access-control-allow-origin"), you can never download the picture file through chrome,
even if you use the setAttribute('crossOrigin', 'anonymous');
Here are some suggestions
hack chrome (use an extension, this will only work on your machine)
proxy the image through a service running on your site. The browser will see the domain as your site. This requires your service to request the image from the 3rd party.
By using fabric js we can solve this security error issue in IE.
function getBase64FromImageUrl(URL) {
var canvas = new fabric.Canvas('c');
var img = new Image();
img.onload = function() {
var canvas1 = document.createElement("canvas");
canvas1.width = this.width;
canvas1.height = this.height;
var ctx = canvas.getContext('2d');
ctx.drawImage(this, 0, 0);
var dataURL = canvas.toDataURL({format: "png"});
};
img.src = URL;
}

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);

canvas.toDataURL() SecurityError

So I'm using google maps and I get the picture so it looks like this
<img id="staticMap"
src="http://maps.googleapis.com/maps/api/staticmap?center=Brooklyn+Bridge,New+York,NY&zoom=13&size=600x300&maptype=roadmap
&markers=color:blue%7Clabel:S%7C40.702147,-74.015794&markers=color:green%7Clabel:G%7C40.711614,-74.012318
&markers=color:red%7Ccolor:red%7Clabel:C%7C40.718217,-73.998284&sensor=false">
I need to save it. I have found this:
function getBase64FromImageUrl(URL) {
var img = new Image();
img.src = URL;
img.onload = function() {
var canvas = document.createElement("canvas");
canvas.width = this.width;
canvas.height = this.height;
var ctx = canvas.getContext("2d");
ctx.drawImage(this, 0, 0);
var dataURL = canvas.toDataURL("image/png");
alert(dataURL.replace(/^data:image\/(png|jpg);base64,/, ""));
};
}
But I get this problem:
Uncaught SecurityError: Failed to execute 'toDataURL' on 'HTMLCanvasElement': tainted canvases may not be exported.
I searched for fixes. I found a sample here How to use CORS but still I can't tie these 2 pieces of code together to make it work. Maybe I'm doing it the wrong way and there is a simpler way to do it? I'm trying to save this pic so that I can transfer the data to my server. So maybe someone did something like this and knows how to make .toDataURL() work as I need it?
Unless google serves this image with the correct Access-Control-Allow-Origin header, then you wont be able to use their image in canvas. This is due to not having CORS approval. You can read more about this here, but it essentially means:
Although you can use images without CORS approval in your canvas,
doing so taints the canvas. Once a canvas has been tainted, you can no
longer pull data back out of the canvas. For example, you can no
longer use the canvas toBlob(), toDataURL(), or getImageData()
methods; doing so will throw a security error.
This protects users from having private data exposed by using images
to pull information from remote web sites without permission.
I suggest just passing the URL to your server-side language and using curl to download the image. Be careful to sanitise this though!
EDIT:
As this answer is still the accepted answer, you should check out #shadyshrif's answer, which is to use:
var img = new Image();
img.setAttribute('crossOrigin', 'anonymous');
img.src = url;
This will only work if you have the correct permissions, but will at least allow you to do what you want.
Just use the crossOrigin attribute and pass 'anonymous' as the second parameter
var img = new Image();
img.setAttribute('crossOrigin', 'anonymous');
img.src = url;
This method will prevent you from getting an 'Access-Control-Allow-Origin' error from the server you are accessing to.
var img = new Image();
var timestamp = new Date().getTime();
img.setAttribute('crossOrigin', 'anonymous');
img.src = url + '?' + timestamp;
Try the code below ...
<img crossOrigin="anonymous"
id="imgpicture"
fall-back="images/penang realty,Apartment,house,condominium,terrace house,semi d,detached,
bungalow,high end luxury properties,landed properties,gated guarded house.png"
ng-src="https://www.google.com/images/branding/googlelogo/2x/googlelogo_color_272x92dp.png"
height="220"
width="200"
class="watermark">
In my case I was using the WebBrowser control (forcing IE 11) and I could not get past the error. Switching to CefSharp which uses Chrome solved it for me.
I had the same error message. I had the file in a simple .html, when I passed the file to php in Apache it worked
html2canvas(document.querySelector('#toPrint')).then(canvas => {
let pdf = new jsPDF('p', 'mm', 'a4');
pdf.addImage(canvas.toDataURL('image/png'), 'PNG', 0, 0, 211, 298);
pdf.save(filename);
});
if the picture from the 3rd party site didn't set the header for cors ("access-control-allow-origin"), you can never download the picture file through chrome,
even if you use the setAttribute('crossOrigin', 'anonymous');
Here are some suggestions
hack chrome (use an extension, this will only work on your machine)
proxy the image through a service running on your site. The browser will see the domain as your site. This requires your service to request the image from the 3rd party.
By using fabric js we can solve this security error issue in IE.
function getBase64FromImageUrl(URL) {
var canvas = new fabric.Canvas('c');
var img = new Image();
img.onload = function() {
var canvas1 = document.createElement("canvas");
canvas1.width = this.width;
canvas1.height = this.height;
var ctx = canvas.getContext('2d');
ctx.drawImage(this, 0, 0);
var dataURL = canvas.toDataURL({format: "png"});
};
img.src = URL;
}

Cross-origin data in HTML5 canvas

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.
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/
To solve the cross domain issue with file://, you can start chrome with the parameter
--allow-file-access-from-files
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
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.
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.

Categories