Артём Мáлков

Выводим изображение в кодировке Base64 на HTML/CSS и сохраняем его на jQuery+PHP

13 фев18 комм

Base64 – это некий стандарт кодирования информации посредством только 64 символов таблицы ASCII. В эту таблицу входят символы латинского языка (A-Z и a-z), цифры от 0 до 9, а также некоторые знаки.

Принцип этого кодирования – представление любой цифровой информации в виде уникального набора символов этой таблицы.

Чтобы вы наглядно понимали, что это такое, поясню. Перед вами изображение:

Выводим изображение в кодировке Base64 на HTML/CSS и сохраняем его на jQuery+PHP

А вот его кодировка Base64:

data:image/gif;base64,R0lGODlhDQAMANUAAFRVVtHd74S192aZzHqVuLq0rvf39+zr6bXI4qizwufdz5WhsmSt/5rC+r3Ezm1zeJiSjmum8tzm9bvZ/6bB5a6qpn+t5dvVzZK88+v8/7vg/7DJ4P/99V5gY8zMzObm5ofD/6zQ/3Fua8fX69fm+vDy9OPi4czh/4SXrJLC/////+7u7Wmt/87f9oG2/5Oku5mZmf///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAUUADEALAAAAAANAAwAAAZTwJhwSIwhDsUixZEkWhLNYeQVjYUYBIVKSCKeGIOCymCISTATISsCu5RKW1VAkHKBUBDToRxTcUYNGhsdFR8GW0IqJS0ZDyIrh0kqCwBIVR4eTUEAOw==

Что нас здесь интересует? Как сохранить такие данные и представить их в читабельном виде на примере все тех же изображений.

Выводим изображение в формате Base64 на HTML/CSS

В HTML встраивание подобного рода кода осуществляется с помощью всем привычного тега IMG. И на примере все той же картинки результат будет следующим:

<img src="data:image/gif;base64,R0lGODlhDQAMANUAAFRVVtHd74S192aZzHqVuLq0rvf39+zr6bXI4qizwufdz5WhsmSt/5rC+r3Ezm1zeJiSjmum8tzm9bvZ/6bB5a6qpn+t5dvVzZK88+v8/7vg/7DJ4P/99V5gY8zMzObm5ofD/6zQ/3Fua8fX69fm+vDy9OPi4czh/4SXrJLC/////+7u7Wmt/87f9oG2/5Oku5mZmf///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAUUADEALAAAAAANAAwAAAZTwJhwSIwhDsUixZEkWhLNYeQVjYUYBIVKSCKeGIOCymCISTATISsCu5RKW1VAkHKBUBDToRxTcUYNGhsdFR8GW0IqJS0ZDyIrh0kqCwBIVR4eTUEAOw==" />

Помимо этого, Base64 можно встроить и в CSS-файл:

div { 
	background: url('data:image/gif;base64,R0lGODlhDQAMANUAAFRVVtHd74S192aZzHqVuLq0rvf39+zr6bXI4qizwufdz5WhsmSt/5rC+r3Ezm1zeJiSjmum8tzm9bvZ/6bB5a6qpn+t5dvVzZK88+v8/7vg/7DJ4P/99V5gY8zMzObm5ofD/6zQ/3Fua8fX69fm+vDy9OPi4czh/4SXrJLC/////+7u7Wmt/87f9oG2/5Oku5mZmf///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAUUADEALAAAAAANAAwAAAZTwJhwSIwhDsUixZEkWhLNYeQVjYUYBIVKSCKeGIOCymCISTATISsCu5RKW1VAkHKBUBDToRxTcUYNGhsdFR8GW0IqJS0ZDyIrh0kqCwBIVR4eTUEAOw==') no-repeat;
}

Какие есть преимущества у этой кодировки? Основное преимущество – это то, что изображения вы не храните на своем сервере и вообще ни на каком в принципе, а просто размещаете нужные вам файлы в теле страницы обычным текстом.

Сохранение изображения в формате Base64 на jQuery+PHP

Чуть выше мы разобрали с вами встраивание изображений непосредственно в страницу вашего сайта с помощью HTML и CSS, а сейчас мы рассмотрим способ сохранения такого изображения на вашем сайте.

В одной из статей был рассмотрен вопрос о том, как же сделать скриншот элемента на JavaScript, используя библиотеку html2canvas. В примере мы рассматривали скриншот как уже готовое изображение, но мы не упомянули, что при использовании там кода:

var my_screen = canvas.get(0).toDataURL();

можно получить изображение как раз в кодировке Base64.

Давайте попробуем сохранить это (вы можете использовать свое) изображение в кодировке Base64, используя технологию AJAX и не большой PHP-скрипт.

Начнем с jQuery. Скрипт, который будет посылать в обработчик (PHP-скрипт) наши данные, будет выглядеть следующим образом:

<script>

	$(function() { 

		var base_image = "data:image/gif;base64,R0lGODlhDQAMANUAAFRVVtHd74S192aZzHqVuLq0rvf39+zr6bXI4qizwufdz5WhsmSt/5rC+r3Ezm1zeJiSjmum8tzm9bvZ/6bB5a6qpn+t5dvVzZK88+v8/7vg/7DJ4P/99V5gY8zMzObm5ofD/6zQ/3Fua8fX69fm+vDy9OPi4czh/4SXrJLC/////+7u7Wmt/87f9oG2/5Oku5mZmf///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAUUADEALAAAAAANAAwAAAZTwJhwSIwhDsUixZEkWhLNYeQVjYUYBIVKSCKeGIOCymCISTATISsCu5RKW1VAkHKBUBDToRxTcUYNGhsdFR8GW0IqJS0ZDyIrh0kqCwBIVR4eTUEAOw==";
		var base_image = base_image.replace("data:image/gif;base64,", "");

		$.post("/upload/base-image.php", {
		
			data: base_image
			
		}, function(result_data) {	
		
			$("#result").html(result_data);
			
		});
	
	});
	
</script>

Где «base_image» – данные изображения в Base64, «/upload/base-image.php» – путь до PHP-скрипта, а «#result» – ID элемента, в который будет выводиться результат.

Сам же скрипт-обработчик будет выглядеть следующим образом:

<?php

	$name = time().".gif";
	$check_save = @file_put_contents($name, base64_decode($_POST["data"]));

	if($check_save) {
	
		echo "Файл успешно сохранен. Адрес для просмотра - /upload/".$name;
		
	} else {
	
		echo "Ошибка в сохранении!";
		
	}
	
?>

Здесь все предельно просто – получаем данные, обрабатываем и сохраняем их в той же директории, что и сам обработчик.

В качестве функции запуска я использовал обычную загрузку страницы, вы же можете привязать ее, например, к клику по ссылке или другому нужному вам действию.

Расписал вроде все максимально подробно, но если какие-то моменты вызывают у вас трудности, не стесняйтесь и задавайте их в комментариях – никого не оставим без внимания.

Рекомендуем к просмотру
Как вставить изображение (картинку) на сайт в HTML?
Статьи и советы
Как сделать скриншот элемента на JavaScript?
Модули и скрипты
Как удалить все буквы, цифры и спецсимволы в строке на PHP/JavaScript?
Статьи и советы
18
комментариев
Форма комментирования этого поста скрыта. Авторизуйтесь, чтобы расширить привилегии гостевого посещения и получить необходимую помощь от сообщества Pandoge.
    • 1
    1066
      •  Команда Pandoge
    18 июл в 20:09

    Ihor Panda ну и хорошо.

    Почаще посещайте сайт smiley

    • 1
    10
      •  Проверенный
    18 июл в 19:37

    Всё, решено, стандартная длинна поля input не позволяла принять настолько длинную строчку, пришлось использовать textarea. Спасибо огромное!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

    • 1
    10
      •  Проверенный
    18 июл в 19:24

    Другие наборы картинок срабатывают отлично, мне кажется проблема где-то на шаге конвертирования в base64 функцией .toDataURL()

    • 1
    10
      •  Проверенный
    18 июл в 19:23

    Я сделал кучу тестов, она всегда обрезана в одном месте. Поставил задержку на функцию канваса. У меня в мониторе она помещается идеально, темболее класс висит на родительском контейнере с фиксированной висотой и шириной

    • 1
    1066
      •  Команда Pandoge
    18 июл в 19:12

    Ihor Panda, рассматривали вариант того, что картинка не успевает прогрузиться или не помещается в экран пользователя?

    • 0
    10
      •  Проверенный
    18 июл в 18:55

    Да, ещё момент, когда удаляю div, к которому прикрепляется картинка с верхом дымохода, добавляя который весь скрин приходит обрезанным - то он приходит норм. Консоль же корректно считывает картинки

    • 1
    10
      •  Проверенный
    18 июл в 18:36

    Другой же скриншот приходит корректно: http://prntscr.com/ogvjjc

    Все картинки идентичны в png, меняются только классы у div'вов что бы подтягивались соответствующие картинки, я уже и сжимал, размер у всех картинок примерно одинаковый. И на фотошопе с нуля переделывал графику, не пойму в чем беда(

    • 1
    10
      •  Проверенный
    18 июл в 18:31

    То бишь плагин корректно считывается размер, но почему то оставляет прозрачное пространство: http://prntscr.com/ogvhsr

    • 0
    10
      •  Проверенный
    18 июл в 18:26

    проблема решилась, нужно было id прямо на картинку прицепить, а я на родительский div))) Но есть ещё один баг связанный связанный с данным плагином, есть сайт, тут я реализую конструктор дымоходов: https://teplo-s.com.ua/produkcziya/konstruktor-dymohodov/

    в момент нажатия на вкладку "Шаг 4" делается скриншот и он в формате base 64 попадает в текстовое поле формы обратной связи, значение которого выводится в параметр тега src, тега img на стороне владельца сайта. в 70% случаев скриншоты приходят корректно, а оставшиеся 30% обрезаются, в чем может быть причина?

    Вот так выводится: http://prntscr.com/ogver6

    может ли это быть следствием того, что все картинки я накладываются в стилях как background?

      • 0
      1
        •  Пользователь
      28 сен в 16:05

      Ihor Panda, Можете помочь? У меня та же проблема. У вас она решилась, как вы сказали тем, что " нужно было id прямо на картинку прицепить, а я на родительский div". Не понятно куда id прицепить.

    • 0
    1066
      •  Команда Pandoge
    18 июл в 14:49

    Ihor Panda, есть возможность предоставить доступ к коду?

    • 0
    10
      •  Проверенный
    18 июл в 10:58

    В переменную попадает не полный код картинки base64, если я верно всё понял, из-за этого они и сохраняются некорректно(

    • 0
    10
      •  Проверенный
    18 июл в 10:55

    Выдает такие вот вещи:

    http://prntscr.com/ognsn5

    • 0
    1066
      •  Команда Pandoge
    17 июл в 20:36

    Ihor Panda, здравствуйте. Вообще, в коде я не вижу ошибок.

    Что выдает консоль разработчика?

    • 1
    10
      •  Проверенный
    17 июл в 19:55

    Здравствуйте, у меня получился такой скрипт (задача сохранить на сервере скриншот картинки, которая лежит в диве #content):

    <script>

    window.onload = function() {

    html2canvas(document.getElementById("content")).then(function(canvas) {

    var base_image = canvas.toDataURL();

    var base_image = base_image.replace("data:image/gif;base64,", "");

    $.post("upload/base-image.php", {

    data: base_image

    }, function(result_data) {

    $("#result").html(result_data);

    });

    });

    }

    </script>

    ---------------------------------------------------

    Если использовать "canvas.get(0).toDataURL()" - картинка не конвертируется в base64, а если использовать "canvas.toDataURL();" - получается что-то похожое, но при открытии возникает ошибка, подскажите пожалуйста, как правельно поступить? Спасибо!

    • 0
    766
      •  Гости
    20 мар в 10:28

    Не получается, почему-то.... Ну да ладно, через отдельный файл отлично работает.

    Чего ради, собственно, я это захотел: нужно было, чтобы адрес сохранённой картинки передавался в переменную, а не в id элемента. Для того, чтобы из первоначального документа сразу ссылаться на картинку.

    Передаю из base-image.php в качестве результата что-то вроде:

    <code>echo '<a href='."пусть на сервере до каталога/".$name.' download>Скачать</a>';</code>

    А в изначальном файле потом вызываю:

    <code><div id="result"></div></code>

    Получается ссылка. Но прописать её в переменную не хватает знаний.

    ------

    В любом случае, ещё раз вам большое спасибо за материал, ушло в закладки

    • 12
    1066
      •  Команда Pandoge
    20 мар в 00:03

    Апрес, большое спасибо. Приятно это слышать.

    Если я Вас правильно понял - то изображение можно передать так же через пост-запрос, но только на самого себя (на ту страницу где находимся) с дополнительной проверкой существования передаваемых данных.

    В скрипте вы будете писать что то типа

    $.post('/upload/1.php', {

    А в обработчике условие:

    if (isset($_POST["data"])) { // Если данные получили - сохраняем.

    Тут скрипт сохранения

    }

    А если же данных нет, то будет просто выводиться скрипт HTML+JS.

    • 1
    766
      •  Гости
    19 мар в 09:16

    Артём, в первую очередь, большое спасибо за обе статьи по теме canvas.

    Остался у меня один вопрос: а можно сделать всё то же самое, только в одном php-файле?

    То есть, у меня имеется условный файл 1.php, в котором через тег script вызывается html2canvas. Он передаёт данные через $.post (как у вас в примере) в файл base-image.php, где производится сохранение файла изображения.

    Можно ли не делать файл base-image.php, а данные из JavaScript convas обработать тем же кодом, но в самом файле 1.php? Если да, то как передать значение и как вернуть (хотя, думаю, с возвратом переменной внутри одного php-файла проблем возникнуть не должно).

Подняться наверх
«Pandoge» - помощник вебмастера