IE cross domain getImageData hack
Theres always one! Mat Groves makes IE play nice with getImageData
There’s always one eh! Fun fact — did you know that Internet Explorer won’t let you EVER use getImageData on a canvas context that has an image from a different domain? Never… Even setting up CORS won’t do the trick. Sure it will let you draw the image to canvas once you have set it up, but it will NEVER let you use getImageData.
We recently launched a project that involved using a lot of pixel level manipulations basically where getImageData was crucial. How else are we going to make the world look beautiful if we can’t get to those juicy pixels?
If everything is being hosted on the same domain then this is not a problem as images loaded from the same domain can have there pixel data accessed and all is well. Unfortunately for us (and a lot of setups) our image content is stored on a different server to keep things nice and fast. This means that images are being loaded from one server to be manipulated by code running from another.
So the gauntlet was then thrown down. How to get an image into our site from a different server and access the pixel data so that our site works in Internet Explorer?
Well the good news is we have access to both servers so that’s a plus! After much head banging I figured out a plan of attack and what follows is one of my proudest ever hacks :)
Heres the theory:
- Load up a small iframe into the site. This iframe comes from the domain where the images are being stored meaning it can load images and also access the pixel data of said images.
- Using postMessage we ask the iframe to load in the image that we would like to use.
- Once the image is loaded (in the iframe) we then create a canvas and draw the image to it.
- We then use the canvas.toDataURL function to get a base64 encoded String. (That’s right! a STRING!)
- Theres is no size limit of how big a postMessage string can be. So now we have a long string we simply post Message it to the main site.
- The main site then gets the string data and then sets an image src to be the string.
- BAM! What we now have is an image that will have zero security issues. Meaning we can use getImageData in ie. Job done!
And guess what? This works like a champ. Happy days all around :)
I even made a little class called ImageProxy that does all the above for you over on github so you can just use it if ya fancy.
This method means that you don’t even need CORS at all to use images from another domain. I wouldn’t recommend using this technique unless it’s critical that you need access to getImageData in IE and your images are on another server though!
This example shows an image being loaded in from another domain (in this case matgroves.com) once loaded in the pixel data is accessed and the color channels are swapped to prove it works.