• Уважаемые посетители сайта esp8266.ru!
    Мы отказались от размещения рекламы на страницах форума для большего комфорта пользователей.
    Вы можете оказать посильную поддержку администрации форума. Данные средства пойдут на оплату услуг облачных провайдеров для сайта esp8266.ru
  • Система автоматизации с открытым исходным кодом на базе esp8266/esp32 микроконтроллеров и приложения IoT Manager. Наша группа в Telegram

Нужна помощь Хранение картинки в ESP для cnhfybws web servera

Tantra

New member
Здравствуйте уважаемые форумчане.
Видит Бог, искал, но не нашел, так что прошу сильно не пинать.
Вопрос такой. Как хранить картинку в ESP так, что бы можно было ее вставить в HTML страничку, когда ESP работает в режиме web servera?
т.е. <img src="? картинка ?">
Варианты - держать картинку на web ресурсе не подходят, нужно хранить ее именно на ESP .
И второе, работу с файловой системой хотелось бы избежать.
 

Сергей_Ф

Moderator
Команда форума
@Tantra либо крестик снять, либо трусы надеть. Либо файл в файловой системе, либо base64 - вроде ничего другого не придумали.
 

Алексей.

Active member
И второе, работу с файловой системой хотелось бы избежать.
храните в массиве байтов, используйте директивы progmem,
картинки (которые в прошивке в ввиде массива байтов) отправляю броузеру, не раздувая их в base64.
в теге img как обычно устанавливаем атрибут src и броузер методом get запрашивает картинку, я в заголовке ответа устанавливаю соответствующий тип и отгружаю контент без каких либо преобразований на есп.
 

Алексей.

Active member
andrik_zp,
Пример получения данных погоды с openweathermap, там статика от веб морды уже конвертнутая в код в файле memcontent.h чем отправляется смотрим WebIface.cpp, там где обработчик server.onNotFound, ну а преобразование статики в memcontent.h на лету - скрипт prebuild.

п.с.
Собирал на ардуине 1.8.5 с пакетом "esp8266 by ESP8266 Community" версия 2.4.1
Проверял на ноде мсу и есп-01, броузер хром фф эдж.
 

Сергей_Ф

Moderator
Команда форума
@Алексей. Вы на каждую картинку обработчик запроса вешаете или как то изящнее вопрос множества картинок решаете? Из приведенного примера не понял.
 

Алексей.

Active member
Сергей_Ф,
Всё проще, точнее совсем просто.
Перед билдом я скриптом конвертирую файлы в си-шный код, если есть смысл жать, то и пережимаю gzip-ом
в результате получаю кучу массивов байтов и массив описателей
Код:
static unsigned char _index_html[] PROGMEM = {..}
static unsigned char _404_html[] PROGMEM = {..}
static unsigned char _favicon_ico[] PROGMEM = {..}
static unsigned char _jquery_2_2_4_min_js[] PROGMEM = {..}
static unsigned char _bootstrap_min_js[] PROGMEM = {..}
static unsigned char _blank_png[] PROGMEM = {..}
static unsigned char _01d_png[] PROGMEM = {..}
static unsigned char _02d_png[] PROGMEM = {..}

struct content_info {char* uri; char* dataType; char* content; size_t size; int gzip;};
static struct content_info _ci[8] = {
  {"/index.html", "text/html", (char*)_index_html, sizeof(_index_html), 1},
  {"/404.html", "text/html", (char*)_404_html, sizeof(_404_html), 0},
  {"/favicon.ico", "image/x-icon", (char*)_favicon_ico, sizeof(_favicon_ico), 0},
  {"/jquery-2.2.4.min.js", "application/javascript", (char*)_jquery_2_2_4_min_js, sizeof(_jquery_2_2_4_min_js), 1},
  {"/bootstrap.min.js", "application/javascript", (char*)_bootstrap_min_js, sizeof(_bootstrap_min_js), 1},
  {"/blank.png", "image/x-icon", (char*)_blank_png, sizeof(_blank_png), 0},
  {"/01d.png", "image/x-icon", (char*)_01d_png, sizeof(_01d_png), 1},
  {"/02d.png", "image/x-icon", (char*)_02d_png, sizeof(_02d_png), 1}
};
Нулевой элемент - корневой контент, первый элемент - контент возвращаемый для кода 404, всё остальное - контент который может быть запрошен со страниц.
В обработчике server.onNotFound если запрошен корень - возвращаем в контенте _ci[0].content длиной _ci[0].size
иначе ищем запрошенный ресурс в _ci
Код:
for (n = 0; n < sizeof(_ci) / sizeof(_ci[0]) && i == 0; n++) {
  if (this->server.uri().endsWith(_ci[n].uri)) {
    i = &_ci[n];
  }
}
если не нашли - возвращаем в контенте _ci[1].content длиной _ci[1].size
ну а если нашли то возвращаем то что найдено :)
 

Сергей_Ф

Moderator
Команда форума
@Алексей. фактически, сделали аналог простейшей файловой системы с фиксированным набором файлов :)

честно говоря, не понял условия [inline]n < sizeof(_ci) / sizeof(_ci[0])[/inline]
получается вы сравниваете индекс с размером структуры, деленным на размер нулевого элемента ? Зачем?
вроде надо сравнивать с конечным индексом[inline] len(_ci)[/inline], нет?
И как вы выходите из цикла, когда элемент найден? Или обработку внутри него делаете?​
 
Последнее редактирование:

Алексей.

Active member
Сергей_Ф,
Пока загрузишь на этот spiffs сотню кило, заснуть можно, а тут всё в памяти уже.
Именно скорость загрузки была причиной переноса файлов в код.
 

Сергей_Ф

Moderator
Команда форума
Сергей_Ф,
Пока загрузишь на этот spiffs сотню кило, заснуть можно, а тут всё в памяти уже.
Именно скорость загрузки была причиной переноса файлов в код.
это точно.
Вот бы ещё это всё оформить библиотекой - цены бы не было.
я там выше вопросы накидал, если не сложно - объясните чайнику.
 

Алексей.

Active member
Вот бы ещё это всё оформить библиотекой - цены бы не было.
Библиотека для трех строчек кода? Излишество.
Большую часть времени заняло подключение своего скрипта к "Скетч->Проверить/Компилировать" ардуино иде.
Документации мало, такое впечатление, что никому это не интересно.
 

Сергей_Ф

Moderator
Команда форума
Библиотека для трех строчек кода? Излишество.
позвольте возразить. Во-первых, "чайникам" труднее сделать ошибку, во-вторых, можно будет оперативно сделать добавление очередного элемента для загрузки, типа [inline]progmem_fs.add("/my_pic.png", _my_pic_png, GZIP_ON)[/inline]
 

Алексей.

Active member
Про добавлять тут я немножко не понял, лежат файлы себе в папочке, нажали кнопку "Проверить/Компилировать" - они уже в прошивке, в progmem (области данных если хотите), spiffs тут совсем ни причем. Куда добавлять то? В прошивку по живому?
Если нужна супер оперативность то проще вынести файлы связанные с http в отдельную папку и поправить скрипт, чтоб всю эту помойку конвертировал в код.

И если уж говорить об установке библиотек, подскажите как в процессе установки, определить версию пакета "esp8266 by ESP8266 Community" и запустить установочный скрипт который обработает platform.local.txt если он создан или создаст его.

П.С.
Забыл про версию смой ide, её тоже нужно знать в процессе установки.
 
Последнее редактирование:

Сергей_Ф

Moderator
Команда форума
Добавлять не файлы, а обработчик этого файла в код. Файлы, естественно надо будет готовить вашим скриптом, как и раньше.
Просто перенесем формирование структуры с данными в библиотеку и немного упростим добавление элементов.
Конечно, никто вас не заставляет делать библиотеку, просто высказываю мысли почему так будет удобнее на мой взгляд.
Если нужна супер оперативность то проще вынести файлы связанные с http в отдельную папку и поправить скрипт, чтоб всю эту помойку конвертировал в код.
Хм. Тоже вариант.

По поводу установки библиотек не подскажу, не знаю.
Вы наверное не заметили пару вопросов, если не трудно поясните
честно говоря, не понял условия n < sizeof(_ci) / sizeof(_ci[0])
получается вы сравниваете индекс с размером структуры, деленным на размер нулевого элемента ? Зачем?
вроде надо сравнивать с длинной массива len(_ci), нет?
И как вы выходите из цикла, когда элемент найден? Или обработку внутри него делаете?
 
Последнее редактирование:

Алексей.

Active member
Сергей_Ф, Прощу прощения, упустил
честно говоря, не понял условия n < sizeof(_ci) / sizeof(_ci[0])
получается вы сравниваете индекс с размером структуры, деленным на размер нулевого элемента ? Зачем?
сравниваю n с количеством элементов массива структур
например структура содержит два указателя void*, на 32-х битной архитектуре размер структуры равен 8 (опустим всякие прагма-паки и т.п.), размер массива структур предположим 256 байт, рассчитаем количество элементов в массиве 256 / 8 = 32

И как вы выходите из цикла, когда элемент найден? Или обработку внутри него делаете?
Перед циклом потерялся
struct content_info* i = 0;
for (n = 0; n < sizeof(_ci) / sizeof(_ci[0]) && i == 0; n++) {
если нашли ресурс - прекращаем цикл

По поводу установки библиотек не подскажу, не знаю.
И я не знаю, получается давайте сделаем то, пока не знаю что. Вернее не знаю как.
 

Сергей_Ф

Moderator
Команда форума
сравниваю n с количеством элементов массива структур
понял, но всё же проще будет[inline] len(_cli)[/inline] или, как у вас, но корректнее/нагляднее [inline]sizeof(_ci) / sizeof(content_info)[/inline]. Если не ошибаюсь, компилятор в этом случае даже сделает предварительные вычисления и подставит в сравнение уже константу.

Перед циклом потерялся
struct content_info* i = 0;
теперь понял :)
 

Сергей_Ф

Moderator
Команда форума
подскажите как в процессе установки, определить версию пакета "esp8266 by ESP8266 Community"
версию смой ide, её тоже нужно знать в процессе установки
а точно нужно знать в процессе установки? Вроде обычно это возлагается на препроцессор при компиляции?
 

Алексей.

Active member
а точно нужно знать в процессе установки? Вроде обычно это возлагается на препроцессор при компиляции?
Какой препроцессор?
Если вы знаете как при выполнении "Проверить/Компилировать" выполнить скрипт (или какое то приложение) передав ему путь к проекту (к директории со скетчем) и не плохо ещё путь ко временной директории которую создает ide, подскажите как?
Основная задача - преобразовать статику в код, а обработка этого кода умещается в несколько строк.
Мне как раз и нужно знать при установки библиотек, куда сохранять platform.local.txt
Писать инструкцию - пойдите туда, скопируйте то, сделайте исполняемым это и т.д. - не прокатит. Установка должна быть исчерпывающей, чтоб вопросов не возникало.
 
Сверху Снизу