Guarde una imagen de archivo en el HTML de localstorage

Intento guardar una imagen en la tienda local y recuperarla cuando sea necesario, estoy confundido sobre cómo guardar una imagen, ya que he remitido una pregunta relacionada con mi misma pregunta, pero son complicadas. Finalmente obtuve algo que parece perfecto para pero estoy confundido sobre cómo usar el código para guardar la imagen en el almacenamiento local
Escuchar es el código en JSFIDDEL

Html:

  

JS:

 bannerImage = document.getElementById('bannerImg'); imgData = getBase64Image(bannerImage); localStorage.setItem("imgData", imgData); function getBase64Image(img) { var canvas = document.createElement("canvas"); canvas.width = img.width; canvas.height = img.height; var ctx = canvas.getContext("2d"); ctx.drawImage(img, 0, 0); var dataURL = canvas.toDataURL("image/png"); return dataURL.replace(/^data:image\/(png|jpg);base64,/, ""); } function fetchimage () { var dataImage = localStorage.getItem('imgData'); var bannerImg = document.getElementById('tableBanner'); bannerImg.src = "data:image/png;base64," + dataImage; } 

Simplemente le falta un FileReader para leer el archivo de entrada en dataURL. Jsfiddle

Html:

    

javascript:

 // Get all variables var bannerImage = document.getElementById('bannerImg'); var result = document.getElementById('res'); var img = document.getElementById('tableBanner'); // Add a change listener to the file input to inspect the uploaded file. bannerImage.addEventListener('change', function() { var file = this.files[0]; // Basic type checking. if (file.type.indexOf('image') < 0) { res.innerHTML = 'invalid type'; return; } // Create a file reader var fReader = new FileReader(); // Add complete behavior fReader.onload = function() { // Show the uploaded image to banner. img.src = fReader.result; // Save it when data complete. // Use your function will ensure the format is png. localStorage.setItem("imgData", getBase64Image(img)); // You can just use as its already a string. // localStorage.setItem("imgData", fReader.result); }; // Read the file to DataURL format. fReader.readAsDataURL(file); }); function getBase64Image(img) { var canvas = document.createElement("canvas"); canvas.width = img.width; canvas.height = img.height; var ctx = canvas.getContext("2d"); ctx.drawImage(img, 0, 0); var dataURL = canvas.toDataURL("image/png"); return dataURL.replace(/^data:image\/(png|jpg);base64,/, ""); } function fetchimage () { var dataImage = localStorage.getItem('imgData'); img.src = "data:image/png;base64," + dataImage; // If you don't process the url with getBase64Image, you can just use // img.src = dataImage; } // Call fetch to get image from localStorage. // So each time you reload the page, the image in localstorage will be // put on tableBanner fetchimage(); 

No es que jsfiddle ejecute este script onload , por lo que puede envolverlos en window.onload en su propio sitio.

Debido a la cuota de almacenamiento limitada que tiene con localStorage, es posible que deba verificar el tamaño de la imagen cargada.

Aquí hay una forma, basada en la respuesta de @fuyushimoya, si no necesita convertir todo tipo de imagen a png. De lo contrario, estás medio jodido porque es uno de los tipos de imagen más pesados.

Esta solución puede no ser la mejor, pero parece manejar algunos casos:

JS

 // Get all variables var bannerImage = document.getElementById('bannerImg'); var result = document.getElementById('res'); var img = document.getElementById('tableBanner'); bannerImage.addEventListener('change', function() { var file = this.files[0]; // declare a maxSize (3Mb) var maxSize = 3000000; if (file.type.indexOf('image') < 0) { res.innerHTML = 'invalid type'; return; } var fReader = new FileReader(); fReader.onload = function() { img.onload = function() { // if localStorage fails, it should throw an exception try { // pass the ratio of the file size/maxSize to your toB64 func in case we're already out of scope localStorage.setItem("imgData", getBase64Image(img, (file.size / maxSize), file.type)); } catch (e) { var msg = e.message.toLowerCase(); // We exceeded the localStorage quota if (msg.indexOf('storage') > -1 || msg.indexOf('quota') > -1) { // we're dealing with a jpeg image : try to reduce the quality if (file.type.match(/jpe?g/)) { console.log('reducing jpeg quality'); localStorage.setItem("imgData", getBase64Image(img, (file.size / maxSize), file.type, 0.7)); } // we're dealing with a png image : try to reduce the size else { console.log('reducing png size'); // maxSize is a total approximation I got from some tests with a random pixel generated img var maxPxSize = 750000, imgSize = (img.width * img.height); localStorage.setItem("imgData", getBase64Image(img, (imgSize / maxPxSize), file.type)); } } } } img.src = fReader.result; }; fReader.readAsDataURL(file); }); function getBase64Image(img, sizeRatio, type, quality) { // if we've got an svg, don't convert it, svg will certainly be lighter than any pixel image if (type.indexOf('svg+xml') > 0) return img.src; // if we've got a jpeg if (type.match(/jpe?g/)) { // and the sizeRatio is okay, don't convert it if (sizeRatio <= 1) return img.src; } // if we've got some other image type else type = 'image/png'; if (!quality) quality = 1; var canvas = document.createElement("canvas"); // if our image file is too large, then reduce its size canvas.width = (sizeRatio > 1) ? (img.width / sizeRatio) : img.width; canvas.height = (sizeRatio > 1) ? (img.height / sizeRatio) : img.height; var ctx = canvas.getContext("2d"); ctx.drawImage(img, 0, 0, canvas.width, canvas.height); // if we already tried to reduce its size but it's still failing, then reduce the jpeg quality var dataURL = canvas.toDataURL(type, quality); return dataURL; } function fetchimage() { var dataImage = localStorage.getItem('imgData'); img.src = dataImage; } // Call fetch to get image from localStorage. fetchimage(); 

HTML

   

▶ ︎ Fiddle

Usa esta directiva:

 directives.directive('baseSixtyFourInput', ['$window', function($window) { return { restrict: 'A', require: 'ngModel', link: function(scope, elem, attrs, ngModel) { var fileObject = {}; scope.readerOnload = function(e) { var base64 = _arrayBufferToBase64(e.target.result); fileObject.base64 = base64; scope.$apply(function() { ngModel.$setViewValue(angular.copy(fileObject)); }); }; var reader = new FileReader(); reader.onload = scope.readerOnload; elem.on('change', function() { var file = elem[0].files[0]; fileObject.filetype = file.type; fileObject.filename = file.name; fileObject.filesize = file.size; reader.readAsArrayBuffer(file); }); //http://stackoverflow.com/questions/9267899/arraybuffer-to-base64-encoded-string function _arrayBufferToBase64(buffer) { var binary = ''; var bytes = new Uint8Array(buffer); var len = bytes.byteLength; for (var i = 0; i < len; i++) { binary += String.fromCharCode(bytes[i]); } return $window.btoa(binary); } } }; 

}]);