#include "MyPngLib.h" #include PNG _png; TFT_eSPI * _tft; File Myfile; void PngClass::listDir(fs::FS &fs, const char * dirname, uint8_t levels) { Serial.printf("Listing directory: %s\n", dirname); File root = fs.open(dirname); if (!root) { Serial.println("Failed to open directory"); return; } if (!root.isDirectory()) { Serial.println("Not a directory"); return; } File file = root.openNextFile(); while (file) { if (file.isDirectory()) { Serial.print(" DIR : "); Serial.println(file.name()); if (levels) { listDir(fs, file.path(), levels - 1); } } else { Serial.print(file.name()); } file = root.openNextFile(); } } void * PngClass::pngOpen(const char *filename, int32_t *size) { Serial.printf("Attempting to open %s - File Size %d \n", filename, Myfile.size()); if (!Myfile) { Myfile = SD.open(filename, "r"); Serial.printf("Have to open Myfile"); } *size = Myfile.size(); return &Myfile; } void PngClass::pngClose(void *handle) { File Myfile = *((File*)handle); if (Myfile) Myfile.close(); } int32_t PngClass::pngRead(PNGFILE *page, uint8_t *buffer, int32_t length) { if (!Myfile) return 0; page = page; // Avoid warning return Myfile.read(buffer, length); } int32_t PngClass::pngSeek(PNGFILE *page, int32_t position) { if (!Myfile) return 0; page = page; // Avoid warning 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 PngClass::pngDraw(PNGDRAW *pDraw) { uint16_t lineBuffer[MAX_IMAGE_WIDTH]; //static uint16_t dmaBuffer[MAX_IMAGE_WIDTH]; // static so buffer persists after fn exit _png.getLineAsRGB565(pDraw, lineBuffer, PNG_RGB565_BIG_ENDIAN, 0xffffffff); _tft->pushImage(xpos, ypos + pDraw->y, pDraw->iWidth, 1, lineBuffer); } void PngClass::DrawPng( TFT_eSPI tft, fs::FS &fs,const int x,const int y, const char * PngName) { xpos = x; ypos = y; _tft = &tft; Myfile = fs.open(PngName, "r"); int16_t rc = _png.open(PngName, pngOpen, pngClose, pngRead, pngSeek, pngDraw); 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_WIDTH) { Serial.println("Image too wide for allocated lin buffer!"); } else { rc = _png.decode(NULL, 0); Serial.printf("Decode PNG %d", rc); _png.close(); } _tft->endWrite(); // How long did rendering take... Serial.print(millis()-dt); Serial.println("ms"); } } String PngClass::readFile(fs::FS &fs, const char * path) { Serial.printf("Reading file: %s\r\n", path); File file = fs.open(path, "r"); if(!file || file.isDirectory()){ Serial.println("- empty file or failed to open file"); return String(); } Serial.println("- read from file:"); String fileContent; while(file.available()){ fileContent+=String((char)file.read()); } Serial.println(fileContent); return fileContent; }