revert(color): saving screenshot to PNG does not work reliably (#7069)

This commit is contained in:
philmoz
2026-02-06 14:14:43 +10:00
committed by GitHub
parent 07c767af2e
commit de5f4eb5dc
2 changed files with 71 additions and 18 deletions
+69 -16
View File
@@ -32,7 +32,11 @@ uint8_t gScale[64] = {
};
#endif
#if defined(COLORLCD) && (defined(STM32H7) || defined(STM32H7RS))
// Uncomment to enable screenshots to be saved as PNG files
// Currently does not work on TX16S Mk3 for unknown reason
// #define ENABLE_PNG_SCREENSHOT
#if defined(ENABLE_PNG_SCREENSHOT) && defined(COLORLCD) && (defined(STM32H7) || defined(STM32H7RS))
#define STB_IMAGE_WRITE_IMPLEMENTATION
#include "stb/stb_image_write.h"
@@ -92,6 +96,32 @@ static const char* _writeScreenshot()
s = strAppendDate(s, true);
strAppend(s, ".png");
// Open output file
FRESULT result = f_open(&fp, file, FA_CREATE_ALWAYS | FA_WRITE);
FILE *fout = fopen(filename, "wb");
if (fout == NULL) {
perror("Error: fopen");
return EXIT_FAILURE;
}
// Initialize Tiny PNG Output
struct TinyPngOut pngout;
enum TinyPngOut_Status status = TinyPngOut_init(&pngout, (uint32_t)WIDTH, (uint32_t)HEIGHT, fout);
if (status != TINYPNGOUT_OK)
return printError(status);
// Write image data
status = TinyPngOut_write(&pngout, PIXELS, (size_t)(WIDTH * HEIGHT));
if (status != TINYPNGOUT_OK)
return printError(status);
// Close output file
if (fclose(fout) != 0) {
perror("Error: fclose");
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
writeResult = nullptr;
// allocate enough for 3 channels
@@ -179,12 +209,6 @@ static const char* _writeScreenshot()
return SDCARD_ERROR(result);
}
result = f_write(&bmpFile, BMP_HEADER, sizeof(BMP_HEADER), &written);
if (result != FR_OK || written != sizeof(BMP_HEADER)) {
f_close(&bmpFile);
return SDCARD_ERROR(result);
}
#if defined(COLORLCD)
lv_img_dsc_t* snapshot = lv_snapshot_take(lv_scr_act(), LV_IMG_CF_TRUE_COLOR);
if (!snapshot) {
@@ -195,22 +219,45 @@ static const char* _writeScreenshot()
auto w = snapshot->header.w;
auto h = snapshot->header.h;
constexpr int BMP_BUF_SIZE = FF_MAX_SS * 4;
static uint8_t _bmp_buf[BMP_BUF_SIZE];
memcpy(_bmp_buf, BMP_HEADER, BMP_HEADERSIZE);
UINT bpos = BMP_HEADERSIZE;
for (int y = h - 1; y >= 0; y--) {
for (uint32_t x = 0; x < w; x++) {
lv_color_t pixel = lv_img_buf_get_px_color(snapshot, x, y, {});
uint32_t dst = (0xFF << 24)
| (rbScale[pixel.ch.red] << 16)
| (gScale[pixel.ch.green] << 8)
| rbScale[pixel.ch.blue];
_bmp_buf[bpos++] = rbScale[pixel.ch.blue];
_bmp_buf[bpos++] = gScale[pixel.ch.green];
result = f_write(&bmpFile, &dst, sizeof(dst), &written);
if (result != FR_OK || written != sizeof(dst)) {
lv_snapshot_free(snapshot);
f_close(&bmpFile);
return SDCARD_ERROR(result);
// Header size is a multiple of 2, sector size is a multiple of 4
// so we will hit end of buffer half way through a pixel
if (bpos == BMP_BUF_SIZE) {
result = f_write(&bmpFile, _bmp_buf, bpos, &written);
if (result != FR_OK || written != bpos) {
lv_snapshot_free(snapshot);
f_close(&bmpFile);
return SDCARD_ERROR(result);
}
bpos = 0;
}
_bmp_buf[bpos++] = rbScale[pixel.ch.red];
_bmp_buf[bpos++] = 0xFF;
}
}
if (bpos > 0) {
result = f_write(&bmpFile, _bmp_buf, bpos, &written);
if (result != FR_OK || written != bpos) {
lv_snapshot_free(snapshot);
f_close(&bmpFile);
return SDCARD_ERROR(result);
}
}
@@ -218,6 +265,12 @@ static const char* _writeScreenshot()
#else // stdlcd
result = f_write(&bmpFile, BMP_HEADER, sizeof(BMP_HEADER), &written);
if (result != FR_OK || written != sizeof(BMP_HEADER)) {
f_close(&bmpFile);
return SDCARD_ERROR(result);
}
#if LCD_W == 128
pixel_t inv = g_eeGeneral.invertLCD ? 0xFF : 0;
#endif
+2 -2
View File
@@ -28,9 +28,9 @@
#include "bitmaps.h"
#include "debug.h"
#if !(defined(STM32H7) || defined(STM32H7RS))
// #if !(defined(STM32H7) || defined(STM32H7RS))
#define STB_IMAGE_WRITE_IMPLEMENTATION
#endif
// #endif
#include "stb/stb_image_write.h"
void convert_RGB565_to_RGB888(uint8_t* dst, const BitmapBuffer* src, coord_t w,