Wie speichere ich ein Bild in localStorage und zeige es auf der nächsten Seite an?

154

Im Grunde muss ich ein einzelnes Bild hochladen, es in localStorage speichern und es dann auf der nächsten Seite anzeigen.

Derzeit habe ich meine HTML-Datei hochgeladen:

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

Womit diese Funktion verwendet wird, um das Bild auf der Seite anzuzeigen

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]);
    }
}

Das Bild wird sofort auf der Seite angezeigt, damit der Benutzer es sehen kann. Sie werden dann gebeten, den Rest des Formulars auszufüllen. Dieser Teil funktioniert perfekt.

Sobald das Formular ausgefüllt ist, klicken sie auf die Schaltfläche "Speichern". Sobald diese Taste gedrückt wird, speichere ich alle Formulareingaben als localStorageZeichenfolgen. Ich brauche eine Möglichkeit, um das Bild auch als localStorageElement zu speichern .

Über die Schaltfläche Speichern werden sie auch auf eine neue Seite weitergeleitet. Auf dieser neuen Seite werden die Benutzerdaten in einer Tabelle angezeigt, wobei sich das Bild oben befindet.

So schlicht und einfach, ich muss das Bild speichern, localStoragesobald die Schaltfläche "Speichern" gedrückt wird, und dann das Bild auf der nächsten Seite von ausleihen localStorage.

Ich habe einige Lösungen wie diese Geige und diesen Artikel bei moz: // a HACKS gefunden .

Obwohl ich immer noch sehr verwirrt bin, wie das funktioniert, und ich wirklich nur eine einfache Lösung brauche. Grundsätzlich muss ich das Bild nur über finden, getElementByIDsobald die Schaltfläche "Speichern" gedrückt wird, und dann das Bild verarbeiten und speichern.

Fizzix
quelle
2
Was ist falsch daran, reader.result in localstorage wie diesem Beispiel zu speichern: jsfiddle.net/x11joex11/9g8NN ?
Trace
Für Leute, die große Datenmengen auf localStorage speichern möchten, ist diese Bibliothek sehr nett: pieroxy / lz-string: LZ-basierter Komprimierungsalgorithmus für JavaScript
brasofilo
"Ich brauche wirklich nur eine einfache Lösung." Tut das nicht jeder?
Rodrigo

Antworten:

213

Wer auch dieses Problem lösen muss:

Zuerst greife ich mit meinem Bild zu getElementByIDund speichere es als Base64. Dann speichere ich die Base64-Zeichenfolge als meinen localStorageWert.

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

Hier ist die Funktion, die das Bild in eine Base64-Zeichenfolge konvertiert:

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

Dann habe ich auf meiner nächsten Seite ein Bild mit einem Leerzeichen srcwie folgt erstellt:

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

Und direkt beim Laden der Seite verwende ich diese nächsten drei Zeilen, um die Base64-Zeichenfolge abzurufen localStorageund sie mit dem von srcmir erstellten Leerzeichen auf das Bild anzuwenden :

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

Getestet in einigen verschiedenen Browsern und Versionen, und es scheint ziemlich gut zu funktionieren.

Fizzix
quelle
1
GIF wird nicht unterstützt, da GIF von Canvas nicht unterstützt wird.
Allen
16
Sie benötigen die Funktion getBase64Image nicht. Daten-URLs sind bereits Basis 64, und wenn Sie reader.readAsDataURL aufrufen, ist das an den reader.onload-Handler gesendete e.target.result alles, was Sie benötigen.
James H. Kelly
3
Beachten Sie, dass für den lokalen Speicher / Sitzungsspeicher ein Limit von ca. 5 MB gilt. Wenn Sie ein Binärbild in eine Basis-64-codierte Zeichenfolge konvertieren, wird es etwa 30% größer. Dies würde also für hochauflösende Bilder nicht funktionieren.
Noel Abrahams
Warum entfernen Sie den ersten Teil der Daten-URL? Größe reduzieren?
Deostroll
3
Beachten Sie, dass das Bild zuerst vollständig geladen werden muss (andernfalls werden leere Bilder angezeigt). In einigen Fällen müssen Sie die Behandlung in Folgendes einbinden: bannerImage.addEventListener ("load", function () {});
YE
9

Ich habe eine kleine 2,2-KB-Bibliothek zum Speichern von Bildern in localStorage JQueryImageCaching Usage geschrieben:

<img data-src="path/to/image">
<script>
    $('img').imageCaching();
</script>
Moledet
quelle
2
2.2 Kilobyte sind für so etwas riesig, und ich vermute, dass dies nicht einmal die Größe von jQuery selbst berücksichtigt. Ich würde vorschlagen, es ohne jQuery zu schreiben, vielleicht wird es kleiner
ChrisBrownie55
1,74 KB laut Gitbub
Hakiko
6

Sie können das Bild in einen Daten-URI serialisieren. In diesem Blog-Beitrag gibt es ein Tutorial . Dadurch wird eine Zeichenfolge erstellt, die Sie im lokalen Speicher speichern können. Verwenden Sie dann auf der nächsten Seite die Daten-URL als Quelle des Bildes.

Ray Wadkins
quelle
0

"Beachten Sie, dass das Bild zuerst vollständig geladen werden muss (andernfalls werden leere Bilder angezeigt). In einigen Fällen müssen Sie die Behandlung in Folgendes einbinden: bannerImage.addEventListener (" load ", function () {}); - Yuga 1. November 17 um 13:04 "

Dies ist äußerst wichtig. Eine der Optionen, die ich heute Nachmittag untersuche, ist die Verwendung von Javascript-Rückrufmethoden anstelle von addEventListeners, da dies auch nicht richtig zu binden scheint. Es ist wichtig, alle Elemente vor dem Laden der Seite OHNE Seitenaktualisierung vorzubereiten.

Wenn jemand dies erweitern kann, tun Sie dies bitte - wie in, haben Sie ein Settimeout, eine Wartezeit, einen Rückruf oder eine addEventListener-Methode verwendet, um das gewünschte Ergebnis zu erzielen. Welches und warum?

Andrew Ellison Pembroke
quelle
Verwenden Sie immer einen Rückruf, wenn Sie können, und verwenden Sie niemals ein Settimeout, wenn Sie dies vermeiden können. Sie möchten, dass das Ding nach dem vorherigen passiert, mit so wenig Aufwand wie möglich. Genau dafür sind Rückrufe gedacht
Grayson
-2

Ich habe das gleiche Problem festgestellt, anstatt Bilder zu speichern, die schließlich den lokalen Speicher überlaufen. Sie können einfach den Pfad zum Bild speichern. etwas wie:

let imagen = ev.target.getAttribute('src');
arrayImagenes.push(imagen);
SebasCiB3R
quelle