Come salvare un'immagine in localStorage e visualizzarla nella pagina successiva?


154

Quindi, fondamentalmente, devo caricare una singola immagine, salvarla in localStorage, quindi visualizzarla nella pagina successiva.

Attualmente, ho il mio caricamento di file HTML:

<input type='file' id="uploadBannerImage" onchange="readURL(this);" />

Che utilizza questa funzione per visualizzare l'immagine sulla pagina

function readURL(input) 
{
    document.getElementById("bannerImg").style.display = "block";

    if (input.files && input.files[0]) {
        var reader = new FileReader();

        reader.onload = function (e) {
            document.getElementById('bannerImg').src =  e.target.result;
        }

        reader.readAsDataURL(input.files[0]);
    }
}

L'immagine viene visualizzata istantaneamente sulla pagina che l'utente può vedere. Viene quindi chiesto di compilare il resto del modulo. Questa parte funziona perfettamente.

Una volta completato il modulo, premono un pulsante 'Salva'. Una volta premuto questo pulsante, salvo tutti gli input del modulo come localStoragestringhe. Ho bisogno di un modo per salvare anche l'immagine come localStorageelemento.

Il pulsante Salva li indirizzerà anche a una nuova pagina. Questa nuova pagina mostrerà i dati degli utenti in una tabella, con l'immagine in alto.

Così semplice e chiaro, ho bisogno di salvare l'immagine localStorageuna volta premuto il pulsante 'Salva', e quindi prendere in prestito l'immagine nella pagina successiva da localStorage.

Ho trovato alcune soluzioni come questo violino e questo articolo su moz: // a HACKS .

Anche se sono ancora estremamente confuso su come funziona, e ho davvero bisogno solo di una soluzione semplice. Fondamentalmente, ho solo bisogno di trovare l'immagine tramite getElementByIDuna volta premuto il pulsante 'Salva', quindi elaborare e salvare l'immagine.


2
Cosa c'è di sbagliato nella memorizzazione di reader.result nell'archivio locale come questo esempio: jsfiddle.net/x11joex11/9g8NN ?
Traccia il

Per le persone che desiderano archiviare grandi quantità di dati su localStorage questa libreria è piuttosto carina: pieroxy / lz-string: algoritmo di compressione basato su LZ per JavaScript
brasofilo

"Ho davvero solo bisogno di una soluzione semplice." Non tutti?
Rodrigo,

Risposte:


213

A chiunque abbia bisogno anche di questo problema risolto:

Innanzitutto, afferro la mia immagine getElementByIDe la salvo come Base64. Quindi salvo la stringa Base64 come localStoragevalore.

bannerImage = document.getElementById('bannerImg');
imgData = getBase64Image(bannerImage);
localStorage.setItem("imgData", imgData);

Ecco la funzione che converte l'immagine in una stringa Base64:

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,/, "");
}

Quindi, nella mia prossima pagina ho creato un'immagine con uno spazio vuoto in questo srcmodo:

<img src="" id="tableBanner" />

E subito quando la pagina viene caricata, utilizzo queste tre righe successive per ottenere la stringa Base64 localStoragee la applico all'immagine con lo spazio vuoto che srcho creato:

var dataImage = localStorage.getItem('imgData');
bannerImg = document.getElementById('tableBanner');
bannerImg.src = "data:image/png;base64," + dataImage;

L'ho testato in diversi browser e versioni e sembra funzionare abbastanza bene.


1
Gif non è supportato, perché gif non è supportato da canvas.
Allen

16
Non è necessaria la funzione getBase64Image. Gli URL dei dati sono già in base 64, quindi quando chiami reader.readAsDataURL l'e.target.result inviato al gestore reader.onload sarà tutto ciò di cui hai bisogno.
James H. Kelly,

3
Tenere presente che esiste un limite di circa 5 MB per l'archiviazione locale / sessione. E la conversione di un'immagine binaria in una stringa codificata in base 64 la ingrandirà di circa il 30%. Quindi questo non funzionerebbe con immagini ad alta risoluzione.
Noel Abrahams,

Perché rimuovi la parte iniziale dell'URL dei dati? Per ridurre le dimensioni?
Deostroll,

3
Nota che devi prima caricare completamente l'immagine (altrimenti finisci per avere immagini vuote), quindi in alcuni casi dovrai avvolgere la gestione in: bannerImage.addEventListener ("load", function () {});
Sì,

9

Ho scritto una piccola libreria da 2,2kb di salvataggio dell'immagine in localStorage JQueryImageCaching Usage:

<img data-src="path/to/image">
<script>
    $('img').imageCaching();
</script>

2
2.2 I Kilobyte sono enormi per qualcosa del genere, inoltre suppongo che non influisca nemmeno sulle dimensioni di jQuery stesso. Suggerirei di scriverlo senza jQuery, forse sarà più piccolo
ChrisBrownie55,

1.74 KB secondo gitbub
hakiko

6

È possibile serializzare l'immagine in un URI dati. C'è un tutorial in questo post del blog . Ciò produrrà una stringa che è possibile memorizzare nella memoria locale. Quindi, nella pagina successiva, utilizzare i dati uri come fonte dell'immagine.


0

"Nota che devi prima caricare completamente l'immagine (altrimenti finisci per avere immagini vuote), quindi in alcuni casi dovrai avvolgere la gestione in: bannerImage.addEventListener (" load ", function () {}); - yuga, 1 novembre 17 alle 13:04 "

Questo è estremamente IMPORTANTE. Una delle opzioni che sto esplorando questo pomeriggio sta usando i metodi di callback javascript piuttosto che addEventListeners poiché anche questo non sembra vincolare correttamente. Preparare tutti gli elementi prima del caricamento della pagina SENZA un aggiornamento della pagina è fondamentale.

Se qualcuno può espandersi su questo, per favore fai - come in, hai usato un settimeout, un'attesa, un callback o un metodo addEventListener per ottenere il risultato desiderato. Quale e perché?


usa sempre un callback se puoi, e non usare mai un settimeout se puoi evitarlo. In base alla progettazione, si desidera che ciò accada dopo quello precedente, con il minor sovraccarico possibile. Questo è esattamente ciò per cui sono progettati i callback
Grayson

-2

Ho riscontrato lo stesso problema, invece di archiviare immagini, che alla fine traboccano la memoria locale, puoi semplicemente memorizzare il percorso dell'immagine. qualcosa di simile a:

let imagen = ev.target.getAttribute('src');
arrayImagenes.push(imagen);
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.