2

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>
3
  • After calling toDataURL, you should already have a base64-encoded image. You shouldn't have to encode it with atob again. Commented Jan 9, 2014 at 15:23
  • @Pointy disagree. without this line it raises an error: 'atob' failed: The string to be decoded is not correctly encoded. Commented Jan 9, 2014 at 15:28
  • You should not have to encode or decode - just save the bytes and then rebuild them as your code is doing. However, it shouldn't hurt anything; it's just not necessary. Commented Jan 9, 2014 at 15:30

2 Answers 2

3

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.

Sign up to request clarification or add additional context in comments.

2 Comments

I added event parameter but it doesn't load image so seems it's not the only problem here. Could you provide an example how to use it without atob and btoa?
@Qvatra well the atob/btoa thing might be a problem, but the first thing to do is make sure that you're getting anything at all from the file reader. Have you tried putting in some console.log() calls, or using the debugger and setting breakpoints? Can you tell whether you're getting the image data back properly?
1

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.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.