Download image from internet to ESP32 and display it out to a TFT display

There is a part of my project where I have to download an image from internet webserver (from a URL), and I have to draw this image to a TFT screen. I use ESP32 as a controller, I have a ILI9488 TFT (using TFT_eSPI lib from Bodmer) display. I'm done with connecting to WiFi, begin a http request, but when I store the data from the http request to a buffer (I guess wrongly) and push this image to the display, I get a unusful bunch of pixels (like I would download wrong data)

void downloadImage(){
  HTTPClient http;
  http.begin("https://people.math.sc.edu/Burkardt/data/bmp/bmp_24.bmp"); //EXAMPLE image from internet
  int httpCode = http.GET();
  int size = http.getSize();
  uint8_t buff[128] PROGMEM = {0};
  if (httpCode == 200) {
    WiFiClient* stream = http.getStreamPtr();
    while(http.connected() && (size > 0 || size == -1)) {
      size_t streamSize = stream->available();

      if (streamSize) {
        int c = stream->readBytes(buff, ((size > sizeof(buff)) ? sizeof(buff) : size));
        tft.pushImage(0,0,200,200,(uint16_t*)buff);
        if (size > 0) {
          size -= c;
        }
      }
      delay(1);
    }
  } else {
    Serial.println("HTTP REQUEST ERROR OCCURED!");
  }
   http.end();

}

The image I get on TFT:

I really appreciate your help, in advance. I need your help so much, I'm stuck with this problem.

You are declaring your buff to be in flash memory and then expecting reading from the stream will somehow do the right thing?

Just declare this as a regular array in RAM and try that.

you are reading in a stream of bytes, but now pushing them to the tft as16bit values. Are you sure the data is in the correct order low byte, high byte or high byte, low byte? This could also be an issue.

Thank you for your quick response! I tried to declare the buffer as a regular array, but that doesn't fixed the problem unfortunately. I realised, that I don't need to convert to uint16_t, so I just write this:

tft.pushImage(0,0,200,200,buff);

I also tried, to use the tft.setSwapBytes(true/false), but that doesn't helped me.
Furthermore, I realised 1 more mistake, that I wrote the tft.pushimage() inside a loop, so I corrected it, with puting it to the end of the function. So my code looks like this:

void downloadImage(){
  HTTPClient http;
  http.begin("https://people.math.sc.edu/Burkardt/data/bmp/bmp_24.bmp"); //EXAMPLE image from internet
  int httpCode = http.GET();
  int size = http.getSize();
  uint8_t buff[128];
  if (httpCode == 200) {
    WiFiClient* stream = http.getStreamPtr();
    while(http.connected() && (size > 0 || size == -1)) {
      size_t streamSize = stream->available();

      if (streamSize) {
        int c = stream->readBytes(buff, ((size > sizeof(buff)) ? sizeof(buff) : size));
        
        if (size > 0) {
          size -= c;
        }
      }
      delay(1);
    }
    tft.pushImage(0,0,200,200,buff);
  } else {
    Serial.println("HTTP REQUEST ERROR OCCURED!");
  }
   http.end();

}

Do you have any suggestions, what should i try?

To write an image to a TFT you should first extract the image data from the bmp, png or whichever format you want to use. Then most likely the image data will need a conversion from rgb888 to rgb 565.

Did you manage to display PNG images on the Internet on a TFT_eSPI display? I am also interested in developing a personal project:

I want to display the picons related to the currently viewed channel on the esp32-2432s028 screen.

Data such as current channel name, current channel EPG, details about current channel EPG and other information, I managed to display them on the screen.

How we extract data from a remote server, and display it on a TFT_eSPI screen. In this case, the server is an AmikoViper 4K satellite receiver running an OpenATV linux image, and the microcontroller with which we extract data is an ESP32-2432s028, which has a 2.8-inch display.
There is no need for physical links between the Set Top Box and the ESP32-2432s028, as the microcontroller connects via the WIFI network and thus reads data from the satellite receiver.

You can follow the detailed evolution of this project, on this discussion forum in Romanian: ESP8266 sau ESP32 pot extrage date din WebIf-ul OpenATV ? - Satelit-Info.com

For display on the TFT display I used the TFT_eSPI library from here: GitHub - Bodmer/TFT_eSPI: Arduino and PlatformIO IDE compatible TFT library optimised for the Raspberry Pi Pico (RP2040), STM32, ESP8266 and ESP32 that supports different driver chips

The settings for the TFT_eSPI library for the ESP32-2432s028 microcontroller are as follows:
-- Replace the file:
-- C:\Users$USER$\Documents\Arduino\libraries\TFT_eSPI
whit this User_setup.h file: ESP32 2432s028 TFT_eSPI library User_Setup.h file - Pastebin.com

The code that I loaded into the microcontroller, contains the examples from here: GitHub - Bodmer/PNG_TEST_ONLY: Work in progress PNG decoder test sketches
on the display part of the image (the icon in this case)

The code loaded in the microcontroller can be greatly improved! It's not a perfect code, but it's the first code that's functional, without any errors, at least I haven't noticed any errors affecting the operation so far.
The code is open source and can be used and modified as you like.

The code loaded in the microcontroller includes 6 files:

I bought the ESP32-2432s028 microcontroller used in this project here: https://www.aliexpress.com/item/1005004502250619.html

Hello I am trying the same type of logic but using atmega 2560. Can you guide me through like how to display image from streaming data

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.