Tuesday, September 17, 2019

Save and Load Binary Files in HTML5

In this example, we firstly draw something (shapes & lines) on the canvas, convert it into a bitmap (pixel data) and save the pixel values as a binary file.

//Draw something
ctx.fillStyle = "red";
ctx.fillRect(0, 0, 60, 60);
ctx.beginPath();
ctx.rect(60, 60, 160, 80);
ctx.fillStyle = "blue";
ctx.fill();
ctx.beginPath();
ctx.lineWidth = "5";
ctx.strokeStyle = "green";
ctx.moveTo(6, 160);
ctx.lineTo(240, 360);
ctx.lineTo(60, 800);
ctx.lineTo(800, 60);
ctx.stroke();//draw
//Convert canvas draws into pixels
var buffer = ctx.getImageData(0, 0, w, h);

//https://stackoverflow.com/questions/23451726/saving-binary-data-as-file-using-javascript-from-a-browser
var saveByteArray = (function () {
    var a = document.createElement("a");
    document.body.appendChild(a);
    a.style = "display: none";
    return function (data, name) {
        var blob = new Blob(data, {type: "octet/stream"}),
            url = window.URL.createObjectURL(blob);
        a.href = url;
        a.download = name;
        a.click();
        window.URL.revokeObjectURL(url);
    };
}());
//Save pixel data (ArrayBuffer) as binary file
saveByteArray([buffer.data], 'example.bf');

Then we load the binary file and display the pixel values it stores (as a bitmap) using a new canvas.
//The requestAnimFrame fallback for better and smoother animation
var buffer = ctx.createImageData(w, h);

//http://qnimate.com/an-introduction-to-javascript-blobs-and-file-interface/
var xhr = new XMLHttpRequest(); 
xhr.open("GET", "./example.bf"); 
//although we can get the remote data directly into an arraybuffer using the string "arraybuffer" assigned to responseType property. For the sake of example we are putting it into a blob and then copying the blob data into an arraybuffer.
xhr.responseType = "blob";

function analyze_data(blob)
{
    var myReader = new FileReader();
    myReader.readAsArrayBuffer(blob);
    
    myReader.addEventListener("loadend", function(e)
    {
        var buf = e.srcElement.result;//arraybuffer object
        var buf8 = new Uint8ClampedArray(buf);//first view for copy pixel data to ImageData
        var data = new Uint32Array(buf);//second view for setting pixel values
        buffer.data.set(buf8);
        //we use putImageData() to copy the image data back to the canvas.
        ctx.putImageData(buffer, 0, 0);
    });
}

xhr.onload = function() 
{
    analyze_data(xhr.response);
}
xhr.send();

Demo & Full Source Code: Create & Save, Load & Show

Sponsors