Как отображать изображения на веб-сервере ESP32 и ESP8266

В этом руководстве показано, как отображать изображения (.png и .jpg) на веб-серверах ESP32 или ESP8266 с использованием Arduino IDE. Мы рассмотрим, как встраивать изображения в асинхронный веб-сервер с использованием библиотеки ESPAsyncWebServer или в простой HTTP-сервер.

Как отображать изображения на веб-сервере ESP32/ESP8266

Отображение изображений на веб-сервере ESP

Существуют различные способы отображения изображений на веб-серверах ESP32/ESP8266. В этой статье мы рассмотрим следующие методы:

  1. Встраивание изображения путём указания его URL (гиперссылка на место хранения изображения);

  2. Сохранение изображения в файловой системе ESP32/ESP8266 (LittleFS);

  3. Конвертация изображений в base64.

Вариант #1: URL изображения

Чтобы включить изображения в HTML, используйте тег <img> с атрибутом src, как показано ниже:

<img src="image_source">

Вы можете использовать URL, который ссылается на источник любого изображения, хранящегося в интернете.

<img src="https://example.com/your_image_source_url.png">

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

Примеры веб-серверов можно найти в следующих статьях:

Вариант #2: Сохранение изображения в LittleFS ESP32/ESP8266

LittleFS — это легковесная файловая система, созданная для микроконтроллеров с flash-чипом, таких как ESP32 и ESP8266.

Она позволяет вам обращаться к flash-памяти так же, как вы бы работали с обычной файловой системой на вашем компьютере. Вы можете хранить HTML- и CSS-файлы в LittleFS для построения веб-сервера, включая небольшие изображения и иконки.

В этом разделе мы покажем, как сохранить изображения во flash-памяти и передать их клиенту в асинхронном веб-сервере.

Плагин загрузки файловой системы

Для загрузки изображений во flash-память ESP32 и ESP8266 мы будем использовать плагин для Arduino IDE: Filesystem uploader. Следуйте одному из следующих руководств для установки плагина загрузки файловой системы (он совместим с обеими платами).

После установки плагина вы можете продолжить руководство.

Установка библиотек для асинхронного веб-сервера

В этом разделе показано, как отобразить изображение, хранящееся во flash-памяти ESP32 или ESP8266, на веб-сервере с использованием библиотеки ESPAsyncWebServer. Для сборки этого веб-сервера вам нужно установить следующие библиотеки:

  • Если вы используете ESP32: вам нужно установить библиотеки ESPAsyncWebServer и AsyncTCP.

  • Если вы используете ESP8266: вам нужно установить библиотеки ESPAsyncWebServer и ESPAsyncTCP.

Код — Отображение изображений в асинхронном веб-сервере

Создайте новый скетч в Arduino IDE и скопируйте следующий код. Этот код работает с ESP32 и ESP8266. Он подключает соответствующие библиотеки в зависимости от используемой платы.

/*********
  Rui Santos & Sara Santos - Random Nerd Tutorials
  Complete project details at https://RandomNerdTutorials.com/display-images-esp32-esp8266-web-server/
*********/
#ifdef ESP32
  #include <WiFi.h>
  #include <ESPAsyncWebServer.h>
  #include <LittleFS.h>
#else
  #include <Arduino.h>
  #include <ESP8266WiFi.h>
  #include <Hash.h>
  #include <ESPAsyncTCP.h>
  #include <ESPAsyncWebServer.h>
  #include "LittleFS.h"
#endif

// Replace with your network credentials
const char* ssid = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_PASSWORD";

// Create AsyncWebServer object on port 80
AsyncWebServer server(80);

const char index_html[] PROGMEM = R"rawliteral(
<!DOCTYPE HTML><html>
<head>
  <meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
  <h2>ESP Image Web Server</h2>
  <img src="sun">
  <img src="sun-cloud">
  <img src="cloud">
  <img src="rain">
  <img src="storm">
  <img src="snow">
</body>
</html>)rawliteral";

void setup(){
  // Serial port for debugging purposes
  Serial.begin(115200);

  // Connect to Wi-Fi
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(1000);
    Serial.println("Connecting to WiFi..");
  }
  if(!LittleFS.begin()){
        Serial.println("An Error has occurred while mounting LittleFS");
        return;
  }

  // Print ESP32 Local IP Address
  Serial.println(WiFi.localIP());

  // Route for root / web page
  server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
    request->send(200, "text/html", index_html);
  });

  server.on("/sun", HTTP_GET, [](AsyncWebServerRequest *request){
    request->send(LittleFS, "/sun.png", "image/png");
  });
  server.on("/sun-cloud", HTTP_GET, [](AsyncWebServerRequest *request){
    request->send(LittleFS, "/sun-cloud.png", "image/png");
  });
  server.on("/cloud", HTTP_GET, [](AsyncWebServerRequest *request){
    request->send(LittleFS, "/cloud.png", "image/png");
  });
  server.on("/rain", HTTP_GET, [](AsyncWebServerRequest *request){
    request->send(LittleFS, "/rain.png", "image/png");
  });
  server.on("/storm", HTTP_GET, [](AsyncWebServerRequest *request){
    request->send(LittleFS, "/storm.png", "image/png");
  });
  server.on("/snow", HTTP_GET, [](AsyncWebServerRequest *request){
    request->send(LittleFS, "/snow.png", "image/png");
  });
  // Start server
  server.begin();
}

void loop(){

}

Просмотреть исходный код

Вставьте ваши сетевые учётные данные в следующие переменные:

const char* ssid = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_PASSWORD";

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

Загрузка изображений в LittleFS ESP32/ESP8266

Откройте ваш скетч и перейдите в Sketch > Show Sketch Folder. Должна открыться папка, где сохранён ваш скетч.

Arduino IDE Open Sketch Folder для создания папки data

Внутри этой папки создайте новую папку с именем data.

Внутри папки data нужно поместить изображения, которые вы хотите отображать на веб-сервере. В нашем случае у нас следующие изображения.

Изображения, сохранённые в папке data

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

Если вы хотите поэкспериментировать с этими изображениями, вы можете скачать их здесь.

Затем в вашем Arduino IDE загрузите изображения на плату. Нажмите [Ctrl] + [Shift] + [P] в Windows или [Cmd] + [Shift] + [P] в MacOS, чтобы открыть палитру команд. Найдите команду Upload LittleFS to Pico/ESP8266/ESP32 и нажмите на неё.

Если эта опция отсутствует, значит, вы не установили плагин загрузки файловой системы. Ознакомьтесь с этим руководством.

Загрузка LittleFS в Pico ESP8266 ESP32 Arduino IDE

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

Загрузка кода

Далее вы можете загрузить код на вашу плату. Не забудьте выбрать правильную плату и COM-порт в меню Tools.

Также не забудьте указать ваши сетевые учётные данные в следующих переменных:

const char* ssid = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_PASSWORD";

Доступ к веб-серверу

После загрузки кода откройте Serial Monitor с baud rate 115200 и нажмите кнопку RST на ESP. Должен быть выведен IP-адрес (в нашем случае это 192.168.1.71).

Демонстрация отображения изображений на веб-сервере ESP32 или ESP8266

Откройте веб-сервер в любом браузере, и все изображения должны отобразиться.

Демонстрация отображения изображений на веб-сервере ESP32 ESP8266

Как работает код

Продолжайте чтение этого раздела, чтобы узнать, как работает код.

Подключение библиотек

Код начинается с подключения необходимых библиотек. Если вы используете ESP32, подключаются следующие библиотеки:

#include <WiFi.h>
#include <ESPAsyncWebServer.h>

Если вы используете ESP8266, подключите следующие библиотеки:

#include <Arduino.h>
#include <ESP8266WiFi.h>
#include <Hash.h>
#include <ESPAsyncTCP.h>
#include <ESPAsyncWebServer.h>

Сетевые учётные данные

Вставьте ваши сетевые учётные данные в следующие переменные, чтобы ESP мог подключиться к вашей сети:

// Replace with your network credentials
const char* ssid = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_PASSWORD";

Создайте объект AsyncWebServer на порту 80:

AsyncWebServer server(80);

HTML-код для построения веб-сервера сохраняется в переменной index_html. Чтобы включить изображения в HTML-текст, вам нужно использовать тег <img> и указать источник изображения, как показано ниже:

<img src="image_source">

В нашем случае мы отображаем все следующие изображения:

<img src="sun">
<img src="sun-cloud">
<img src="cloud">
<img src="rain">
<img src="storm">
<img src="snow">

Когда браузер читает этот HTML-текст, он делает запрос по /image_source. Например, он сделает запрос по URL /sun. Поэтому нам нужно обработать эти запросы далее.

Подключение к Wi-Fi

В setup() подключитесь к Wi-Fi и выведите IP-адрес ESP:

WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
  delay(1000);
  Serial.println("Connecting to WiFi..");
}

// Print ESP32 Local IP Address
Serial.println(WiFi.localIP());

Обработка запросов

Поскольку это асинхронный веб-сервер, нам нужно отправить HTML-текст при получении запроса на корневой URL следующим образом:

server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
  request->send_P(200, "text/html", index_html);
});

После получения HTML-текста вы будете получать запросы на /image_source. Поэтому вам нужно обработать все эти запросы. Вот пример для одного из изображений:

server.on("/sun", HTTP_GET, [](AsyncWebServerRequest *request){
  request->send(LittleFS, "/sun.png", "image/png");
});

Когда приходит запрос на URL /sun, мы отправляем изображение, которое хранится по пути /sun.png в LittleFS (файловой системе) ESP32/ESP8266, и его тип — image/png.

Наконец, запустите сервер с помощью метода begin().

server.begin();

Вариант #3: Кодирование Base64

В этом разделе показано, как конвертировать изображения в формат base64 для включения их в веб-сервер ESP32/ESP8266. Мы покажем, как отображать изображения в асинхронном веб-сервере и в простом HTTP-сервере.

Конвертируйте ваши изображения в кодировку base64. Перейдите на следующий сайт:

Кодирование изображений в Base64 для тега img src

Перетащите ваши изображения. Вы можете загрузить до 20 изображений одновременно. Для этого примера мы будем использовать следующие шесть изображений.

Иконки погодных изображений для конвертации в Base64

Нажмите кнопку «show code» для каждого загруженного файла изображения:

Инструмент конвертации изображений в Base64

Затем скопируйте данные из первого поля. Это то, что вам нужно использовать в качестве источника в HTML-теге <img src="">.

Копирование данных Base64 изображения

Код — Асинхронный веб-сервер ESP

Следующий код создаёт веб-сервер, который отображает любые изображения на вашей веб-странице. Код работает с ESP32 и ESP8266:

/*********
  Rui Santos & Sara Santos - Random Nerd Tutorials
  Complete project details at https://RandomNerdTutorials.com/display-images-esp32-esp8266-web-server/
*********/

#ifdef ESP32
  #include <WiFi.h>
  #include <ESPAsyncWebServer.h>
#else
  #include <Arduino.h>
  #include <ESP8266WiFi.h>
  #include <Hash.h>
  #include <ESPAsyncTCP.h>
  #include <ESPAsyncWebServer.h>
#endif

// Replace with your network credentials
const char* ssid = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_PASSWORD";

// Create AsyncWebServer object on port 80
AsyncWebServer server(80);

const char index_html[] PROGMEM = R"rawliteral(
<!DOCTYPE HTML><html>
<head>
  <meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
  <h2>ESP Image Web Server</h2>
  <img src="data:image/png;base64,[BASE64_DATA]">
  <img src="data:image/png;base64,[BASE64_DATA]">
  <img src="data:image/png;base64,[BASE64_DATA]">
  <img src="data:image/png;base64,[BASE64_DATA]">
  <img src="data:image/png;base64,[BASE64_DATA]">
  <img src="data:image/png;base64,[BASE64_DATA]">
</body>
</html>)rawliteral";

void setup(){
  // Serial port for debugging purposes
  Serial.begin(115200);

  // Connect to Wi-Fi
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(1000);
    Serial.println("Connecting to WiFi..");
  }

  // Print ESP32 Local IP Address
  Serial.println(WiFi.localIP());

  // Route for root / web page
  server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
    request->send_P(200, "text/html", index_html);
  });

  // Start server
  server.begin();
}

void loop(){

}

Примечание

В коде выше [BASE64_DATA] заменяется на фактические данные base64 ваших изображений. Полный исходный код с данными base64 можно скачать по ссылке ниже.

Просмотреть исходный код

Как работает код

Продолжайте чтение, чтобы узнать, как работает код, или перейдите к разделу «Демонстрация».

Подключение библиотек

Код начинается с подключения необходимых библиотек. Если вы используете ESP32, подключаются следующие библиотеки:

#include <WiFi.h>
#include <ESPAsyncWebServer.h>

Если вы используете ESP8266, подключите следующие библиотеки:

#include <Arduino.h>
#include <ESP8266WiFi.h>
#include <Hash.h>
#include <ESPAsyncTCP.h>
#include <ESPAsyncWebServer.h>

Сетевые учётные данные

Вставьте ваши сетевые учётные данные в следующие переменные, чтобы ESP мог подключиться к вашей сети:

// Replace with your network credentials
const char* ssid = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_PASSWORD";

Создайте объект AsyncWebServer на порту 80:

AsyncWebServer server(80);

Включение изображения

Затем включите ваш HTML-текст в переменную index_html. Именно здесь будут ваши изображения.

Чтобы включить изображения в HTML, используйте тег <img> с атрибутом src, как показано ниже:

<img src="your_image_encoded">

Вы должны заменить your_image_encoded на код, который вы скопировали ранее с сайта кодирования base64. В нашем случае у нас следующее для всех 6 изображений:

<img src="data:image/png;base64,[BASE64_DATA_ДЛЯ_ИЗОБРАЖЕНИЯ_1]">
<img src="data:image/png;base64,[BASE64_DATA_ДЛЯ_ИЗОБРАЖЕНИЯ_2]">
<img src="data:image/png;base64,[BASE64_DATA_ДЛЯ_ИЗОБРАЖЕНИЯ_3]">
<img src="data:image/png;base64,[BASE64_DATA_ДЛЯ_ИЗОБРАЖЕНИЯ_4]">
<img src="data:image/png;base64,[BASE64_DATA_ДЛЯ_ИЗОБРАЖЕНИЯ_5]">
<img src="data:image/png;base64,[BASE64_DATA_ДЛЯ_ИЗОБРАЖЕНИЯ_6]">

Подключение к Wi-Fi

В setup() подключитесь к Wi-Fi и выведите IP-адрес ESP:

WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
  delay(1000);
  Serial.println("Connecting to WiFi..");
}

// Print ESP32 Local IP Address
Serial.println(WiFi.localIP());

Обработка запросов

Поскольку это асинхронный веб-сервер, нам нужно отправить HTML-текст при получении запроса на корневой URL следующим образом:

server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
  request->send_P(200, "text/html", index_html);
});

Запустите сервер с помощью метода begin().

server.begin();

Демонстрация

Загрузите код на вашу плату ESP32 или ESP8266. Не забудьте выбрать правильную плату и COM-порт в меню Tools.

После загрузки кода откройте Serial Monitor с baud rate 115200 и нажмите кнопку RST на ESP. Должен быть выведен IP-адрес (в нашем случае это 192.168.1.71).

Демонстрация отображения изображений на веб-сервере ESP32 или ESP8266

Откройте веб-сервер в любом браузере, и все изображения должны отобразиться.

Демонстрация отображения изображений на веб-сервере ESP32 ESP8266

Простой HTTP веб-сервер ESP32/ESP8266

В этом разделе мы покажем, как отобразить изображение на простом HTTP веб-сервере.

Примечание: для отображения изображений лучше использовать метод с асинхронным веб-сервером (предыдущий пример). У вас могут возникнуть проблемы с этим методом, если вы попытаетесь отобразить много изображений или использовать большие файлы. Однако этот метод хорошо работает, если вы просто хотите отобразить маленькое изображение или иконку.

Следующий код показывает, как отобразить изображение, если вы используете простой HTTP веб-сервер (без библиотеки ESPAsyncWebServer):

/*********
  Rui Santos
  Complete project details at https://RandomNerdTutorials.com
*********/

#ifdef ESP32
  #include <WiFi.h>
#else
  #include <ESP8266WiFi.h>
#endif

// Replace with your network details
const char* ssid = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_PASSWORD";

// Web Server on port 80
WiFiServer server(80);

void setup() {
  Serial.begin(115200);
  Serial.print("Connecting to ");
  Serial.println(ssid);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  // Print local IP address and start web server
  Serial.println("");
  Serial.println("WiFi connected.");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
  server.begin();
}
void loop() {
  // Listenning for new clients
  WiFiClient client = server.available();

  if (client) {
    Serial.println("New client");
    // bolean to locate when the http request ends
    boolean blank_line = true;
    while (client.connected()) {
      if (client.available()) {
        char c = client.read();
        if (c == '\n' && blank_line) {
          client.println("HTTP/1.1 200 OK");
          client.println("Content-Type: text/html");
          client.println("Connection: close");
          client.println();
          client.println("<!DOCTYPE HTML>");
          client.println("<html>");
          client.println("<head><meta name=\"viewport\" content=\"width=device-width, initial-scale=1\"></head>");
          client.println("<body><h2>ESP Image Web Server</h2>");
          client.println("<img src=\"data:image/png;base64,[BASE64_DATA]\">");
          client.println("</body></html>");
          break;
        }
        if (c == '\n') {
          blank_line = true;
        }
        else if (c != '\r') {
          blank_line = false;
        }
      }
    }
    delay(1);
    client.stop();
    Serial.println("Client disconnected.");
  }
}

Примечание

В коде выше [BASE64_DATA] заменяется на фактические данные base64 ваших изображений. Полный исходный код с данными base64 можно скачать по ссылке ниже.

Просмотреть исходный код

Этот код работает как с ESP32, так и с ESP8266. Код использует правильную библиотеку Wi-Fi в зависимости от используемой платы.

Процесс отображения изображения аналогичен: вам нужно включить кодировку base64 изображения в атрибут src тега <img>.

Затем отправьте HTML-текст клиенту с помощью метода client.println() следующим образом:

client.println("<img src=\"data:image/png;base64,[BASE64_DATA]\">");

Мы подробно объяснили работу такого веб-сервера в предыдущих руководствах. Чтобы узнать больше, вы можете прочитать следующие статьи:

После загрузки кода изображения должны отобразиться на вашем веб-сервере.

Отображение встроенных изображений на веб-сервере ESP32 ESP8266 с Arduino IDE

Заключение

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

Мы надеемся, что это руководство было полезным. Вам также может быть полезно использовать изображения из этих примеров в метеостанции ESP для отображения текущего состояния погоды.

Если вы хотите узнать больше об ESP32 или ESP8266, вы можете записаться на наши курсы:

Вы также можете посмотреть наши бесплатные ресурсы:

Спасибо за чтение.


Источник: How to Display Images in ESP32 and ESP8266 Web Server