Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I save and restore a File object in local storage

I have an HTML5/javscript app which uses

<input type="file" accept="image/*;capture=camera" onchange="gotPhoto(this)"> 

to capture a camera image. Because my app wants to be runnable offline, how do I save the File (https://developer.mozilla.org/en-US/docs/Web/API/File) object in local storage, such that it can be retrieved later for an ajax upload?

I'm grabbing the file object from the using ...

function gotPhoto(element) {       var file = element.files[0];      //I want to save 'file' to local storage here :-( } 

I can Stringify the object and save it, but when I restore it, it is no longer recognised as a File object, and thus can't be used to grab the file content.

I have a feeling it can't be done, but am open to suggestions.

FWIW My workaround is to read the file contents at store time and save the full contents to local storage. This works, but quickly consumes local storage since each file is a 1MB plus photograph.

like image 700
pinoyyid Avatar asked Oct 01 '13 14:10

pinoyyid


People also ask

How do I save a file in local storage?

Syntax to save data to localStorage:localStorage. setItem(key, value) Ex: localStorage. setItem("firstName", "Mark Zuker berg");

How do I save an image in local storage?

To save an image to localStorage and display it on the next page with JavaScript, we can create a canvas, put the image in it, and then convert the canvas data to a base64 string. const getBase64Image = (img) => { const canvas = document. createElement("canvas"); canvas.


2 Answers

You cannot serialize file API object.

Not that it helps with the specific problem, but ... Although I haven't used this, if you look here it seems that there are ways (althought not supported yet by most browsers) to store the offline image data to some files so as to restore them afterwards when the user is online (and not to use localstorage)

like image 183
George Mavritsakis Avatar answered Sep 27 '22 19:09

George Mavritsakis


Here is a workaround that I got working with the code below. I'm aware with your edit you talked about localStorage but I wanted to share how I actually implemented that workaround. I like to put the functions on body so that even if the class is added afterwards via AJAX the "change" command will still trigger the event.

See my example here: http://jsfiddle.net/x11joex11/9g8NN/

If you run the JSFiddle example twice you will see it remembers the image.

My approach does use jQuery. This approach also demonstrates the image is actually there to prove it worked.

HTML:

<input class="classhere" type="file" name="logo" id="logo" /> <div class="imagearea"></div> 

JS:

$(document).ready(function(){   //You might want to do if check to see if localstorage set for theImage here   var img = new Image();                   img.src = localStorage.theImage;    $('.imagearea').html(img);    $("body").on("change",".classhere",function(){       //Equivalent of getElementById       var fileInput = $(this)[0];//returns a HTML DOM object by putting the [0] since it's really an associative array.       var file = fileInput.files[0]; //there is only '1' file since they are not multiple type.        var reader = new FileReader();       reader.onload = function(e) {            // Create a new image.            var img = new Image();             img.src = reader.result;            localStorage.theImage = reader.result; //stores the image to localStorage            $(".imagearea").html(img);        }         reader.readAsDataURL(file);//attempts to read the file in question.     }); }); 

This approach uses the HTML5 File System API's to read the image and put it into a new javascript img object. The key here is readAsDataURL. If you use chrome inspector you will notice the images are stored in base64 encoding.

The reader is Asynchronous, this is why it uses the callback function onload. So make sure any important code that requires the image is inside the onLoad or else you may get unexpected results.

like image 38
Joseph Astrahan Avatar answered Sep 27 '22 17:09

Joseph Astrahan