NodeMCU (esp8266) - downloading an image file to SPIFFS

Hey all, I'm trying to download a file(jpg) and store it in SPIFFS to later be used to draw using JPEGdecoder library

SPIFFS is constant, so Node really only needs to download the image the first time it's on.

Just need an efficient way to grab the image from HTTP - Store it in SPIFFS

The code I'm using below (just a part of larger project) - trying to read the JPG line by line and write it line by line to SPIFFS is in-elegant I know. Here for ideas :slight_smile:

Thanks!

#include "FS.h"
#include <ESP8266WiFi.h>
#include <ESP8266WiFiMulti.h>

ESP8266WiFiMulti WiFiMulti;

void setup() {
  Serial.begin(9600);
  //SPIFFS.format();

  // always use this to "mount" the filesystem
  bool result = SPIFFS.begin();
  Serial.println("SPIFFS opened: " + result);

  // this opens the file "test.jpg" in read-mode
  File f = SPIFFS.open("/test.jpg", "r");
  
  if (!f) {
    Serial.println("File doesn't exist yet. Grabbing it");
  WiFi.mode(WIFI_STA);
  WiFiMulti.addAP("SSID", "Password");

  Serial.println();
  Serial.println();
  Serial.print("Wait for WiFi... ");

  while (WiFiMulti.run() != WL_CONNECTED) {
    Serial.print(".");
    delay(500);
  }

  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());

  delay(500);
  
  const uint16_t port = 80;
  const char * host = "13.238.161.58"; // ip or dns



  Serial.print("connecting to ");
  Serial.println(host);

  // Use WiFiClient class to create TCP connections
  WiFiClient client;

  if (!client.connect(host, port)) {
    Serial.println("connection failed");
    Serial.println("wait 5 sec...");
    delay(5000);
    return;
  }

  // This will send the request to the server
  client.println("GET /test.jpg");

  //read back one line from server
  String line = client.readStringUntil('\r');
  //Serial.println(line);
  //SPIFFS.open("/test.jpg", "r");
  f.println(line);

  Serial.println("closing connection");
  client.stop();

  Serial.println("wait 5 sec...");
  delay(5000);
  
  } 
  else {
    // we could open the file
    while(f.available()) {
      //Lets read line by line from the file
      String line = f.readStringUntil('n');
      Serial.println(line);
    }

  }
  f.close();
}

void loop() {
  // nothing to do for now, this is just a simple test

}

Look at the example program File | Examples | ESP8266WebServer | FSBrower. This program implements a Web file browser for the SPIFFS file system.

Try this function:

(I'm copy/pasting from one of my projects, hopefully it'll work)

#include <FS.h>
#include "SPIFFS.h"
#include <HTTPClient.h>

void setup()
{
    Serial.begin(115200);
    if (!SPIFFS.begin(FORMAT_SPIFFS_IF_FAILED)) {
      Serial.println("SPIFFS initialisation failed!");
      while (1) yield(); // Stay here twiddling thumbs waiting
    }

  //downloadAndSaveFile("/birds.png","http://192.168.3.139/downloads/birds.png");
    bitmapDemo();
}

void downloadAndSaveFile(String fileName, String  url){
  
  HTTPClient http;

  Serial.println("[HTTP] begin...\n");
  Serial.println(fileName);
  Serial.println(url);
  http.begin(url);
  
  Serial.printf("[HTTP] GET...\n", url.c_str());
  // start connection and send HTTP header
  int httpCode = http.GET();
  if(httpCode > 0) {
      // HTTP header has been send and Server response header has been handled
      Serial.printf("[HTTP] GET... code: %d\n", httpCode);
      Serial.printf("[FILE] open file for writing %d\n", fileName.c_str());
      
      File file = SPIFFS.open(fileName, FILE_WRITE);

      // file found at server
      if(httpCode == HTTP_CODE_OK) {

          // get lenght of document (is -1 when Server sends no Content-Length header)
          int len = http.getSize();

          // create buffer for read
          uint8_t buff[128] = { 0 };

          // get tcp stream
          WiFiClient * stream = http.getStreamPtr();

          // read all data from server
          while(http.connected() && (len > 0 || len == -1)) {
              // get available data size
              size_t size = stream->available();
              if(size) {
                  // read up to 128 byte
                  int c = stream->readBytes(buff, ((size > sizeof(buff)) ? sizeof(buff) : size));
                  // write it to Serial
                  //Serial.write(buff, c);
                  file.write(buff, c);
                  if(len > 0) {
                      len -= c;
                  }
              }
              delay(1);
          }

          Serial.println();
          Serial.println("[HTTP] connection closed or file end.\n");
          Serial.println("[FILE] closing file\n");
          file.close();
          
      }
      
  }
  http.end();

  
}

You can try to convert the JPEG file to Base64 char Array an Send it over MQTT...!!!
It very simple but doesn't efficient..

  1. read the status from response status line. status 200 is OK
  2. read the headers, parse and store the Content-length header value
  3. headers end with empty line (\r\n). after that copy the bytes of the image to a file. count of bytes was in Content-length header

to copy one byte from client to file use file.write(client.read());

Taking advantage of the subject, how does this code work? You need to download jpg or .raw images to a folder named 'data' as in the Bodmer sketch here: NodeMCU (ESP8266) + ILI9341 TFT + SPIFFS = easy image storage and display - Displays - Arduino Forum
I would very much like to attach several images to Nodemcu's SPIFFS and display in a tft display like slideshow, for example.
If anyone can put it here, I appreciate it.

Dancopy:
Taking advantage of the subject, how does this code work? You need to download jpg or .raw images to a folder named 'data' as in the Bodmer sketch here: NodeMCU (ESP8266) + ILI9341 TFT + SPIFFS = easy image storage and display - Displays - Arduino Forum
I would very much like to attach several images to Nodemcu's SPIFFS and display in a tft display like slideshow, for example.
If anyone can put it here, I appreciate it.

it is a different topic. use IDE spiffs plugin