Как сделать WebClient.write() изображением, хранящимся в строке?
Мое приложение работает на ESP32-CAM. Он делает снимки и хранит их для ШПИОНОВ. Периодически SPIFFS проверяется и если изображения найдены: 1 - Изображение сохраняется на FTP-сервере 2 - Изображение передается в веб-сервис, который возвращает некоторую информацию об изображении 3 - Значения сохраняются в MySQL 4 - Изображение удаляется из SPIFFS
Чтобы прочитать изображение из SPIFFS, я использую следующий фрагмент кода:
String imageName = file.name();
imageBuffer = "";
while (file.available()){
imageBuffer += char(file.read());
}
FTP-передача отлично работает со следующей командой:
ftp.WriteData((uint8_t*)imageBuffer.c_str(),imageBuffer.length());
Сервис, на который отправляется изображение для анализа, работает нормально, если я использую команду:
webClient.write(fb->buf,fb->len);
Но поскольку он не может быть использован в текущей реализации моего проекта, я пытаюсь работать с:
webClient.write((uint8_t*) imageBuffer.c_str(), imageBuffer.length());
Я не получаю никаких ошибок в ответ, но это просто не работает, и веб-сервис в пункте назначения ничего не возвращает.
Что я делаю не так?
@Paulo Borges, 👍1
Обсуждение2 ответа
Не следует использовать строку
для хранения двоичных данных.
Вместо этого выделите себе массив uint8_t
нужного размера.
uint8_t *imageData;
size_t len = file.size();
imageData = alloca(len);
file.readBytes(imageData, len);
webClient.write(imageData, len);
С учетом сказанного, не зная, что делает остальная часть вашей программы, я могу только предположить, что вы просто взрываете необработанные данные на веб-сервере и надеетесь, что они застрянут. Это не то, как работает веб-передача данных. Вы должны правильно создать страницу загрузки в виде многосоставных данных mime-формы. Прочтите это для получения дополнительной информации
Привет, спасибо, с одной стороны, я отправляю его в библиотеку FTP и предполагаю, что он будет обрабатывать поток. Отправка в веб-службу осуществляется по протоколу HTTP, поэтому я не знаю,но когда я использую WebClient.write(fb->buf, fb - >>len); это работает, поэтому я предполагаю, что он обрабатывает около 24 тыс. байт изображения. Что ты предлагаешь мне делать? Спасибо, @Paulo Borges
Хорошо, я получил его работать следующим образом:
Больше не передавая двоичный файл, передавая имя файла, так что функция FTPPost будет делать свое собственное чтение файла на SPIFFS и будет публиковать в 256 байтах. Та же стратегия работает с HTTP post на веб-сервис.
File picFile = SPIFFS.open(fileName,FILE_READ);
const size_t bufferSize = 256;
uint8_t buffer[bufferSize];
while (picFile.available()) {
size_t n = picFile.readBytes((char*) buffer, bufferSize);
if (n != 0) {
ftp.WriteData(buffer, n);
} else {
Serial.println(F("Buffer was empty"));
break;
}
}
picFile.close();
- Веб-страница с использованием Bluetooth?
- Как получить ответ HTTP_POST?
- Как получить HTTPS на Arduino?
- esp32, platformio A fatal error occurred: Packet content transfer stopped (received 8 bytes) *** [upload] Error 2
- Как выбрать альтернативные контакты I2C на ESP32?
- Драйверы для чипа последовательного порта CH9102X
- Как преобразовать форматированный оператор print в строковую переменную?
- ESP32 - "Детектор Браунаута был активирован" при запуске Wi-Fi
То, что вы делаете, - это рассматриваете двоичные данные как текст. Как только вы получите 0 байт, строка будет усечена., @Majenko
Ваш `WebClient.write () " выглядит нормально, но как вы оформляете эти необработанные данные? См. [Как работает загрузка файлов HTTP?](https://stackoverflow.com/questions/8659808)., @Edgar Bonet
Короткие знания о том, как обрабатывать такого рода данные. "обрамление необработанных данных"? Что это значит?, @Paulo Borges
@Majenko: Объект "String" не усекает первое значение NUL: он сохраняет все байты, которые вы нажимаете с помощью"+=", а метод "length ()" возвращает общее количество байтов, включая встроенные значения NUL., @Edgar Bonet
Краткий ответ: вы не можете хранить необработанные данные изображения в строке., @Majenko
"То, что вы делаете, - это обрабатываете двоичные данные как текст" в результате поиска в Интернете. Как это работало с FTP, я попробовал тот же вид или команду с WebClient, но не получилось. Честно говоря, я действительно не понимаю, что я делаю на этом двоичном уровне. Поиск в Интернете и попытка понять, что работает., @Paulo Borges
@EdgarBonet Я ожидал бы, что в итоге получится строка, в которой нет нулей, так как добавление НУЛЯ в конец строки не будет иметь никакого эффекта., @Majenko
“обрамление” - это материал, который вы помещаете вокруг данных. Смотрите ссылку, которую я предоставил. @Majenko: да, можно., @Edgar Bonet
Я хотел бы понять, почему он работает с FTP, но не с WebClient, @Paulo Borges
Мое плохое понимание говорит мне, что что-то связано с пробелами и нулями, но я не знаю, как это уладить., @Paulo Borges
@EdgarBonet Внутренне String::concat() использует strcpy(). Следовательно, он будет копировать все, что угодно, вплоть до первого НУЛЯ, заменяя любой конечный НУЛЬ, который уже есть., @Majenko
@Majenko: попробуй это! Я сделал., @Edgar Bonet
Я попробую это сделать. Спасибо, @Paulo Borges
@EdgarBonet, я бы предпочел не делать этого, спасибо. Я держусь *ну* подальше от Веревки и всего, что с ней связано. Никогда не используйте строку для *чего-либо*. Мало того, что это вообще плохая идея, вы просто не можете доверять тому, что она делает. И независимо от этого: хранение необработанных двоичных данных в строке вызывает проблемы., @Majenko