Redesign to keepsake Memory Frame: config file based named memories with beautiful mobile web dashboard, upload wizard, and delete flow
This commit is contained in:
@@ -1,88 +1,73 @@
|
||||
#include "Display_PNG.h"
|
||||
|
||||
PNG png;
|
||||
File Image_file;
|
||||
static PNG png;
|
||||
static File Image_file;
|
||||
static int16_t xpos = 0;
|
||||
static int16_t ypos = 0;
|
||||
|
||||
uint16_t Image_Count = 0;
|
||||
char Image_Names[100][100];
|
||||
|
||||
int16_t xpos = 0;
|
||||
int16_t ypos = 0;
|
||||
|
||||
void * pngOpen(const char *filePath, int32_t *size) {
|
||||
// ── PNG callbacks ─────────────────────────────────────────────────────────────
|
||||
static void* pngOpen(const char* filePath, int32_t* size) {
|
||||
Image_file = SD_MMC.open(filePath);
|
||||
if (!Image_file) { printf("PNG: failed to open %s\r\n", filePath); return nullptr; }
|
||||
*size = Image_file.size();
|
||||
return &Image_file;
|
||||
}
|
||||
|
||||
void pngClose(void *handle) {
|
||||
static void pngClose(void* handle) {
|
||||
File* fp = (File*)handle;
|
||||
if (fp && *fp) fp->close();
|
||||
}
|
||||
|
||||
int32_t pngRead(PNGFILE *page, uint8_t *buffer, int32_t length) {
|
||||
static int32_t pngRead(PNGFILE* page, uint8_t* buffer, int32_t length) {
|
||||
if (!Image_file) return 0;
|
||||
return Image_file.read(buffer, length);
|
||||
}
|
||||
|
||||
int32_t pngSeek(PNGFILE *page, int32_t position) {
|
||||
static int32_t pngSeek(PNGFILE* page, int32_t position) {
|
||||
if (!Image_file) return 0;
|
||||
return Image_file.seek(position);
|
||||
}
|
||||
|
||||
static uint16_t lineBuffer[MAX_IMAGE_WIDTH];
|
||||
void pngDraw(PNGDRAW *pDraw) {
|
||||
static void pngDraw(PNGDRAW* pDraw) {
|
||||
png.getLineAsRGB565(pDraw, lineBuffer, PNG_RGB565_BIG_ENDIAN, 0xffffffff);
|
||||
uint32_t size = pDraw->iWidth;
|
||||
for (size_t i = 0; i < size; i++) {
|
||||
lineBuffer[i] = __builtin_bswap16(lineBuffer[i]);
|
||||
}
|
||||
LCD_addWindow(xpos, pDraw->y, xpos + pDraw->iWidth - 1, ypos + pDraw->y, lineBuffer);
|
||||
uint32_t w = pDraw->iWidth;
|
||||
for (size_t i = 0; i < w; i++) lineBuffer[i] = __builtin_bswap16(lineBuffer[i]);
|
||||
LCD_addWindow(xpos, pDraw->y, xpos + w - 1, ypos + pDraw->y, lineBuffer);
|
||||
}
|
||||
|
||||
void Search_Images(const char* directory) {
|
||||
Image_Count = Folder_retrieval(directory, ".png", Image_Names, 100);
|
||||
}
|
||||
|
||||
// Fill entire screen with black before drawing a new image
|
||||
// ── Screen fill ───────────────────────────────────────────────────────────────
|
||||
static void clearScreen() {
|
||||
static uint16_t blackLine[MAX_IMAGE_WIDTH];
|
||||
memset(blackLine, 0, sizeof(blackLine));
|
||||
for (int y = 0; y < LCD_HEIGHT; y++) {
|
||||
for (int y = 0; y < LCD_HEIGHT; y++)
|
||||
LCD_addWindow(0, y, LCD_WIDTH - 1, y, blackLine);
|
||||
}
|
||||
}
|
||||
|
||||
void Display_Image_By_Path(const char* filePath) {
|
||||
printf("Displaying image: %s\r\n", filePath);
|
||||
int16_t ret = png.open(filePath, pngOpen, pngClose, pngRead, pngSeek, pngDraw);
|
||||
if (ret == PNG_SUCCESS) {
|
||||
printf("Image dimensions: %d x %d, %d bpp\r\n", png.getWidth(), png.getHeight(), png.getBpp());
|
||||
if (png.getWidth() > MAX_IMAGE_WIDTH) {
|
||||
printf("Image is too wide for line buffer!\r\n");
|
||||
} else {
|
||||
clearScreen(); // Clear leftovers from previous smaller image
|
||||
ret = png.decode(NULL, 0);
|
||||
png.close();
|
||||
}
|
||||
} else {
|
||||
printf("Failed to open PNG image! Error code: %d\r\n", ret);
|
||||
// ── Public API ────────────────────────────────────────────────────────────────
|
||||
void Display_Image_From_SD(const char* fullPath) {
|
||||
printf("PNG: loading %s\r\n", fullPath);
|
||||
int16_t rc = png.open(fullPath, pngOpen, pngClose, pngRead, pngSeek, pngDraw);
|
||||
if (rc != PNG_SUCCESS) {
|
||||
printf("PNG: open failed, rc=%d\r\n", rc);
|
||||
return;
|
||||
}
|
||||
if (png.getWidth() > MAX_IMAGE_WIDTH) {
|
||||
printf("PNG: image too wide (%d px)\r\n", png.getWidth());
|
||||
png.close();
|
||||
return;
|
||||
}
|
||||
clearScreen();
|
||||
png.decode(NULL, 0);
|
||||
png.close();
|
||||
}
|
||||
|
||||
void Display_Image_By_Index(const char* directory, uint16_t index) {
|
||||
if (Image_Count == 0) {
|
||||
Search_Images(directory);
|
||||
}
|
||||
if (Image_Count > 0 && index < Image_Count) {
|
||||
String filePath;
|
||||
if (String(directory) == "/") {
|
||||
filePath = String(directory) + Image_Names[index];
|
||||
} else {
|
||||
filePath = String(directory) + "/" + Image_Names[index];
|
||||
}
|
||||
Display_Image_By_Path(filePath.c_str());
|
||||
} else {
|
||||
printf("Invalid image index: %d (Total images: %d)\r\n", index, Image_Count);
|
||||
void Display_Memory_Photo(int memoryIndex) {
|
||||
if (memoryIndex < 0 || memoryIndex >= g_memoryCount) {
|
||||
printf("PNG: invalid memory index %d\r\n", memoryIndex);
|
||||
return;
|
||||
}
|
||||
char path[120];
|
||||
snprintf(path, sizeof(path), "/photos/%s", g_memories[memoryIndex].photo);
|
||||
Display_Image_From_SD(path);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user