Serialize canvas content to ArrayBuffer and deserialize again

vtortola picture vtortola · Mar 6, 2014 · Viewed 16.2k times · Source

I have two canvases, and I want to pass the content of canvas1, serialize it to an ArrayBuffer, and then load it in canvas2. In the future I will send the canvas1 content to the server, process it, and return it to canvas2, but right now I just want to serialize and deserialize it.

I found this way of getting the canvas info in bytes:

var img1 = context.getImageData(0, 0, 400, 320);
var binary = new Uint8Array(img1.data.length);
for (var i = 0; i < img1.data.length; i++) {
    binary[i] = img1.data[i];
}

And also found this way of set the information to a Image object:

var blob = new Blob( [binary], { type: "image/png" } );
var urlCreator = window.URL || window.webkitURL;
var imageUrl = urlCreator.createObjectURL( blob );
var img = new Image();
img.src = imageUrl;

But unfortunately it doesn't seem to work.

Which would be the right way of doing this?

Answer

user1693593 picture user1693593 · Mar 6, 2014

The ImageData you get from getImageData() is already using an ArrayBuffer (used by the Uint8ClampedArray view). Just grab it and send it:

var imageData = context.getImageData(x, y, w, h);
var buffer = imageData.data.buffer;  // ArrayBuffer

To set it again:

var imageData = context.createImageData(w, h);
imageData.data.set(incomingBuffer);

You probably want to consider some form of byte encoding though (such as f.ex base-64) as any byte value above 127 (ASCII) is subject to character encoding used on a system. Or make sure all steps on the trip uses the same (f.ex. UTF8).