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?
Consider using canvas.toBlob()
instead of context.getImageData()
if you want compact data rather than a raw ImageData object.
Example:
const imageIn = document.querySelector('#image-in');
const imageOut = document.querySelector('#image-out');
const canvas = document.querySelector('#canvas');
const imageDataByteLen = document.querySelector('#imagedata-byte-length');
const bufferByteLen = document.querySelector('#arraybuffer-byte-length');
const mimeType = 'image/png';
imageIn.addEventListener('load', () => {
// Draw image to canvas.
canvas.width = imageIn.width;
canvas.height = imageIn.height;
const ctx = canvas.getContext('2d');
ctx.drawImage(imageIn, 0, 0);
// Convert canvas to ImageData.
const imageData = ctx.getImageData(0, 0, imageIn.width, imageIn.height);
imageDataByteLen.textContent = imageData.data.byteLength + ' bytes.';
// Convert canvas to Blob, then Blob to ArrayBuffer.
canvas.toBlob((blob) => {
const reader = new FileReader();
reader.addEventListener('loadend', () => {
const arrayBuffer = reader.result;
bufferByteLen.textContent = arrayBuffer.byteLength + ' bytes.';
// Dispay Blob content in an Image.
const blob = new Blob([arrayBuffer], {type: mimeType});
imageOut.src = URL.createObjectURL(blob);
});
reader.readAsArrayBuffer(blob);
}, mimeType);
});
<h1>Canvas ↔ ArrayBuffer</h1>
<h2>1. Source <code><img></code></h2>
<img id="image-in" src="https://ucarecdn.com/a0338bfa-9f88-4ce7-b53f-e6b61000df89/" crossorigin="">
<h2>2. Canvas</h2>
<canvas id="canvas"></canvas>
<h2>3. ImageData</h2>
<p id="imagedata-byte-length"></p>
<h2>4. ArrayBuffer</h2>
<p id="arraybuffer-byte-length"></p>
<h2>5. Final <code><img></code></h2>
<img id="image-out">
JSFiddle: https://jsfiddle.net/donmccurdy/jugzk15b/
Also note that images must be hosted on a service that provides CORS headers, or you'll see errors like "The canvas has been tainted by cross-origin data."
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With