Як зберегти зображення в localStorage і відобразити його на наступній сторінці?


154

Отже, в основному мені потрібно завантажити одне зображення, зберегти його в localStorage, а потім відобразити на наступній сторінці.

Наразі я завантажую свій HTML-файл:

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

Яка функція використовує цю функцію для відображення зображення на сторінці

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

Зображення відображається миттєво на сторінці, яку бачить користувач. Потім їх просять заповнити решту форми. Ця частина працює чудово.

Після заповнення форми вони натискають кнопку "Зберегти". Після натискання цієї кнопки я зберігаю всі введення форми у вигляді localStorageрядків. Мені потрібен спосіб також зберегти зображення як localStorageпредмет.

Кнопка збереження також направить їх на нову сторінку. Ця нова сторінка відображатиме дані користувачів у таблиці, зображення вгорі.

Настільки просто і просто, мені потрібно зберегти зображення, localStorageяк тільки натиснути кнопку «Зберегти», а потім позичити зображення на наступній сторінці від localStorage.

Я знайшов такі рішення, як ця скрипка та ця стаття в моді: // HACKS .

Хоча я все ще вкрай розгублений у тому, як це працює, і мені дуже потрібне просте рішення. По суті, мені просто потрібно знайти зображення, getElementByIDнатиснувши кнопку "Зберегти", а потім обробити та зберегти зображення.


2
Що не так із зберіганням читача.result у локальному сховищі, як цей приклад: jsfiddle.net/x11joex11/9g8NN ?
Простежте

Для людей, які хочуть зберігати велику кількість даних у localStorage, ця бібліотека є дуже приємною: pieroxy / lz-string: алгоритм стиснення на основі LZ для JavaScript
brasofilo

"Мені дуже потрібне просте рішення". Чи не всі?
Родріго

Відповіді:


213

Для того, хто також потребує вирішення цієї проблеми:

По-перше, я захоплюю своє зображення getElementByIDі зберігаю його як Base64. Тоді я зберігаю рядок Base64 як своє localStorageзначення.

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

Ось функція, яка перетворює зображення в рядок 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,/, "");
}

Потім на своїй наступній сторінці я створив зображення з таким порожнім src:

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

І прямо під час завантаження сторінки я використовую ці три наступні рядки, щоб отримати рядок Base64 localStorageі застосувати його до зображення із srcствореним мною пустим :

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

Випробували його у досить кількох різних браузерах та версіях, і, здається, він працює досить добре.


1
Gif не підтримує, оскільки gif не підтримується полотном.
Аллен

16
Вам не потрібна функція getBase64Image. URL-адреси даних вже є базовою 64, тому коли ви зателефонуєте на читач.readAsDataURL, e.target.result, надісланий на обробник читача, буде все, що вам потрібно.
Джеймс Х. Келлі

3
Майте на увазі, що для локального / сеансового зберігання існує обмеження близько 5 Мб. А перетворення двійкового зображення в кодовану рядок 64, зробить його приблизно на 30%. Отже, це не буде працювати для зображень високої роздільної здатності.
Ноель Авраамс

Чому ви знімаєте початкову частину URL-адреси даних? Щоб зменшити розмір?
деастролл

3
Зауважте, що спочатку потрібно повністю завантажити зображення (інакше закінчившись порожніми зображеннями), тому в деяких випадках вам потрібно буде перетворити обробку на: bannerImage.addEventListener ("load", function () {});
YE

9

Я написав невелику бібліотеку збереження зображення в 2,2kb в localStorage JQueryImageCaching Використання:

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

2
2.2 Кілобайти є величезним для чогось подібного, плюс я гадаю, що навіть не враховує розмір jQuery. Я б запропонував написати це без jQuery, можливо, він буде меншим
ChrisBrownie55

1,74 Кб за версією gitbub
hakiko

6

Ви можете серіалізувати зображення в URI даних. У цій публікації блогу є підручник . Це дозволить створити рядок, який можна зберігати в локальному сховищі. Потім на наступній сторінці використовуйте дані uri як джерело зображення.


0

"Зверніть увагу, що спочатку вам потрібно повністю завантажити зображення (інакше закінчившись порожніми зображеннями), тому в деяких випадках вам потрібно буде обробляти обробку в: bannerImage.addEventListener (" load ", function () {}) - Юга 1 листопада '17 о 13:04 "

Це надзвичайно ВАЖЛИВО. Один із варіантів, які я вивчаю сьогодні вдень, - це використання методів зворотного виклику javascript, а не addEventListeners, оскільки, здається, теж не пов'язується правильно. Підготовка всіх елементів до завантаження сторінки БЕЗ оновлення сторінки є критично важливою.

Якщо хтось може розширити це питання, будь ласка, зробіть це, як і раніше, чи використовували ви час встановлення, очікування, зворотний дзвінок або метод addEventListener, щоб отримати бажаний результат. Який і чому?


завжди використовуйте зворотний дзвінок, якщо можете, і ніколи не використовуйте час встановлення, якщо ви можете цього уникнути. За дизайном ви хочете, щоб річ сталася після попередньої речі, з якомога меншими накладними витратами. Саме для цього розраховані зворотні виклики
Грейсон

-2

Я придумав те саме питання, замість того, щоб зберігати зображення, які з часом переповнюють локальну пам’ять, ви можете просто зберігати шлях до зображення. щось на зразок:

let imagen = ev.target.getAttribute('src');
arrayImagenes.push(imagen);
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.