Part of my app includes html5 photo editing using a mixture of standard 2d context canvases and webGL.
Anyway, I am saving \'undo\' states while the user is manipula
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()
widthOfImage * heightOfImage * 4
, for example imageData length of image with dimensions 100 is var imageDataArrayLenth = 100 * 100 * 4 = 40 000 (bytes);
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);
});