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.
Related
I'm trying to add an image from a different url using a function and im getting an issue with cors saying my request is blocked.
I tried adding a cossOrigin attribute to the image and it still dosnt seem to work
function getDataUri(url, callback) {
var image = new Image();
image.crossOrigin = "Anonymous"
image.onload = function () {
var canvas = document.createElement('canvas');
canvas.width = this.naturalWidth; // or 'width' if you want a special/scaled size
canvas.height = this.naturalHeight; // or 'height' if you want a special/scaled size
canvas.getContext('2d').drawImage(this, 0, 0);
// Get raw image data
// callback(canvas.toDataURL('image/png').replace(/^data:image\/(png|jpg);base64,/, ''));
// ... or get as Data URI
callback(canvas.toDataURL('image/png'));
};
image.src = url;
}
getDataUri(imageurl, function (dataURI) {
})
Access to image at 'imageurl' from origin 'http://localhost:8000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
I always do: image.setAttribute('crossOrigin', '');
I scraping some pages (I know, I know, I shouldn't, but the info from our intranet is not available in any other reliable way). So I inject a small $(...).each(... $.ajax({})); JavaScript and this works fine.
I got most info out of it, but now I need the images. I can get the URL, but I need to store them on the server (or on my local machine first). I can't use the URL because the images are behind username/password authentication.
Can I send them with a $.ajax(multipart/form post - new FormData()) construct?
All idea's welcome.
One idea is to encode them as base64 strings and store them that way. Here's a fiddle demonstrating the method: http://jsfiddle.net/c8n9d4ce/
I also found this fiddle that likewise demonstrates this method.
My code from the fiddle:
var canvas = document.getElementById("myCanvas");
var srcImg = document.getElementById("sourceImage");
var final = document.getElementById("base64Image");
var img = new Image();
img.crossOrigin = 'Anonymous';
img.onload = function(){
canvas.height = this.height;
canvas.width = this.width;
canvas.getContext('2d').drawImage(this,0,0);
var dataURL = canvas.toDataURL();
canvas = null;
final.src = dataURL;
};
img.src = srcImg.src;
img {
max-width: 100%;
}
<h1>Original Image</h1>
<img src="https://i.imgur.com/5YJ3HQ9.jpg" id="sourceImage">
<h1>Canvas Rendered Image</h1>
<canvas id="myCanvas"></canvas>
<h1>Base64 Encoded Image</h1>
<img id="base64Image">
Seems the way to go, I tried, but got this error: "Cross-origin image load denied by Cross-Origin Resource Sharing policy". I tried the snippet on this webpage (just copy/paste into the console).
function getDataURL(srcImg, done) {
var img = new Image();
img.crossOrigin = 'Anonymous';
img.onload = function(){
var canvas = document.createElement('canvas');
canvas.height = this.height;
canvas.width = this.width;
canvas.getContext('2d').drawImage(this,0,0);
done(canvas.toDataURL());
};
img.src = srcImg.src;
}
getDataURL($("img")[0], function(data) {
console.log(data);
});
I've been trying to find a method to save the canvas to file. My image is too large to use dataToUrl, so I have been trying various toblob methods. It seems that when a patterned fill is used, toblob does not work. Would anyone be able to to me if it is possible for this to work or if there is another way to accomplish this? Thanks
jfiddle example
<!DOCTYPE html>
<html>
<canvas id="myCanvas" width="300" height="150" style="border:1px solid #d3d3d3;">Your browser does not support the HTML5 canvas tag.</canvas>
<script src="jquery.min.js"></script>
<script src="canvas-to-blob.js"/></script>
<script src="FileSaver.js-master\FileSaver.js"></script>
<script>
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
ctx.clearRect(0, 0, c.width, c.height);
var img = new Image();
img.src = "http://www.w3schools.com/tags/img_lamp.jpg";
var pat = ctx.createPattern(img, "repeat");
ctx.rect(0, 0, 150, 100);
//Works with color, but not with pattern
ctx.fillStyle = pat;
//ctx.fillStyle = 'blue';
ctx.fill();
try {
var isFileSaverSupported = !! new Blob();
} catch (e) {
alert(e);
}
alert("toBlob");
c.toBlob(function (blob) {
alert("success");
saveAs(blob, "TruVue.png");
});
</script>
</html>
The reason is due to CORS, images from other domains are restricted - you can show them on the canvas but you cannot extract their bitmap.
As toBlob is a bitmap extracting method like toDataURL or getImageData you won't be able to use these images.
There are a couple of work-arounds:
Upload the image to your own server and load it from there (same domain as you use for the page).
Modify the other server to include Access-Control-Allow-Origin headers (in this case it will probably not be do-able).
Use your own server as an image proxy
BTW: You should also use the image's onload event to be sure the image gets proper loaded before using the image:
var img = new Image();
img.onload = drawFunction;
img.src = "http://www.w3schools.com/tags/img_lamp.jpg";
function drawFunction() {
/// draw here
}
I'm getting the following javascript error when I try to get data from a canvas element:
Error: canvas.toDataURL() not supported. [Exception... "The operation is insecure." code: "18" nsresult: "0x80530012 (SecurityError)"...
The canvas is drawn from an image served from a different domain, but I'm using a proxy to add these 2 lines to the image response header:
access-control-allow-origin: *
access-control-allow-credentials: true
What am I missing?
Thanks,
Ted
To make a proper CORS request, you must set the image's cross origin property to "Anonymous". This example is from the Mozilla Developer Network.
var img = new Image,
canvas = document.createElement("canvas"),
ctx = canvas.getContext("2d"),
src = "http://example.com/image"; // insert image url here
img.crossOrigin = "Anonymous";
img.onload = function() {
canvas.width = img.width;
canvas.height = img.height;
ctx.drawImage( img, 0, 0 );
localStorage.setItem( "savedImageData", canvas.toDataURL("image/png") );
}
img.src = src;
// make sure the load event fires for cached images too
if ( img.complete || img.complete === undefined ) {
img.src = "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==";
img.src = src;
}
The browser support excludes any known version of IE, and unreleased versions of Safari. Firefox and Chrome have years of support.
I have the following code :
function createImage(source) {
var pastedImage = new Image();
pastedImage.onload = function() {
document.write('<br><br><br>Image: <img src="'+pastedImage.src+'" height="700" width="700"/>');
}
pastedImage.src = source;
}
Here I am displaying the image through html image tag which I wrote in document.write and provide appropriate height and width to image.
My question is can it possible to displaying image into the canvas instead of html img tag? So that I can drag and crop that image as I want?
But how can I display it in canvas?
Further I want to implement save that image using PHP but for now let me know about previous issue.
Try This
var ctx = document.getElementById('canvas').getContext('2d');
var img = new Image(); // Create new img element
img.onload = function(){
// execute drawImage statements here This is essential as it waits till image is loaded before drawing it.
ctx.drawImage(img , 0, 0);
};
img.src = 'myImage.png'; // Set source path
Make sure the image is hosted in same domain as your site. Read this for Javascript Security Restrictions Same Origin Policy.
E.g. If your site is http://example.com/
then the Image should be hosted on http://example.com/../myImage.png
if you try http://facebook.com/..image/ or something then it will throw security error.
Use
CanvasRenderingContext2D.drawImage.
function createImage(source) {
var ctx = document.getElementById('canvas').getContext('2d');
var pastedImage = new Image();
pastedImage.onload = function(){
ctx.drawImage(pastedImage, 0, 0);
};
pastedImage = source;
}
Also MDN seems to be have nice examples.