Bagaimana cara menyimpan gambar ke penyimpanan lokal dan menampilkannya di halaman berikutnya?

154

Jadi, pada dasarnya, saya perlu mengunggah satu gambar, menyimpannya ke localStorage, lalu menampilkannya di halaman berikutnya.

Saat ini, saya memiliki unggahan file HTML saya:

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

Yang menggunakan fungsi ini untuk menampilkan gambar pada halaman

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

Gambar ditampilkan langsung di halaman untuk dilihat pengguna. Mereka kemudian diminta mengisi sisa formulir. Bagian ini berfungsi dengan sempurna.

Setelah formulir selesai, mereka kemudian menekan tombol 'Simpan'. Setelah tombol ini ditekan, saya menyimpan semua input form sebagai localStoragestring. Saya perlu cara untuk juga menyimpan gambar sebagai localStorageitem.

Tombol simpan juga akan mengarahkan mereka ke halaman baru. Halaman baru ini akan menampilkan data pengguna dalam sebuah tabel, dengan gambar berada di atas.

Begitu sederhana dan sederhana, saya perlu menyimpan gambar localStoragesetelah tombol 'Simpan' ditekan, dan kemudian meminjamkan gambar di halaman berikutnya localStorage.

Saya menemukan beberapa solusi seperti biola ini dan artikel ini di moz: // a HACKS .

Meskipun saya masih sangat bingung tentang cara kerjanya, dan saya hanya benar-benar membutuhkan solusi sederhana. Pada dasarnya, saya hanya perlu menemukan gambar melalui getElementByIDsekali tombol 'Simpan' ditekan, lalu proses dan simpan gambar.

Fizzix
sumber
2
Apa yang salah dengan menyimpan reader.result di penyimpanan lokal seperti contoh ini: jsfiddle.net/x11joex11/9g8NN ?
Lacak
Bagi orang yang mencari untuk menyimpan sejumlah besar data di localStorage perpustakaan ini cukup bagus: pieroxy / lz-string: Algoritma kompresi berbasis LZ untuk JavaScript
brasofilo
"Aku hanya butuh solusi sederhana." Tidak semua orang?
Rodrigo

Jawaban:

213

Kepada siapa pun yang membutuhkan masalah ini diselesaikan:

Pertama, saya ambil gambar saya dengan getElementByID, dan menyimpan gambar sebagai Base64. Lalu saya menyimpan string Base64 sebagai localStoragenilai saya .

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

Berikut adalah fungsi yang mengubah gambar menjadi string 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,/, "");
}

Kemudian, pada halaman berikutnya saya membuat gambar dengan kosong srcseperti:

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

Dan langsung ketika halaman dimuat, saya menggunakan tiga baris berikutnya untuk mendapatkan string Base64 localStorage, dan menerapkannya pada gambar dengan kosong yang srcsaya buat:

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

Mengujinya di beberapa peramban dan versi yang berbeda, dan tampaknya berfungsi dengan baik.

Fizzix
sumber
1
Gif tidak mendukung, karena gif tidak didukung oleh kanvas.
Allen
16
Anda tidak memerlukan fungsi getBase64Image. Url data sudah berbasis 64 sehingga ketika Anda memanggil reader.readAsDataURL, e.target.result yang dikirim ke reader.onload handler akan menjadi semua yang Anda butuhkan.
James H. Kelly
3
Ingatlah bahwa ada batas sekitar 5MB untuk penyimpanan lokal / sesi. Dan mengkonversi gambar biner ke basis 64 string yang dikodekan akan membuatnya sekitar 30% lebih besar. Jadi ini tidak akan berfungsi untuk gambar resolusi tinggi.
Noel Abrahams
Mengapa Anda menghapus bagian awal url data? Untuk mengurangi ukuran?
deostroll
3
Perhatikan bahwa Anda harus memuat gambar sepenuhnya terlebih dahulu (jika tidak berakhir memiliki gambar kosong), maka dalam beberapa kasus Anda harus membungkus penanganan ke: bannerImage.addEventListener ("load", function () {});
YE
9

Saya menulis perpustakaan kecil 2,2 kb untuk menyimpan gambar di localStorage JQueryImageCaching Usage:

<img data-src="path/to/image">
<script>
    $('img').imageCaching();
</script>
moledet
sumber
2
2.2 Kilobyte sangat besar untuk hal seperti ini, ditambah lagi saya menduga itu bahkan tidak menjadi faktor dalam ukuran jQuery itu sendiri. Saya sarankan menulisnya tanpa jQuery, mungkin itu akan lebih kecil
ChrisBrownie55
1.74 KB menurut gitbub
hakiko
6

Anda bisa membuat cerita bersambung gambar menjadi Data URI. Ada tutorial di posting blog ini . Itu akan menghasilkan string yang dapat Anda simpan di penyimpanan lokal. Kemudian di halaman selanjutnya, gunakan data uri sebagai sumber gambar.

Ray Wadkins
sumber
0

"Perhatikan bahwa Anda perlu memuat gambar sepenuhnya terlebih dahulu (jika tidak berakhir memiliki gambar kosong), maka dalam beberapa kasus Anda harus membungkus penanganan ke: bannerImage.addEventListener (" load ", function () {}); - yuga 1 Nov '17 jam 13:04 "

Ini sangat PENTING. Salah satu opsi yang saya jelajahi sore ini adalah menggunakan metode panggilan balik javascript daripada addEventListeners karena itu sepertinya juga tidak mengikat dengan benar. Mempersiapkan semua elemen sebelum memuat halaman TANPA penyegaran halaman sangat penting.

Jika ada yang bisa memperluas ini silakan lakukan - seperti dalam, apakah Anda menggunakan settimeout, tunggu, panggilan balik, atau metode addEventListener untuk mendapatkan hasil yang diinginkan. Yang mana dan mengapa?

Andrew Ellison Pembroke
sumber
selalu gunakan panggilan balik jika Anda bisa, dan jangan pernah gunakan penyelesaian jika Anda bisa menghindarinya. Dengan desain, Anda ingin hal itu terjadi setelah hal sebelumnya, dengan sesedikit mungkin overhead. Inilah mengapa callback dirancang untuk
Grayson
-2

Saya telah menemukan masalah yang sama, alih-alih menyimpan gambar, yang pada akhirnya meluap penyimpanan lokal, Anda bisa menyimpan path ke gambar. sesuatu seperti:

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