Saving Canvas Data as an Image

Over the past few months, we have talked quite a bit about HTML5, more specifically canvases. There are plenty of other interesting HTML5 subjects canvases offer, which makes it by far the most fascinating and flexible object. We have covered topics ranging from simple rotations to photo filters. Today we are going to go over how to take your canvas and save it as an image.

Below we have a working demonstration of the concept this tutorial will cover. If you click “Image Tag”, a new image element will be inserted into the contents of this page. The image element will be populated by the contents of the canvas. If you click “New Window”, the contents of the canvas will be displayed as an image in a new browser window or tab. If you click “Download”, the browser will prompt you to download the contents of the canvas as an image file.

Introduction

Getting the pixel data from a canvas is fairly simple, as we learned in the grayscale filter tutorial. Luckily, getting “image ready” data is also extremely easy as well.

Before we get started with some code, it should be noted that you can only get image data, in any form, from sources on the same domain on the canvas. This means that, while you can draw cross-domain images, you cannot get pixel data nor image data from canvases that have cross-domain images drawn on them.

Digging In

Now, the code to get your image data is actually really straight forward. All you have to do is have some fun with a canvas, then get a data string and us it accordingly. So here is what our code looks like:

var can = document.getElementById(‘canvas’);
var ctx = can.getContext(‘2d’);

var imgA = new Image();
imgA.src = ‘vader.jpg’;

imgA.onload = function() {
  ctx.drawImage(imgA, 25, 0, imgA.width, imgA.height);
  ctx.restore();
};

var imgB = new Image();
imgB.src = ‘troopers.jpg’;

imgB.onload = function() {
  ctx.globalAlpha = 0.1
  ctx.drawImage(imgB, 100, 75, imgB.width, imgB.height);
  ctx.restore();
};

function toImage(returnType) {
  var dataURL = document.getElementById(‘canvas’).toDataURL("image/png");

  // The returnType argument specifies how to get the
  // the image.  ‘obj’ will set the source to an image element.
  // ‘window’ will open a new window and display the image.
  // ‘download’ will prompt the user to save the image.
  switch(returnType) {
    case ‘obj’:
      var imgObj = new Image();
      imgObj.src = dataURL;
      document.getElementById(‘graphics’).appendChild(imgObj);
      break;
    case ‘window’:
      window.open(dataURL, "Canvas Image");
      break;
    case ‘download’:
      dataURL = dataURL.replace("image/png", "image/octet-stream");
      document.location.href = dataURL;
      break;
  }
}

In our example, we take two images and layer them, with the on top image mostly transparent, to give us a trendy fade-in look.

So first thing we do is take two images and draw them to a canvas, with one being drawn on top of the other with 50% opacity. However, what you put on your fancy canvas is up to you, the important part is getting that data into an image.

The magic revolves around the call to toDataURL inside our toImage function, which actually returns a string that contains the image data (in URL form) for the canvas. Also notice that this call is on the canvas itself and not the 2d context we use to draw the images.

Once you have this string, you can use it many different ways. You can make an image and set the source to the data, open the data in a new window, or even point the location of the current document to the data which allows you to do a straight-up download of the image. All these methods offer a way to get the canvas data as an image, we have them all inside our function. All three methods have been included so you can see how they are each accomplished. Again, very simple code.

So there you have it. Saving canvas data as an image is quite easy, and you can present that data in any number of ways…as long as you don’t use cross-domain images. This is going to wrap it up for this tutorial, just remember when you need coding help, all you have to do is Switch On The Code.

Leave a Reply

Your email address will not be published. Required fields are marked *