I'm trying to convert an the contents of an HTML5 canvas to a png image.
Problem is that the canvas contains an image that isn't hosted locally so I get the security error.
I don't have the option to host the image locally, is there any other way to capture what is inside the canvas element?
Thanks!
Unless you can make your image resource CORS friendly, then no.
https://developer.mozilla.org/en-US/docs/CORS_Enabled_Image#What_is_a_.22tainted.22_canvas.3F
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.
Edit: Of course, if you aren't limited to pure HTML5 methods, there are some Flash/Crossdomain.xml tricks you could use, but that still assumes you have some control over the server which serves the images.
If you're not opposed to using jQuery this plugin my do the trick.
http://www.maxnov.com/getimagedata/
Guess there is no way around that on the client-side otherwise what would be the point of blocking toDataURL anyway right?
Maybe you could have a server side script forwarding external images to the client so the browser won't know it's from another domain. (Not that it need to anyway since you can't use the browser's credentials from the server side)
Just send the image url as a get parameter, have the content-type header modified according to the image file, of course, and just spread all those bytes on the response content.
Related
I have a cropping utility, built with AngularJs, part of the utility is that it can crop any image in the browser using the canvas.toDataURL method, the problem is that it's not possible to call this method on and image that is not from the same origin, doing so will cause a SecurityError breaking up the rest of the code. So my question is:
Is there a way to validate if an image complies with the same origin policy before trying the toDataURL method?
I've been searching about this but all answers I find relate to making changes to the request in the server so that all images show up as same origin, but I want to distribute this code so I have no way of making sure the user will always use a same origin image, so I want to automatically disable the canvas cropping for images that don't comply with this.
I am building a web app which reads an image through the FileReader API, and then displays it on a Canvas. After that, I re-color the image by going pixel-by-pixel after making the .getImageData call on the canvas, as shown below:
// Color Image on Canvas
ctx = document.getElementById('my_canvas').getContext('2d');
var img_px = ctx.getImageData(0,0,canv_w,canv_h);
img_px = colorImage(img_px,red,green,blue);
ctx.putImageData(img_px,0,0);
colorImage() is a function I've written that changes the pixel values given a corresponding RGB color code, and it definitely does work. The above snippet of code does work when I am loading an image locally, but it does not when I try to access an image from an online server, like a public Dropbox account. Firefox is telling me it's a security issue; is there a way to get around it?
I believe that this is a Cross Origin Resource Sharing CORS (security) issue.
See HTML5 Canvas getImageData and Same Origin Policy
The gist is, requests to images from external domains could inherently supply the user's authentication cookies, etc, allowing your javascript to access their potentially protected images and assets. While you can reference them, via <img>, CORS was established as a security protocol to prevent you from programmatically reading (and perhaps storing) the pixel data.
The Dropbox API supports CORS as of mid August, 2012. You may be able to accomplish what you want using their API once users properly authenticate.
https://github.com/dropbox/dropbox-js/blob/master/doc/getting_started.md
I'm working on an image mashup web app.
I want to avoid flash or other client hassles and just do it pure HTML+javascript.
To keep it light, I'd like to do the work on the client side in Javascript, and have it just push a final saved image to the server.
I thought after reading about the wonders of HTML5 and Canvas I'd be able to use that.
Trouble is though:
If I use the new drag and drop feature of HTML5 for the user to pass a local image to the app and then paint it to the canvas, then ... the canvas get's dirty and it throws a security exception if I try to save the image data.
If I use an API like Bing Image search to find images for the user and paint them to the canvas, then ... the canvas gets dirty and it throws a security exception if I try to save the image data.
The only work around I can think is to have the server act as a kind of proxy and have it relay every image that is worked with to the client - but that defeats the purpose of going client side.
Is there any other method I'm not thinking of, or is pure HTML5 + JS at the client side just not an option for this use case?
The security exception is thrown because you are using images from different domain (local or Bing in your case), you should give to the user the ability to upload the selected images on your server and then work with them in canvas. For images from internet storages you can make something like a proxy to show them on the frontend, images from user's pc should always be uploaded. There is no other way to avoid XSS exceptions as far as I know.
P.S. there is a good article about HTML5 canvas image restrictions here: http://simonsarris.com/blog/480-understanding-the-html5-canvas-image-security-rules
I recently started building a bookmarklet that displays the EXIF data of any image on a website. I chose to use Nihilogic's binary.js and exif.js libraries. For images hosted on the same domain as the parent page, the script works wonderfully. But because it uses XHR to read the binary data of images, and because XHR is restricted to same-origin requests, I can't access the binary data of any cross-site-hosted images.
Is there a way to load the binary data of an image locally (or at least without using XHR) that preserves EXIF data?
I've explored a few other directions, but I fear I don't understand them well enough to determine if there's a solution:
JSONP - I'm assuming there's no way to get binary data into one of these things.
canvas tags - these seem to produce very different base64 encodings than what PHP does, and I suspect that the EXIF data no longer exists in the new encoding.
Javascript is allowed to do special operations (like on the canvas) with same-origin images and cors-enabled images because the browser can safely assume that those would be OK to upload to the server in the first place. But then it gets complicated...
I can't access the binary data of any cross-site-hosted images.
Yes, generally it is very important that you can't. More to the point, you can't do what you want with a bookmarklet.
You can't do this with a canvas because the cors rules here are strict (for good reasons!)
In short the reasoning in general is pretty much exactly the same. Browsers are in a unique security position: A random page on the internet can show you things that are private to you, such as the hypothetical image, C:\MyPhotos\privateImage1.jpg, assuming it could guess that file path.
But that webpage is most certainly not allowed to do anything with that file other than show it to you. It can't read the binary information (EXIF information or pixel information). JavaScript is not allowed to know what that image looks like or nearly any data associated with it.
If it was able to figure that out, a random webpage would be able to try a bunch of file paths and maybe come across an image on your hard drive, and then upload the binary data of that image to a server, in effect stealing your private image.
A browser extension would be far more suited to this task than a (JavaScript) bookmarklet because of this.
Purely from the client? I doubt it. How about XHR'ing a local PHP script that runs something like exif_imagetype()? This function works on remote as well as images.
I'm wondering if it's possible to get the blob data (like base64 encoded or something) of an image that's already loaded, via javascript?
The use case would be that I get a captcha image from a webpage into an android app.
You may be able to use getImageData from the Canvas API. See https://developer.mozilla.org/En/HTML/Canvas/Pixel_manipulation_with_canvas for example. So you can create a canvas, render the image onto it, and then use getImageData on the canvas to get the pixels.
One obstacle to this, though, is the same origin policy. If the image that you're parsing comes from the same domain as your JavaScript, I think you're fine, but if the image comes from an external source, getImageData is going to fail due to the same origin policy.