Saving an uploaded image to localStorage (chrome extension)

I'm having trouble finding how exactly I would store an uploaded image in localStorage, as inputted by a user in my options page. There isnt too much documentation on how to do it because for awhile it was a known error and I couldnt find any examples on Stack. There's some examples on how to save an image already on a page but nothing on an inputed image.

All i have is the HTML, but I imagine that the javascript running in the back needs to access the value of the input or something (?).

<input id="uploadImage" type="file" accept="image/*" />

Then after the user chooses a file, the value of the input is C:\fakepath\some_image.jpg. I dont want to store the filepath but store the actual image, if possible.

$("#uploadImage").change(function(){
    alert($("#uploadImage").val());
});

EDIT:

I found a sample on how to do it from this stack topic, but the filepath that I get from $("#uploadImage").val() doesnt work (So I dont know if this method work work even if the filepath was valid)

var img = new Image();
img.src = $("#uploadImage").val();
img.load = function() {
    var canvas = document.createElement('canvas');
    document.body.appendChild(canvas);
    var context = canvas.getContext('2d');
    context.drawImage(img, 0, 0);
    var data = context.getImageData(x, y, img.width, img.height).data;
    localStorage['uploadedImage'] = data; // save image data
};

Answers


This requires the FileReader API, and is just a modified version of this answer (ref: Loading an image to a <img> from <input file>):

    var input = document.getElementById('uploadImage');
    input.onchange = function(evt){
        var tgt = evt.target || window.event.srcElement, 
            files = tgt.files;

        if (FileReader && files && files.length) {
            var fr = new FileReader();
            fr.onload = function () {
                localStorage['foo'] = fr.result;
            }
            fr.readAsDataURL(files[0]);
        }
    }

You could then apply it as a background image by doing something like:

var el = document.querySelector('body');
el.style.backgroundImage = 'url(' + localStorage['foo'] + ')';

Well, this is how you can do it:

  1. First of all read the file using FileAPI. A good example could be found here
  2. After you have a file content you have another problem: how to store it. LocalStorage accepts only strings, so you would need to convert your binary image file to Base64, e.g. like they do here
  3. And finally you can render your image later using data-URI

As you may see, this isn't that easy, but still if you follow the instructions you can do it.


You can't open file:// URLs from http:// or https:// URLs, as this breaches security (see this question), however, if you are just running your HTML page from a file:// URL it should work with your code.

You do need to make sure the canvas element is the same dimensions as the image though, and also it's best practice to specify the src attribute after the onload callback function just in case it loads too fast for the onload callback binding to be in place.

You should also make sure you are using the correct localStorage API to store and retrieve items from localStorage.

canvas.toDataURL() is also a neater way of getting the Base64 string for the image data.

Here's some updated code.

var img = new Image();
img.onload = function() {
    var canvas = document.createElement('canvas');
    canvas.width = this.width;
    canvas.height = this.height;
    document.body.appendChild(canvas);

    var context = canvas.getContext('2d');
    context.drawImage(img, 0, 0);

    var data = canvas.toDataURL();
    localStorage.setItem('uploadedImage', data); // save image data
};
img.src = 'file://' + $("#uploadImage").val();

Then to get the item and use it as an image on your page, you could use:

var $img = $('<img />', { src: localStorage.getItem('uploadedImage') });
$('body').append($img);

Need Your Help