toDataURL: throw an security error [duplicate] - javascript

This question already has answers here:
Canvas image crossplatform insecure error
(1 answer)
Cross-origin data in HTML5 canvas
(5 answers)
Closed 6 years ago.
I want to get the 64 base encode of the canvas. Below code throw an security exception: Uncaught SecurityError: Failed to execute 'toDataURL' on 'HTMLCanvasElement': Tainted canvases may not be exported.
<canvas id="canvas" width="345" height="345"></canvas>
var
canvas = document.getElementById("canvas"),
ctx = null,
img = new Image(),
dataUrl = null;
var init = function() {
img.onload = function () {
ctx.drawImage(img, 0, 0);
dataUrl = canvas.toDataURL();
};
/*img.crossOrigin = "Anonymous";*/
img.src = "./img/s1.jpg";
console.log(dataUrl);
};
if (Modernizr.canvas) {
ctx = canvas.getContext("2d");
init();
}
I also tried to add img.crossOrigin = "Anonymous"; but then i get this exception Image from origin 'file://' has been blocked from loading by Cross-Origin Resource Sharing policy: Invalid response. Origin 'null' is therefore not allowed access.

Related

How to set img.src in HTML from responseText in Javascript?

I followed this answer & file downloading is successful. The facing problem is to set downloaded image file into the img.src tag.
Image link: https://images.pexels.com/photos/853199/pexels-photo-853199.jpeg?crop=entropy&cs=srgb&dl=aerial-view-of-seashore-near-large-grey-rocks-853199.jpg&fit=crop&fm=jpg&h=4000&w=6000
Code:
function onReadyState(e){
let r = e.target;
if(r.readyState != 4 || r.status != 200){
return
}
console.log(r)
let img = document.getElementById('downloaded-img')
let base64 = btoa(r.response)
img.src = 'data:image/jpg;base64,'+base64
}
I tried to convert responseText into base64 to set img.scr for display downloaded image. But I got error,
Uncaught DOMException: Failed to execute 'btoa' on 'Window': The
string to be encoded contains characters outside of the Latin1 range.
at XMLHttpRequest.downloadCompleted
Then I used below code by following this answer.
let base64 = btoa(unescape(encodeURIComponent(r.responseText)))
The error is gone. But img is still whitespace. How can I resolve it? Thanks in advance...
Update:
I used this link. It throws below error,
Access to XMLHttpRequest at
'https://cdn.dribbble.com/users/93493/screenshots/1445193/notfound.png'
from origin 'null' has been blocked by CORS policy: No
'Access-Control-Allow-Origin' header is present on the requested
resource.
I used this link too, Didn't got any error But I got same blank area instead of image.
btoa receive a string as an argument, but you have a stream. You can use URL.createObjectURL for get a blob url
const url = 'https://images.pexels.com/photos/853199/pexels-photo-853199.jpeg?crop=entropy&cs=srgb&dl=aerial-view-of-seashore-near-large-grey-rocks-853199.jpg&fit=crop&fm=jpg&h=4000&w=6000';
const img = document.querySelector('img');
fetch(url).then(data => data.blob()).then(blob => {
const src = URL.createObjectURL(blob);
img.src = src;
}).catch(err => console.log(err));
<img height="150"/>
For download an image from url:
var a = document.createElement('a');
a.href='https://images.pexels.com/photos/853199/pexels-photo-853199.jpeg?crop=entropy&cs=srgb&dl=aerial-view-of-seashore-near-large-grey-rocks-853199.jpg&fit=crop&fm=jpg&h=4000&w=6000';
a.download='filname.jpg';
document.body.appendChild(a);
a.click();
a.remove()
One long way is to use FileReader that assuming you received the data as blob
so this should work (hopefully) :
xml = new XMLHttpRequest()
xml.open("GET", "YOUR URL", true)
xml.responseType = "blob"
var blob
xml.onload = function(e){blob = xml.response;}
file = new FileReader()
var base64
file.onloadend = function() {base64 = file.result}
file.readAsDataURL(blob)
img = document.getElementById('downloaded-img')
img.src = base64

How to convert live image url into blob in angular? [duplicate]

This question already has answers here:
DOMException when playing audio with blob as source
(2 answers)
How to get the image size (height & width) using JavaScript
(33 answers)
Getting BLOB data from XHR request
(4 answers)
Closed 3 years ago.
Im working in angular 7 and my requirement is i need to get Width, Height and Size (in how much kb or mb) of the image and also im trying to convert it into blob.
I tried with below code but im not getting exact output:
var img_url = "http://snook.ca/files/mootools_83_snookca.png";
var blob = new Blob([img_url]);
let reader = new FileReader;
reader.readAsDataURL(blob); // read file as data url
reader.onload = () => { // when file has loaded
console.log(reader.result)
var img:any = new Image();
img.src = reader.result;
img.onload = () => {
this.uploaded_image_width = img.width; //to get image width
this.uploaded_image_height = img.height; //to get image height
this.uploaded_image_url = reader.result; //to get blob image
console.log(reader.result)
};
}
When im consoling the blob data is coming wrong (console.log(reader.result)) and inside img.onload function is not executing.
I referred this fiddle to achieve this :
http://jsfiddle.net/guest271314/9mg5sf7o/
you can try like this way. i hope it helps you out
var img = new Image();
img.onload = function(){
alert( this.width+' '+ this.height );
};
img.src = "http://lorempixel.com/output/city-q-c-250-250-1.jpg";

Tainted canvases may not be exported error on chrome when i reload the page

I am making paint like web application using canvas, it is working properly on Firefox but when I reload the page on chrome and use .ToDataURL function it gives me an error of Tainted canvases may not be exported
canvas = document.getElementById('can');
ctx = canvas.getContext("2d");
widthOfCanvas = canvas.width;
highOfCanvas = canvas.height;
var image = new Image();
image.src='https://scontent.fkhi9-1.fna.fbcdn.net/v/t1.0-9/53169476_2381573508543072_5059610343865581568_n.png?_nc_cat=102&_nc_ht=scontent.fkhi9-1.fna&oh=bad33f4d78d743ed41c3455dcde6eeae&oe=5CE3CD71';
image.crossOrigin="anonymous";
console.log(image.onload)
image.onload = function(){
ctx.drawImage(image, 0, 0 ,widthOfCanvas,highOfCanvas);
}

Javascript Convert a URL to a base64 Image [duplicate]

This question already has answers here:
canvas.toDataURL() SecurityError
(8 answers)
Closed 6 years ago.
I am trying to convert an image url to a base64 image. I have found this which I am trying to make use of.
I have the following code:
var imgUrl = 'https://www.google.de/images/srpr/logo11w.png';
let base64image = this.getBase64Image(imgUrl);
console.log(base64image);
and
public getBase64Image(imgUrl) {
var img = new Image();
img.src = imgUrl;
var canvas = document.createElement("canvas");
canvas.width = img.width;
canvas.height = img.height;
var ctx = canvas.getContext("2d");
ctx.drawImage(img, 0, 0);
var dataURL = canvas.toDataURL("image/png");
return dataURL.replace(/^data:image\/(png|jpg);base64,/, "");
}
But, it outputs the following:
data:,
I get the following error in the console:
EXCEPTION: Uncaught (in promise): SecurityError: Failed to execute 'toDataURL' on 'HTMLCanvasElement': Tainted canvases may not be exported.
Error: Failed to execute 'toDataURL' on 'HTMLCanvasElement': Tainted canvases may not be exported.
My code must me incoreect. Can anyone please advise how to convert the url to a base64 image?
Thanks
UPDATE
I aded the following line to the function:
img.crossOrigin = "Anonymous";
That got rid of the error, however, now I get the following:
data:,
You can use an XHR and the File Reader API instead, which is cleaner but is limited in browser compatibility.
var imgxhr = new XMLHttpRequest();
imgxhr.open( "GET", url );
imgxhr.responseType = "blob";
imgxhr.onload = function (){
if ( imgxhr.status===200 ){
reader.readAsDataURL(imgxhr.response);
}
else if ( imgxhr.status===404 ){
// Error handle
}
};
var reader = new FileReader();
reader.onloadend = function () {
console.log(reader.result.length);
// Code here
};
imgxhr.send();

Allow Access-Control-Allow-Origin: * in pure javascript

So I've been working on a fun, online image effect program in javascript where the user enters a url to an image and hits 'enter', the image is drawn on the screen, and then the user can run some effects on it, such as g for greyscale, b for blur, etc.
My problem is that the console prints out either:
Redirect at origin [origin] has been blocked from loading by
Cross-Origin Resource Sharing policy: No 'Access-Control-Allow-Origin'
header is present on the requested resource. Origin 'null' is
therefore not allowed access.
or:
Uncaught SecurityError: Failed to execute 'getImageData' on
'CanvasRenderingContext2D': The canvas has been tainted by
cross-origin data.
I looked into many answers to this issue, and I added an extension to my chrome browser that enables cross-origin resource sharing, and my webpage runs fine (after a couple of reloads).
All the solutions I found require either enabling the cross-origin resource sharing option in chrome, or using some sort of php and ajax calls to enable this option. Since I'm writing the code on jsbin, I'm looking specifically for a solution that can be done in pure javascript, and I haven't been able to find any that work. If you have any ideas on something that could work, or the news that there is no possible solution, any response would be appreciated.
My code:
var background, context, image;
var docwidth, docheight;
image = new Image();
image.src = $('#image-src').val();
image.crossOrigin = "anonymous";
docwidth = $(document).outerWidth(true);
docheight = $(document).outerHeight(true);
background = document.getElementById("background");
context = background.getContext("2d");
image.onload = function() {
background.width = docwidth;
background.height = docheight;
context.drawImage(image,0,0,image.width,image.height, 0, 0, docwidth, docheight);
};
function change_image_src(src) {
image.src = $('#image-src').val();
}
// ... more image effect functions ...
function grayscale() {
var data = context.getImageData(0, 0, background.width, background.height);
var pixels = data.data;
for (var x = 0; x < data.width; x++)
for (var y = 0; y < data.height; y++) {
var i = (y * 4) * data.width + x * 4;
var avg = (pixels[i] + pixels[i + 1] + pixels[i + 2]) / 3;
pixels[i] = avg;
pixels[i + 1] = avg;
pixels[i + 2] = avg;
}
context.putImageData(data, 0, 0, 0, 0, data.width, data.height);
}
$(document).keydown(function(e) {
switch (e.which) {
// ... other cases ...
case 71: // g
grayscale();
break;
}
});
Btw, I do have image.crossOrigin = "anonymous";
Thanks in advance!
In order to use images from another origin on a canvas without tainting it, the image must be served with CORS headers. This page on MDN explains it, but essentially, when the image is served, it has to be accompanied by an Access-Control-Allow-Origin header allowing the origin of your page (potentially via the * wildcard).
Unless the image is served that way, putting it in the canvas will taint it, and you won't be able to use getImageData.
So this isn't a JavaScript thing, really; it's how the image is served that determines how you can use it.
I was able to get over this problem using a CORS proxy server: http://crossorigin.me/

Categories

Resources