this is the example
https://github.com/Bodmer/TFT_eSPI/blob/master/examples/PNG%20Images/Flash_PNG/Flash_PNG.ino
the panda file is a .h file
// array size is 182750
static const unsigned char panda[] PROGMEM = {
0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52,
0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x01, 0x40, 0x08, 0x06, 0x00, 0x00, 0x00, 0x82, 0xe8, 0xf1,
0x53, 0x00, 0x00, 0x00, 0x01, 0x73, 0x52, 0x47, 0x42, 0x00, 0xae, 0xce, 0x1c, 0xe9, 0x00, 0x00,
0x00, 0x04, 0x67, 0x41, 0x4d, 0x41, 0x00, 0x00, 0xb1, 0x8f, 0x0b, 0xfc, 0x61, 0x05, 0x00, 0x00,
0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x1b, 0xae, 0x00, 0x00, 0x1b, 0xae, 0x01, 0x8c... etc etc
};
and complete sketch is
#include <SD.h>
#include "panda.h"
// Include the PNG decoder library
#include <PNGdec.h>
PNG png; // PNG decoder inatance
#define MAX_IMAGE_WDITH 256 // Adjust for your images
int16_t xpos = 0;
int16_t ypos = 0;
// Include the TFT library https://github.com/Bodmer/TFT_eSPI
#include "SPI.h"
#include <TFT_eSPI.h> // Hardware-specific library
TFT_eSPI tft = TFT_eSPI(); // Invoke custom library
// Functions to access a file on the SD card
File myfile;
const char *filename;
//====================================================================================
// Setup
//====================================================================================
void setup()
{
Serial.begin(115200);
Serial.println("\n\n Using the PNGdec library");
// Set all chip selects high to avoid bus contention during initialisation of each peripheral
digitalWrite(22, HIGH); // Touch controller chip select (if used)
digitalWrite(15, HIGH); // TFT screen chip select
digitalWrite( 5, HIGH); // SD card chips select, must use GPIO 5 (ESP32 SS)
// Initialise the TFT
tft.begin();
tft.fillScreen(TFT_BLACK);
if (!SD.begin()) {
Serial.println("Card Mount Failed");
return;
}
uint8_t cardType = SD.cardType();
if (cardType == CARD_NONE) {
Serial.println("No SD card attached");
return;
}
Serial.print("SD Card Type: ");
if (cardType == CARD_MMC) {
Serial.println("MMC");
} else if (cardType == CARD_SD) {
Serial.println("SDSC");
} else if (cardType == CARD_SDHC) {
Serial.println("SDHC");
} else {
Serial.println("UNKNOWN");
}
uint64_t cardSize = SD.cardSize() / (1024 * 1024);
Serial.printf("SD Card Size: %lluMB\n", cardSize);
File dir = SD.open("/");
while (true) {
File entry = dir.openNextFile();
if (!entry) break;
if (entry.isDirectory() == false) {
const char *name = entry.name();
const int len = strlen(name);
if (len > 3 && strcmp(name + len - 3, "png") == 0) {
///Serial.print("File: ");
//Serial.println(name);
filename = name;
}
// close the file:
entry.close();
Serial.println("close file");
}
}
Serial.println(filename);
String strname = filename;
strname = "/" + strname;
//int16_t rc = png.open(strname.c_str(), myOpen, myClose, myRead, mySeek, pngDraw);
int16_t rc = png.openFLASH((uint8_t *)panda, sizeof(panda), pngDraw);
Serial.println(rc);
if(rc == PNG_INVALID_FILE){
Serial.println("invalid file");
}
if(rc == PNG_SUCCESS) {
Serial.println("success file");
}
if (rc == PNG_SUCCESS) {
tft.startWrite();
Serial.printf("image specs: (%d x %d), %d bpp, pixel type: %d\n", png.getWidth(), png.getHeight(), png.getBpp(), png.getPixelType());
uint32_t dt = millis();
if (png.getWidth() > MAX_IMAGE_WDITH) {
Serial.println("Image too wide for allocated lin buffer!");
}
else {
rc = png.decode(NULL, 0);
png.close();
}
tft.endWrite();
// How long did rendering take...
Serial.print(millis()-dt); Serial.println("ms");
}
Serial.println("\r\nInitialisation done.");
}
//====================================================================================
// Loop
//====================================================================================
void loop()
{
}
void * myOpen(const char *filename, int32_t *size) {
Serial.printf("Attempting to open %s\n", filename);
myfile = SD.open(filename);
if (!myfile) {
Serial.println("Failed to open file");
}
*size = myfile.size();
return &myfile;
}
void myClose(void *handle) {
Serial.println("close");
if (myfile) myfile.close();
}
int32_t myRead(PNGFILE *handle, uint8_t *buffer, int32_t length) {
Serial.println("read");
if (!myfile) return 0;
return myfile.read(buffer, length);
}
int32_t mySeek(PNGFILE *handle, int32_t position) {
Serial.println("seek:"+ position);
if (!myfile)
{
Serial.println("Error seek file");
return 0;
}
return myfile.seek(position);
}
//=========================================v==========================================
// pngDraw
//====================================================================================
// This next function will be called during decoding of the png file to
// render each image line to the TFT. If you use a different TFT library
// you will need to adapt this function to suit.
// Callback function to draw pixels to the display
void pngDraw1(PNGDRAW *pDraw) {
Serial.println("pDraw");
uint16_t usPixels[png.getWidth()];
uint16_t lineBuffer[MAX_IMAGE_WDITH];
png.getLineAsRGB565(pDraw, usPixels, PNG_RGB565_BIG_ENDIAN, 0xffffffff);
tft.pushImage(0, 0 + pDraw->y, pDraw->iWidth, 1, usPixels);
}
void pngDraw(PNGDRAW *pDraw) {
uint16_t lineBuffer[MAX_IMAGE_WDITH];
static uint16_t dmaBuffer[MAX_IMAGE_WDITH]; // static so buffer persists after fn exit
png.getLineAsRGB565(pDraw, lineBuffer, PNG_RGB565_BIG_ENDIAN, 0xffffffff);
tft.pushImageDMA(xpos, ypos + pDraw->y, pDraw->iWidth, 1, lineBuffer, dmaBuffer);
}