Home > Front End Development, HTML, Javascript > Working with images and HTML5 Canvas locally

Working with images and HTML5 Canvas locally

September 16th, 2011


A problem that I often run into with while working locally with Canvas is the security error that comes with working with images on my local machine or cross domain. This post will give you a work around that will work if in a bind.

The Error

If you ever come across : Uncaught Error: SECURITY_ERR: DOM Exception 18 , you’re not alone. This error is triggered if you’re trying to get the imageData from an image that lives on your machine, or cross domain….good times. Kind of a pain…of course most errors are ;-)

Here is an example that will make the error trigger.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<img src="test.jpg" alt=""  id="image"/>

<canvas id="stage"></canvas>
<script>
    var canvas = document.getElementById("stage");
    var image = document.getElementById("image");
   
    if (canvas.getContext) {
        var context = canvas.getContext("2d");

        image.onload = function (){
           canvas.width = image.width;
           canvas.height = image.height;
           
           context.drawImage(image,0,0);
           
            //You will get an ERROR -> Uncaught Error: SECURITY_ERR: DOM Exception 18
            var imageData = context.getImageData(0,0,image.width,image.height);
           
            console.log(imageData);
        }
    }
   
</script>

The Solution

I’m sure there are a couple of ways to handle this but the one I came across was to encode the image into base64. This way the image is embedded right into your html page. Preventing the browser from having to go off site to get your image.

Fantastic news right….but how do I use a base64 image? In any img’s src you can put a data source in place of the image’s path. This is what one might look like:

1
<img src="data:image/jpeg;base64,iVBORw0KGgoAAAANSUhEUgAAADIA...really long string" alt="" />

base64 image explination

Here is a handy tool to help you encode your images.

So now to get the earlier code working, we just have to replace the image’s src information with the base64 image data we got from the site.

Here is that in all it’s glory:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<img src="data:image/jpeg;base64,/9j/4AAQSkZJRgABAgAAZABkAAD/7AA..." alt=""  id="image"/>

<canvas id="stage"></canvas>
<script>
    var canvas = document.getElementById("stage");
    var image = document.getElementById("image");
   
    if (canvas.getContext) {
        var context = canvas.getContext("2d");

        image.onload = function (){
           canvas.width = image.width;
           canvas.height = image.height;
           
           context.drawImage(image,0,0);
           
            //This works now because of our image's source is now embedded.
            var imageData = context.getImageData(0,0,image.width,image.height);
           
            console.log(imageData);
        }
    }
   
</script>

Of course once you push it to a server you’d probably want to change this, as it blows up the size of the image by quite a bit. The fix isn’t pretty, but at least you’ll be able to work locally in all your canvas-y goodness.




Top