Result of html5 Canvas getImageData or toDataURL - Which takes up more memory?

I just went through this the other day... the getImageData method returns an image object where the actual data is stored in a uint8array... you have to get the data converted to something your database can manage and its just not worth it, the final output is much larger than the toDataURL method

Its also very simple to get toDataURL base64 string back onto the canvas... you just instantiate a new image and give the src the base64 string


Good question! I'm not sure about the true sizes of the objects themselves, and it should differ between implementions of JS, but that doesn't mean we can't make some educated guesses.

First we can use the approximation function from this question: JavaScript object size

And make an example: http://jsfiddle.net/g39uz/

The string is perhaps 80116 bytes, compared to the ImageData's 720056 bytes. Or thereabouts.

There's an order of magnitude difference here, and the difference would be even more stark if the image was simple. It's worth remembering that the Base64 representation can be compressed (and it is). Let's take it to the limit for a moment to see, by using a blank canvas:

http://jsfiddle.net/g39uz/2/

On a blank canvas the dataURL string is just 1996 bytes (or thereabouts) but the image data, which of course still dutifully describes every single pixel in painstaking array detail, is still 720056.

In short, if you're storing it, the base64 string probably takes up less space. By an order of magnitude.


getImageData() takes more memory than toDataURL()

  • ImageData is pixel array, the largest information about image, the length of pixel array is widthOfImage * heightOfImage * 4, for example imageData length of image with dimensions 100 is var imageDataArrayLenth = 100 * 100 * 4 = 40 000 (bytes);
  • BLOB (JPG or PNG) is imageData compressed with jpg or png algorithm can be less sized by 10 or 20 times than imageData (depends on image content).
  • DataURL (BASE64) is imageData compressed to JPG or PNG, then converted to string, and this string is larger by 37% (info) than BLOB.

Conclusion: Better way is to use BLOB (info).

//Example of using blob with objectURL
var canvas = document.getElementById("canvas");

canvas.toBlob((blob) => {
  let img = new Image();
  img.onload = () =>  URL.revokeObjectURL(img.src);  // no longer need to read the blob so it's revoked
  img.src = URL.createObjectURL(blob);
  document.body.appendChild(img);
});