sneci
sneci

Reputation: 31

Javascript FileReader eats up all the memory when reads local images

I'm working on a concent to show the thumbnail of a large number of images from the local drive.

With HTML5 File API is seems quite possible, but whn I try to load a big number of images the memory usage of the browser goes over the roof and the collapses.

I think the problem is that the FileReader doesn't releases the memory after a file read.

Originally I had a new instance of FileReader and a simple loop to iterate through the images.

To solve this memory problem I replaced this to have one FileReader only, but it did not really help.

Here is the relevand code block:

<script>

var areader = new FileReader();
var counter=0;

function loadImage(file) {
    var canvas = document.createElement("canvas");
    areader.onload = function (event) {
        var img = new Image;

        img.onload = function () {
            canvas.width = img.width / 100;
            canvas.height = img.height / 100;
            var ctx = canvas.getContext("2d");
            ctx.drawImage(img, 0, 0, img.width / 100, img.height / 100);
            var browse = document.getElementById("uploadInput");
            if (browse.files.length > counter) {
                counter++;
                areader.result = null;//I don't think this makes any difference
                loadImage(browse.files[counter]);
            }
        };

        img.src = event.target.result;
    };
    areader.readAsDataURL(file);
    preview.appendChild(canvas);
}

function showImages() {
    loadImage(document.getElementById("uploadInput").files[0]);

}

If anybody come across this problem the I do something very stupid could you reply.

Thanks,

Tamas

Upvotes: 3

Views: 5577

Answers (1)

Esailija
Esailija

Reputation: 140230

It's not the file reader but you are using the entire image's data in base64 as the src property of the image, which will actually take 133% of the image's size in memory.

You should use Blob URLs instead:

var URL = window.URL || window.webkitURL;

function loadImage( file ) {
    var canvas = document.createElement("canvas"),
        img = new Image();

    img.onload = function() {
        canvas.width = img.width / 100;
        canvas.height = img.height / 100;
        var ctx = canvas.getContext("2d");
        ctx.drawImage(img, 0, 0, img.width / 100, img.height / 100);
        URL.revokeObjectURL( img.src );
        img = null;

        var browse = document.getElementById("uploadInput");
            if (browse.files.length > counter) {
            counter++;
            loadImage(browse.files[counter]);
        }
    };
    img.src = URL.createObjectURL( file );

    preview.appendChild(canvas);
}

Upvotes: 10

Related Questions