mirror of
https://github.com/Bodmer/TFT_eSPI.git
synced 2025-07-31 19:24:46 +02:00
Add PNG image render examples
This commit is contained in:
71
examples/PNG Images/Flash_PNG/Flash_PNG.ino
Normal file
71
examples/PNG Images/Flash_PNG/Flash_PNG.ino
Normal file
@@ -0,0 +1,71 @@
|
||||
|
||||
// This example renders a png file that is stored in a FLASH array
|
||||
// using the PNGdec library (available via library manager).
|
||||
|
||||
#include <LittleFS.h>
|
||||
#define FileSys LittleFS
|
||||
|
||||
// Include the PNG decoder library
|
||||
#include <PNGdec.h>
|
||||
#include "panda_png.h" // Image is stored here in an 8 bit array
|
||||
|
||||
PNG png; // PNG decoder inatance
|
||||
|
||||
#define MAX_IMAGE_WDITH 240 // 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
|
||||
|
||||
//====================================================================================
|
||||
// Setup
|
||||
//====================================================================================
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
Serial.println("\n\n Using the PNGdec library");
|
||||
|
||||
// Initialise the TFT
|
||||
tft.begin();
|
||||
tft.fillScreen(TFT_BLACK);
|
||||
|
||||
Serial.println("\r\nInitialisation done.");
|
||||
}
|
||||
|
||||
//====================================================================================
|
||||
// Loop
|
||||
//====================================================================================
|
||||
void loop()
|
||||
{
|
||||
int16_t rc = png.openFLASH((uint8_t *)panda_png, sizeof(panda_png), pngDraw);
|
||||
if (rc == PNG_SUCCESS) {
|
||||
Serial.println("Successfully png file");
|
||||
Serial.printf("image specs: (%d x %d), %d bpp, pixel type: %d\n", png.getWidth(), png.getHeight(), png.getBpp(), png.getPixelType());
|
||||
tft.startWrite();
|
||||
uint32_t dt = millis();
|
||||
rc = png.decode(NULL, 0);
|
||||
Serial.print(millis() - dt); Serial.println("ms");
|
||||
tft.endWrite();
|
||||
// png.close(); // not needed for memory->memory decode
|
||||
}
|
||||
delay(3000);
|
||||
tft.fillScreen(random(0x10000));
|
||||
}
|
||||
|
||||
|
||||
//=========================================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 pngDraw(PNGDRAW *pDraw) {
|
||||
uint16_t lineBuffer[MAX_IMAGE_WDITH];
|
||||
png.getLineAsRGB565(pDraw, lineBuffer, PNG_RGB565_BIG_ENDIAN, 0xffffffff);
|
||||
tft.pushImage(xpos, ypos + pDraw->y, pDraw->iWidth, 1, lineBuffer);
|
||||
}
|
7096
examples/PNG Images/Flash_PNG/panda_png.h
Normal file
7096
examples/PNG Images/Flash_PNG/panda_png.h
Normal file
File diff suppressed because it is too large
Load Diff
99
examples/PNG Images/LittleFS_PNG/LittleFS_PNG.ino
Normal file
99
examples/PNG Images/LittleFS_PNG/LittleFS_PNG.ino
Normal file
@@ -0,0 +1,99 @@
|
||||
|
||||
// This example if for processors with LittleFS capability (e.g. RP2040,
|
||||
// ESP32, ESP8266). It renders a png file that is stored in LittleFS
|
||||
// using the PNGdec library (available via library manager).
|
||||
|
||||
// The test image is in the sketch "data" folder (press Ctrl+K to see it).
|
||||
// You must upload the image to LittleFS using the Arduino IDE Tools Data
|
||||
// Upload menu option (you may need to install extra tools for that).
|
||||
|
||||
// Don't forget to use the Arduino IDE Tools menu to allocate a LittleFS
|
||||
// memory partition before uploading the sketch and data!
|
||||
|
||||
#include <LittleFS.h>
|
||||
#define FileSys LittleFS
|
||||
|
||||
// Include the PNG decoder library
|
||||
#include <PNGdec.h>
|
||||
|
||||
PNG png;
|
||||
#define MAX_IMAGE_WDITH 240 // 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
|
||||
|
||||
//====================================================================================
|
||||
// Setup
|
||||
//====================================================================================
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
Serial.println("\n\n Using the PNGdec library");
|
||||
|
||||
// Initialise FS
|
||||
if (!FileSys.begin()) {
|
||||
Serial.println("LittleFS initialisation failed!");
|
||||
while (1) yield(); // Stay here twiddling thumbs waiting
|
||||
}
|
||||
|
||||
// Initialise the TFT
|
||||
tft.begin();
|
||||
tft.fillScreen(TFT_BLACK);
|
||||
|
||||
Serial.println("\r\nInitialisation done.");
|
||||
}
|
||||
|
||||
//====================================================================================
|
||||
// Loop
|
||||
//====================================================================================
|
||||
void loop()
|
||||
{
|
||||
// Scan LittleFS and load any *.png files
|
||||
File root = LittleFS.open("/", "r");
|
||||
while (File file = root.openNextFile()) {
|
||||
String strname = file.name();
|
||||
strname = "/" + strname;
|
||||
Serial.println(file.name());
|
||||
// If it is not a directory and filename ends in .png then load it
|
||||
if (!file.isDirectory() && strname.endsWith(".png")) {
|
||||
// Pass support callback function names to library
|
||||
int16_t rc = png.open(strname.c_str(), 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_WDITH) {
|
||||
Serial.println("Image too wide for allocated line buffer size!");
|
||||
}
|
||||
else {
|
||||
rc = png.decode(NULL, 0);
|
||||
png.close();
|
||||
}
|
||||
tft.endWrite();
|
||||
// How long did rendering take...
|
||||
Serial.print(millis()-dt); Serial.println("ms");
|
||||
}
|
||||
}
|
||||
delay(3000);
|
||||
tft.fillScreen(random(0x10000));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//=========================================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 pngDraw(PNGDRAW *pDraw) {
|
||||
uint16_t lineBuffer[MAX_IMAGE_WDITH];
|
||||
png.getLineAsRGB565(pDraw, lineBuffer, PNG_RGB565_BIG_ENDIAN, 0xffffffff);
|
||||
tft.pushImage(xpos, ypos + pDraw->y, pDraw->iWidth, 1, lineBuffer);
|
||||
}
|
28
examples/PNG Images/LittleFS_PNG/PNG_FS_Support.ino
Normal file
28
examples/PNG Images/LittleFS_PNG/PNG_FS_Support.ino
Normal file
@@ -0,0 +1,28 @@
|
||||
// Here are the callback functions that the decPNG library
|
||||
// will use to open files, fetch data and close the file.
|
||||
|
||||
File pngfile;
|
||||
|
||||
void * pngOpen(const char *filename, int32_t *size) {
|
||||
Serial.printf("Attempting to open %s\n", filename);
|
||||
pngfile = FileSys.open(filename, "r");
|
||||
*size = pngfile.size();
|
||||
return &pngfile;
|
||||
}
|
||||
|
||||
void pngClose(void *handle) {
|
||||
File pngfile = *((File*)handle);
|
||||
if (pngfile) pngfile.close();
|
||||
}
|
||||
|
||||
int32_t pngRead(PNGFILE *page, uint8_t *buffer, int32_t length) {
|
||||
if (!pngfile) return 0;
|
||||
page = page; // Avoid warning
|
||||
return pngfile.read(buffer, length);
|
||||
}
|
||||
|
||||
int32_t pngSeek(PNGFILE *page, int32_t position) {
|
||||
if (!pngfile) return 0;
|
||||
page = page; // Avoid warning
|
||||
return pngfile.seek(position);
|
||||
}
|
BIN
examples/PNG Images/LittleFS_PNG/data/EagleEye.png
Normal file
BIN
examples/PNG Images/LittleFS_PNG/data/EagleEye.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 35 KiB |
BIN
examples/PNG Images/LittleFS_PNG/data/panda.png
Normal file
BIN
examples/PNG Images/LittleFS_PNG/data/panda.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 178 KiB |
107
examples/PNG Images/LittleFS_PNG_DMA/LittleFS_PNG_DMA.ino
Normal file
107
examples/PNG Images/LittleFS_PNG_DMA/LittleFS_PNG_DMA.ino
Normal file
@@ -0,0 +1,107 @@
|
||||
|
||||
// This example if for processors with LittleFS capability (e.g. RP2040,
|
||||
// ESP32, ESP8266). It renders a png file that is stored in LittleFS
|
||||
// using the PNGdec library (available via library manager).
|
||||
|
||||
// It uses DMA to send image data to the TFT while the decoding takes
|
||||
// place. The processor and display combination must support DMA to
|
||||
// run this sketch! The decode time dominates so DMA is mainly an advantage
|
||||
// for slow display interface speeds.
|
||||
|
||||
// The test image is in the sketch "data" folder (press Ctrl+K to see it).
|
||||
// You must upload the image to LittleFS using the Arduino IDE Tools Data
|
||||
// Upload menu option (you may need to install extra tools for that).
|
||||
|
||||
// Don't forget to use the Arduino IDE Tools menu to allocate a LittleFS
|
||||
// memory partition before uploading the sketch and data!
|
||||
|
||||
#include <LittleFS.h>
|
||||
#define FileSys LittleFS
|
||||
|
||||
// Include the PNG decoder library
|
||||
#include <PNGdec.h>
|
||||
|
||||
PNG png;
|
||||
#define MAX_IMAGE_WDITH 240 // 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
|
||||
|
||||
//====================================================================================
|
||||
// Setup
|
||||
//====================================================================================
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
Serial.println("\n\n Using the PNGdec library");
|
||||
|
||||
// Initialise FS
|
||||
if (!FileSys.begin()) {
|
||||
Serial.println("LittleFS initialisation failed!");
|
||||
while (1) yield(); // Stay here twiddling thumbs waiting
|
||||
}
|
||||
|
||||
// Initialise the TFT
|
||||
tft.begin();
|
||||
tft.fillScreen(TFT_BLACK);
|
||||
tft.initDMA();
|
||||
|
||||
Serial.println("\r\nInitialisation done.");
|
||||
}
|
||||
|
||||
//====================================================================================
|
||||
// Loop
|
||||
//====================================================================================
|
||||
void loop()
|
||||
{
|
||||
// Scan LittleFS and load any *.png files
|
||||
File root = LittleFS.open("/", "r");
|
||||
while (File file = root.openNextFile()) {
|
||||
String strname = file.name();
|
||||
strname = "/" + strname;
|
||||
Serial.println(file.name());
|
||||
// If it is not a directory and filename ends in .png then load it
|
||||
if (!file.isDirectory() && strname.endsWith(".png")) {
|
||||
// Pass support callback function names to library
|
||||
int16_t rc = png.open(strname.c_str(), 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_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");
|
||||
}
|
||||
}
|
||||
delay(3000);
|
||||
tft.fillScreen(random(0x10000));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//=========================================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 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);
|
||||
}
|
28
examples/PNG Images/LittleFS_PNG_DMA/PNG_FS_Support.ino
Normal file
28
examples/PNG Images/LittleFS_PNG_DMA/PNG_FS_Support.ino
Normal file
@@ -0,0 +1,28 @@
|
||||
// Here are the callback functions that the decPNG library
|
||||
// will use to open files, fetch data and close the file.
|
||||
|
||||
File pngfile;
|
||||
|
||||
void * pngOpen(const char *filename, int32_t *size) {
|
||||
Serial.printf("Attempting to open %s\n", filename);
|
||||
pngfile = FileSys.open(filename, "r");
|
||||
*size = pngfile.size();
|
||||
return &pngfile;
|
||||
}
|
||||
|
||||
void pngClose(void *handle) {
|
||||
File pngfile = *((File*)handle);
|
||||
if (pngfile) pngfile.close();
|
||||
}
|
||||
|
||||
int32_t pngRead(PNGFILE *page, uint8_t *buffer, int32_t length) {
|
||||
if (!pngfile) return 0;
|
||||
page = page; // Avoid warning
|
||||
return pngfile.read(buffer, length);
|
||||
}
|
||||
|
||||
int32_t pngSeek(PNGFILE *page, int32_t position) {
|
||||
if (!pngfile) return 0;
|
||||
page = page; // Avoid warning
|
||||
return pngfile.seek(position);
|
||||
}
|
BIN
examples/PNG Images/LittleFS_PNG_DMA/data/EagleEye.png
Normal file
BIN
examples/PNG Images/LittleFS_PNG_DMA/data/EagleEye.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 35 KiB |
BIN
examples/PNG Images/LittleFS_PNG_DMA/data/panda.png
Normal file
BIN
examples/PNG Images/LittleFS_PNG_DMA/data/panda.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 178 KiB |
Reference in New Issue
Block a user