Qvatra
Qvatra

Reputation: 3857

javascript load image from local hard drive using blob

The following code should be able to save and load .png image to/from local hard drive.

Saving works fine(at least in chrome) but loading produces wrong url and display nothing..

A little help would be really appreciated!

<html>
<head>
    <title></title>
</head>
<body>
    <img id="img" /><br>
    <input type="button" value="Save" onclick="onSave()" /><br />
    <input type="file" onchange="onOpen(event)" /><br />

    <script>

        onSave = function () {
            var canvas = document.createElement("canvas");
            canvas.width = 200;
            canvas.height = 200;

            var ctx = canvas.getContext("2d");
            ctx.fillRect(0, 0, 100, 150);

            var dataURL = canvas.toDataURL("image/png");
            var img64 = dataURL.replace(/^data:image\/(png|jpg);base64,/, "");

            var binaryImg = atob(img64);
            var length = binaryImg.length;
            var ab = new ArrayBuffer(length);
            var ua = new Uint8Array(ab);
            for (var i = 0; i < length; i++) {
                ua[i] = binaryImg.charCodeAt(i);
            }

            var blob = new Blob([ab]);

            var a = document.createElement("a");
            a.download = 'Blob_img';
            a.innerHTML = "Download File";
            a.href = window.webkitURL.createObjectURL(blob);
            a.style.display = 'none';
            document.body.appendChild(a);
            a.click();
        };


        onOpen = function (event) {
            var fileReader = new FileReader();
            fileReader.onload = function (event) {
                var ab = event.target.result;

                var ua = new Uint8Array(ab);

                var binaryImg;
                for (var i = 0; i < ua.length; i++) {
                    binaryImg += String.fromCharCode(ua[i]);
                }
                var img64 = btoa(binaryImg);

                var image = new Image();
                image.src = 'data:image/png;base64,' + img64;

                var img = document.getElementById('img');
                img.src = image.src;
            }
            fileReader.readAsArrayBuffer(event.target.files[0]);
        };

    </script>
</body>
</html>

Upvotes: 2

Views: 5142

Answers (2)

qur2
qur2

Reputation: 480

In case somebody is wondering, there is a simpler way of reading the file:

FileReader.readAsDataURL

Check a working example at https://developer.mozilla.org/en-US/docs/Web/API/FileReader.readAsDataURL.

Upvotes: 1

Pointy
Pointy

Reputation: 413747

Your "load" handler for your FileReader is declared without an event parameter. As a result, it's not going to have access to the file contents.

        fileReader.onload = function (event) {
           var ab = event.target.result;

Without that parameter, the symbol "event" would refer to the parameter of the enclosing function, and that one won't have the file contents.

Also, I think you don't need to do the base64 encoding/decoding via atob and btoa, because the results of converting the canvas contents to a data URL will be a base64 string anyway.

Upvotes: 3

Related Questions