aboutsummaryrefslogtreecommitdiff
path: root/examples
diff options
context:
space:
mode:
authormrfaptastic <12006953+mrfaptastic@users.noreply.github.com>2020-08-10 21:44:25 +0100
committermrfaptastic <12006953+mrfaptastic@users.noreply.github.com>2020-08-10 21:44:25 +0100
commit1ffce4e60c3f60a7c9662f5b6a5650bed1d16c77 (patch)
treebf85bd6c86f109e2c5f1f2bf60e9d58341a68c18 /examples
parentee186006a3c5dd6dc7e362036a28c239a999ad0e (diff)
New GIF animation example based on AnimatedGIF library for better performance.
Diffstat (limited to 'examples')
-rw-r--r--examples/AnimatedGIF/AnimatedGIF.ino4
-rw-r--r--examples/AnimatedGIFPanel/AnimatedGIFPanel/AnimatedGIFPanel.ino240
-rw-r--r--examples/AnimatedGIFPanel/AnimatedGIFPanel/README.md9
-rw-r--r--examples/AnimatedGIFPanel/AnimatedGIFPanel/data/gifs/ezgif.com-pacmn.gifbin0 -> 44831 bytes
-rw-r--r--examples/AnimatedGIFPanel/AnimatedGIFPanel/data/gifs/loading.io-64x32px.gifbin0 -> 39645 bytes
-rw-r--r--examples/AnimatedGIFPanel/AnimatedGIFPanel/data/gifs/matrix-spin.gifbin0 -> 174779 bytes
-rw-r--r--examples/AnimatedGIFPanel/AnimatedGIFPanel/data/gifs/shock.gifbin0 -> 46806 bytes
7 files changed, 252 insertions, 1 deletions
diff --git a/examples/AnimatedGIF/AnimatedGIF.ino b/examples/AnimatedGIF/AnimatedGIF.ino
index 77dd3ed..a5830d2 100644
--- a/examples/AnimatedGIF/AnimatedGIF.ino
+++ b/examples/AnimatedGIF/AnimatedGIF.ino
@@ -56,7 +56,7 @@ GifDecoder<GIFWidth, GIFHeight, 12> decoder;
int num_files;
void screenClearCallback(void) {
- matrix.fillScreen(matrix.color565(0,0,0));
+ //matrix.fillScreen(matrix.color565(0,0,0));
}
void updateScreenCallback(void) {
@@ -88,6 +88,8 @@ void setup() {
decoder.setFileReadCallback(fileReadCallback);
decoder.setFileReadBlockCallback(fileReadBlockCallback);
+
+
matrix.begin();
// Clear screen
diff --git a/examples/AnimatedGIFPanel/AnimatedGIFPanel/AnimatedGIFPanel.ino b/examples/AnimatedGIFPanel/AnimatedGIFPanel/AnimatedGIFPanel.ino
new file mode 100644
index 0000000..0f08249
--- /dev/null
+++ b/examples/AnimatedGIFPanel/AnimatedGIFPanel/AnimatedGIFPanel.ino
@@ -0,0 +1,240 @@
+// Example sketch which shows how to display a 64x32
+// animated GIF image stored in FLASH memory
+// on a 64x32 LED matrix
+//
+// To display a GIF from memory, a single callback function
+// must be provided - GIFDRAW
+// This function is called after each scan line is decoded
+// and is passed the 8-bit pixels, RGB565 palette and info
+// about how and where to display the line. The palette entries
+// can be in little-endian or big-endian order; this is specified
+// in the begin() method.
+//
+// The AnimatedGIF class doesn't allocate or free any memory, but the
+// instance data occupies about 22.5K of RAM.
+//
+// Credits: https://github.com/bitbank2/AnimatedGIF/tree/master/examples/ESP32_LEDMatrix_I2S
+//
+
+#define FILESYSTEM SPIFFS
+#include <SPIFFS.h>
+#include <AnimatedGIF.h>
+#include <ESP32-RGB64x32MatrixPanel-I2S-DMA.h>
+
+// ----------------------------
+
+RGB64x32MatrixPanel_I2S_DMA dma_display;
+AnimatedGIF gif;
+File f;
+int x_offset, y_offset;
+
+
+
+// Draw a line of image directly on the LED Matrix
+void GIFDraw(GIFDRAW *pDraw)
+{
+ uint8_t *s;
+ uint16_t *d, *usPalette, usTemp[320];
+ int x, y, iWidth;
+
+ iWidth = pDraw->iWidth;
+ if (iWidth > MATRIX_WIDTH)
+ iWidth = MATRIX_WIDTH;
+
+ usPalette = pDraw->pPalette;
+ y = pDraw->iY + pDraw->y; // current line
+
+ s = pDraw->pPixels;
+ if (pDraw->ucDisposalMethod == 2) // restore to background color
+ {
+ for (x=0; x<iWidth; x++)
+ {
+ if (s[x] == pDraw->ucTransparent)
+ s[x] = pDraw->ucBackground;
+ }
+ pDraw->ucHasTransparency = 0;
+ }
+ // Apply the new pixels to the main image
+ if (pDraw->ucHasTransparency) // if transparency used
+ {
+ uint8_t *pEnd, c, ucTransparent = pDraw->ucTransparent;
+ int x, iCount;
+ pEnd = s + pDraw->iWidth;
+ x = 0;
+ iCount = 0; // count non-transparent pixels
+ while(x < pDraw->iWidth)
+ {
+ c = ucTransparent-1;
+ d = usTemp;
+ while (c != ucTransparent && s < pEnd)
+ {
+ c = *s++;
+ if (c == ucTransparent) // done, stop
+ {
+ s--; // back up to treat it like transparent
+ }
+ else // opaque
+ {
+ *d++ = usPalette[c];
+ iCount++;
+ }
+ } // while looking for opaque pixels
+ if (iCount) // any opaque pixels?
+ {
+ for(int xOffset = 0; xOffset < iCount; xOffset++ ){
+ dma_display.drawPixelRGB565(x + xOffset, y, usTemp[xOffset]);
+ }
+ x += iCount;
+ iCount = 0;
+ }
+ // no, look for a run of transparent pixels
+ c = ucTransparent;
+ while (c == ucTransparent && s < pEnd)
+ {
+ c = *s++;
+ if (c == ucTransparent)
+ iCount++;
+ else
+ s--;
+ }
+ if (iCount)
+ {
+ x += iCount; // skip these
+ iCount = 0;
+ }
+ }
+ }
+ else // does not have transparency
+ {
+ s = pDraw->pPixels;
+ // Translate the 8-bit pixels through the RGB565 palette (already byte reversed)
+ for (x=0; x<pDraw->iWidth; x++)
+ {
+ dma_display.drawPixelRGB565(x, y, usPalette[*s++]);
+ }
+ }
+} /* GIFDraw() */
+
+
+void * GIFOpenFile(char *fname, int32_t *pSize)
+{
+ f = FILESYSTEM.open(fname);
+ if (f)
+ {
+ *pSize = f.size();
+ return (void *)&f;
+ }
+ return NULL;
+} /* GIFOpenFile() */
+
+void GIFCloseFile(void *pHandle)
+{
+ File *f = static_cast<File *>(pHandle);
+ if (f != NULL)
+ f->close();
+} /* GIFCloseFile() */
+
+int32_t GIFReadFile(GIFFILE *pFile, uint8_t *pBuf, int32_t iLen)
+{
+ int32_t iBytesRead;
+ iBytesRead = iLen;
+ File *f = static_cast<File *>(pFile->fHandle);
+ // Note: If you read a file all the way to the last byte, seek() stops working
+ if ((pFile->iSize - pFile->iPos) < iLen)
+ iBytesRead = pFile->iSize - pFile->iPos - 1; // <-- ugly work-around
+ if (iBytesRead <= 0)
+ return 0;
+ iBytesRead = (int32_t)f->read(pBuf, iBytesRead);
+ pFile->iPos = f->position();
+ return iBytesRead;
+} /* GIFReadFile() */
+
+int32_t GIFSeekFile(GIFFILE *pFile, int32_t iPosition)
+{
+ int i = micros();
+ File *f = static_cast<File *>(pFile->fHandle);
+ f->seek(iPosition);
+ pFile->iPos = (int32_t)f->position();
+ i = micros() - i;
+// Serial.printf("Seek time = %d us\n", i);
+ return pFile->iPos;
+} /* GIFSeekFile() */
+
+unsigned long start_tick = 0;
+
+void ShowGIF(char *name)
+{
+ start_tick = millis();
+
+ if (gif.open(name, GIFOpenFile, GIFCloseFile, GIFReadFile, GIFSeekFile, GIFDraw))
+ {
+ x_offset = (MATRIX_WIDTH - gif.getCanvasWidth())/2;
+ if (x_offset < 0) x_offset = 0;
+ y_offset = (MATRIX_HEIGHT - gif.getCanvasHeight())/2;
+ if (y_offset < 0) y_offset = 0;
+ Serial.printf("Successfully opened GIF; Canvas size = %d x %d\n", gif.getCanvasWidth(), gif.getCanvasHeight());
+ Serial.flush();
+ while (gif.playFrame(true, NULL))
+ {
+ if ( (millis() - start_tick) > 8000) { // we'll get bored after about 8 seconds of the same looping gif
+ break;
+ }
+ }
+ gif.close();
+ }
+
+} /* ShowGIF() */
+
+
+
+/************************* Arduino Sketch Setup and Loop() *******************************/
+void setup() {
+
+ Serial.begin(115200);
+ Serial.println("Starting AnimatedGIFs Sketch");
+
+ // Start filesystem
+ Serial.println(" * Loading SPIFFS");
+ if(!SPIFFS.begin()){
+ Serial.println("SPIFFS Mount Failed");
+ }
+
+ dma_display.setPanelBrightness(32);
+ dma_display.setMinRefreshRate(200);
+
+ dma_display.begin();
+ dma_display.fillScreen(dma_display.color565(0, 0, 0));
+ gif.begin(LITTLE_ENDIAN_PIXELS);
+
+}
+
+void loop() {
+char *szDir = "/gifs"; // play all GIFs in this directory on the SD card
+char fname[256];
+File root, temp;
+
+ while (1) // run forever
+ {
+ root = FILESYSTEM.open(szDir);
+ if (root)
+ {
+ temp = root.openNextFile();
+ while (temp)
+ {
+ if (!temp.isDirectory()) // play it
+ {
+ strcpy(fname, temp.name());
+
+ Serial.printf("Playing %s\n", temp.name());
+ Serial.flush();
+ ShowGIF((char *)temp.name());
+
+ }
+ temp.close();
+ temp = root.openNextFile();
+ }
+ root.close();
+ } // root
+ delay(4000); // pause before restarting
+ } // while
+}
diff --git a/examples/AnimatedGIFPanel/AnimatedGIFPanel/README.md b/examples/AnimatedGIFPanel/AnimatedGIFPanel/README.md
new file mode 100644
index 0000000..aa55689
--- /dev/null
+++ b/examples/AnimatedGIFPanel/AnimatedGIFPanel/README.md
@@ -0,0 +1,9 @@
+=== Animated GIF Decoding Example ===
+
+==== Prerequisite ====
+1. The excellent 'AnimatedGIF' library by Larry Bank needs to be installed: https://github.com/bitbank2/AnimatedGIF
+
+This is available via the Arduino Library manager, or can be placed in the 'libs' directory with PlatformIO.
+
+2. The files in the 'data' folder are written to the ESP32's SPIFFS file system.
+
diff --git a/examples/AnimatedGIFPanel/AnimatedGIFPanel/data/gifs/ezgif.com-pacmn.gif b/examples/AnimatedGIFPanel/AnimatedGIFPanel/data/gifs/ezgif.com-pacmn.gif
new file mode 100644
index 0000000..0a219a4
--- /dev/null
+++ b/examples/AnimatedGIFPanel/AnimatedGIFPanel/data/gifs/ezgif.com-pacmn.gif
Binary files differ
diff --git a/examples/AnimatedGIFPanel/AnimatedGIFPanel/data/gifs/loading.io-64x32px.gif b/examples/AnimatedGIFPanel/AnimatedGIFPanel/data/gifs/loading.io-64x32px.gif
new file mode 100644
index 0000000..342f8ae
--- /dev/null
+++ b/examples/AnimatedGIFPanel/AnimatedGIFPanel/data/gifs/loading.io-64x32px.gif
Binary files differ
diff --git a/examples/AnimatedGIFPanel/AnimatedGIFPanel/data/gifs/matrix-spin.gif b/examples/AnimatedGIFPanel/AnimatedGIFPanel/data/gifs/matrix-spin.gif
new file mode 100644
index 0000000..7925d68
--- /dev/null
+++ b/examples/AnimatedGIFPanel/AnimatedGIFPanel/data/gifs/matrix-spin.gif
Binary files differ
diff --git a/examples/AnimatedGIFPanel/AnimatedGIFPanel/data/gifs/shock.gif b/examples/AnimatedGIFPanel/AnimatedGIFPanel/data/gifs/shock.gif
new file mode 100644
index 0000000..b07d631
--- /dev/null
+++ b/examples/AnimatedGIFPanel/AnimatedGIFPanel/data/gifs/shock.gif
Binary files differ