Search code examples
javascripthtmlserializationhtml5-canvasarraybuffer

Serialize canvas content to ArrayBuffer and deserialize again


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?


Solution

  • 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).