Bir görüntüyü localStorage'a nasıl kaydedebilir ve sonraki sayfada nasıl görüntüleyebilirim?


154

Yani, temel olarak, tek bir resim yüklemem, localStorage'a kaydetmem ve sonra bir sonraki sayfada göstermem gerekiyor.

Şu anda HTML dosya yüklemem var:

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

Görüntüyü sayfada görüntülemek için bu işlevi kullanan

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

Görüntü, kullanıcının görmesi için anında sayfada görüntülenir. Daha sonra formun geri kalanını doldurmaları istenir. Bu bölüm mükemmel çalışıyor.

Form tamamlandıktan sonra, bir 'Kaydet' düğmesine basarlar. Bu düğmeye basıldığında, tüm form girişlerini localStoragedize olarak kaydederim. Ayrıca resmi bir localStorageöğe olarak kaydetmek için bir yol gerekir .

Kaydet düğmesi ayrıca yeni bir sayfaya yönlendirir. Bu yeni sayfa, görüntü üstte olacak şekilde kullanıcı verilerini bir tabloda görüntüleyecektir.

Çok sade ve basit, localStorage'Kaydet' düğmesine basıldığında görüntüyü kaydetmem ve sonraki sayfadaki görüntüyü ödünç almam gerekiyor localStorage.

Moz: // a HACKS'de bu keman ve bu makale gibi bazı çözümler buldum .

Yine de bunun nasıl çalıştığı konusunda son derece kafam karışmış olsa da ve gerçekten basit bir çözüme ihtiyacım var. Temel olarak, getElementByID'Kaydet' düğmesine basıldıktan sonra görüntüyü bulmam ve ardından görüntüyü işlemem ve kaydetmem gerekiyor.


2
Reader.result dosyasının bu örnekte olduğu gibi localstorage'da saklanmasında sorun nedir: jsfiddle.net/x11joex11/9g8NN ?
İz


"Sadece basit bir çözüme ihtiyacım var." Herkes değil mi?
Rodrigo

Yanıtlar:


213

Bu soruna kimin ihtiyacı varsa çözüldü:

İlk olarak, resmimi getElementByIDalıp Base64 olarak kaydediyorum. Sonra Base64 dizesini benim localStoragedeğer olarak kaydedin .

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

Görüntüyü Base64 dizesine dönüştüren işlev şunlardır:

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

Sonra, bir sonraki sayfada şöyle boş bir görüntü oluşturdum src:

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

Ve sayfa yüklendiğinde, Base64 dizesini almak ve oluşturduğum boşlukla localStoragegörüntüye uygulamak için sonraki üç satırı kullanıyorum src:

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

Birkaç farklı tarayıcıda ve sürümde test edildi ve oldukça iyi çalışıyor gibi görünüyor.


1
Gif destek değildir, çünkü gif tuval tarafından desteklenmez.
Allen

16
GetBase64Image işlevine ihtiyacınız yoktur. Veri URL'leri zaten temel 64'tür, bu nedenle reader.readAsDataURL öğesini çağırdığınızda, reader.onload işleyicisine gönderilen e.target.result tek ihtiyacınız olan şey olacaktır.
James H. Kelly

3
Yerel / oturum depolaması için yaklaşık 5 MB'lık bir sınır olduğunu unutmayın. Ve ikili bir görüntüyü 64 kodlanmış bir dizeye dönüştürmek görüntüyü yaklaşık% 30 büyütür. Yani bu yüksek çözünürlüklü görüntüler için işe yaramaz.
Noel Abrahams

Neden veri url'sinin ilk kısmını kaldırıyorsunuz? Boyutu azaltmak için?
deostroll

3
Öncelikle görüntünün tam olarak yüklenmiş olması gerektiğini unutmayın (aksi takdirde boş görüntülere sahip olursunuz), bu nedenle bazı durumlarda ele almayı sarmanız gerekir: bannerImage.addEventListener ("load", function () {});
YE

9

LocalStorage JQueryImageCaching Kullanımı görüntü kaydetmek biraz 2,2kb kütüphane yazdı :

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

2
2.2 Kilobayt, böyle bir şey için çok büyük, artı jQuery'nin boyutunu bile etkilemediğini tahmin ediyorum. Bunu jQuery olmadan yazmanızı öneririm, belki daha küçük olacaktır
ChrisBrownie55

1.74 KB gitbub'a göre
hakiko

6

Görüntüyü bir Veri URI'sinde serileştirebilirsiniz. Bu blog yazısında bir eğitim var . Bu, yerel depolama alanında depolayabileceğiniz bir dize üretecektir. Sonra bir sonraki sayfada görüntünün kaynağı olarak veri uri'yi kullanın.


0

Msgstr "" "Önce görüntüyü tam olarak yüklemeniz gerektiğini unutmayın (aksi takdirde boş görüntülere sahip olursunuz), bu nedenle bazı durumlarda ele almayı sarmanız gerekir: bannerImage.addEventListener (" load ", function () {}); - yuga 1 '17, 13:04 "

Bu son derece önemlidir. Bu öğleden sonra keşfetmek seçeneklerden biri de doğru bağlanma gibi görünmüyor çünkü addEventListeners yerine javascript geri arama yöntemleri kullanıyor. Sayfa yenilemeden Sayfa yüklenmeden önce tüm öğelerin hazır hale getirilmesi çok önemlidir.

Eğer herkes bunu genişletebilirse, lütfen - olduğu gibi, istenen sonucu almak için bir settimeout, bir bekleme, bir geri arama veya addEventListener yöntemi kullandınız mı? Hangisi ve neden?


her zaman mümkünse bir geri arama kullanın ve kaçınabiliyorsanız asla bir zamanaşımı kullanmayın. Tasarım gereği, bir önceki şeyden sonra, olabildiğince az ek yük ile gerçekleşmesini istiyorsunuz. Geri çağrılar tam olarak bunun için tasarlanmıştır
Grayson

-2

Aynı sorunu, görüntüleri depolamak yerine, sonunda yerel depodan taşan, sadece görüntü yolunu saklayabilirsiniz. gibi bir şey:

let imagen = ev.target.getAttribute('src');
arrayImagenes.push(imagen);
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.