Three amazing uses for dataURLs

DataURLs have been around for ages. IE 8 can handle them and so can every other browser. But when does it make sense to use them? And when is it in fact the only possible way? Well, surely in these three use cases:

1. Create downloadable files on the client

You’d like to create a word document with the text “Yeah baby” and make the user download it? Here’s how:

document.location.href = 'data:application/msword;charset=UTF-8,' + encodeURIComponent("Yeah baby");

2. Saving a (webcam) video frame or canvas as an image

You’ve created an amazing chart using HTML 5 canvas or successfully hooked your webcam up to a video using getUserMedia()? Here’s how to save them as an image to the server:

Step 1: Convert the video, image or canvas to a dataURL.

This can be done using the following function:

* source can be an image, video or canvas element
function toDataUrl( source )
    var canvas = document.createElement( "canvas" );
    canvas.width = source.videoWidth || source.width;
    canvas.height = source.videoHeight || source.height;
    canvas.getContext( "2d" ).drawImage( source, 0, 0 );
    return canvas.toDataURL();

Step 2: Send it to the server

For example by using an Ajax post request.

Step 3: Save it as a binary file

dataUrl Structure

DataURLs consist of three parts. A mime-type, the encoding and the actual encoded binary-data. Theoretically any encoding with valid URL characters can be used, in practice however you’ll usually end up with base64 encoding. In order to save the data on the server you’ll therefore need to:

a) split the dataURL on the comma ( there will always be exactly one comma ) and base64 decode the data
b) extract the file extension from the mime type
c) write the binary data to a file and save it with the extension

In Node.js for example this would look like this:

function saveDataUrl( fileName, dataUrl )
    var dataString = dataUrl.split( "," )[ 1 ];
    var buffer = new Buffer( dataString, 'base64');
    var extension = dataUrl.match(/\/(.*)\;/)[ 1 ];
    var fs = require( "fs" );
    var fullFileName = fileName + "." + extension;
    fs.writeFileSync( fullFileName, buffer, "binary" );

3. Save bandwidth and speed up your page download.

DataUrls make it easy to embed images in both html

<img src=”data:image/png;base64,iVBOR…” />

and CSS

background-image: url(data:image/png;base64,iVBOR...);.

But they are on average a third bigger than the original binary image. So when does it make sense to use them anyways for performance reasons? In any of these cases:

You need to download a very small image.  Every http requests comes with a number of headers. For very small images like icons these can easily account for more than a third of the total transfer volume.

– You need to download a large number of resources. Browsers usually only allow for a limited number of simultaneous http connections per domain. Since dataURLs don’t need to be downloaded separately they free up connections for other traffic.

– You’d like to distribute your multimedia application as a single file. My photobooth.js widget is a good example for this. CSS, JavaScript and images are all wrapped into a single js file.

4 responses to “Three amazing uses for dataURLs

  1. Is there a way to disable options: hue, saturation and brightness?
    All I need is Crop and Take a Picture.

  2. Pingback: Photobooth.js, enable webcam on your web app | Coders Grid·

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s