@jojo this is my full snapshot code from the project file that is working for me:
#include "lvgl.h"
#include "SdFat.h"
#include "Arduino.h"
#include "screenshot.h"
SdFs sd;
FsFile file;
// Use Teensy SDIO
#define SD_CONFIG SdioConfig(FIFO_SDIO)
#define LOG_FILE_SIZE (480*320*3) // 480px * 320px * 3bytes per pixle
DMAMEM uint8_t img_buffer[LOG_FILE_SIZE]; //Buffer in RAM2 to place the snapshot
lv_img_dsc_t snapshot_img; //
struct bmp_header_t
{
uint32_t bfSize;
uint32_t bfReserved;
uint32_t bfOffBits;
uint32_t biSize;
int32_t biWidth;
int32_t biHeight;
uint16_t biPlanes;
uint16_t biBitCount;
uint32_t biCompression;
uint32_t biSizeImage;
int32_t biXPelsPerMeter;
int32_t biYPelsPerMeter;
uint32_t biClrUsed;
uint32_t biClrImportant;
uint32_t bdMask[3]; // RGB
};
static void gui_get_bitmap_header(uint8_t* buffer, size_t bufsize)
{
lv_obj_t * scr = lv_disp_get_scr_act(NULL);
lv_coord_t width = lv_obj_get_width(scr);
lv_coord_t height = lv_obj_get_height(scr);
const char* bm = "BM";
memcpy(buffer, bm, strlen(bm));
buffer += strlen(bm);
// Bitmap file header
bmp_header_t* bmp = (bmp_header_t*)buffer;
bmp->bfSize = (uint32_t)(width * height * LV_COLOR_DEPTH / 8);
bmp->bfReserved = 0;
bmp->bfOffBits = bufsize;
// Bitmap information header
bmp->biSize = 40;
bmp->biWidth = width;
bmp->biHeight = -height;
bmp->biPlanes = 1;
bmp->biBitCount = LV_COLOR_DEPTH;
bmp->biCompression = 3; // BI_BITFIELDS
bmp->biSizeImage = bmp->bfSize;
bmp->biXPelsPerMeter = 2836;
bmp->biYPelsPerMeter = 2836;
bmp->biClrUsed = 0; // zero defaults to 2^n
bmp->biClrImportant = 0;
// BI_BITFIELDS
bmp->bdMask[0] = 0xF800; // Red bitmask : 1111 1000 | 0000 0000
bmp->bdMask[1] = 0x07E0; // Green bitmask: 0000 0111 | 1110 0000
bmp->bdMask[2] = 0x001F; // Blue bitmask : 0000 0000 | 0001 1111
}
void takeScreenshot(lv_obj_t * screenshot, const char* fileName){
arm_dcache_flush((uint8_t*)img_buffer, sizeof(img_buffer)); // always flush cache after writing to DMAMEM variable that will be accessed by DMA
lv_res_t snap = lv_snapshot_take_to_buf(screenshot, LV_IMG_CF_TRUE_COLOR_ALPHA, &snapshot_img, &img_buffer, sizeof(img_buffer));
if (snap == LV_RES_INV){
//Serial.println("Snapshot failed");
}
else{
//Serial.println("Snapshot Success");
uint8_t header[sizeof(bmp_header_t) + 2];
//Serial.println("Starting to build header");
gui_get_bitmap_header(header, sizeof(header));
//Serial.println("Finished building header");
// Initialize the SD.
if (!sd.begin(SD_CONFIG)) {
sd.initErrorHalt(&Serial);
}
// Open or create file - truncate existing file.
if (!file.open(fileName, O_RDWR | O_CREAT | O_TRUNC)) {
//Serial.println("open failed\n");
return;
}
// File must be pre-allocated to avoid huge
// delays searching for free clusters.
if (!file.preAllocate((480*320*2)+sizeof(header))) {
//Serial.println("preAllocate failed\n");
file.close();
return;
}
//Serial.println("Start write headers to SD");
file.write(header, sizeof(header));
//Serial.println("Finish write headers to SD, and start write image to SD");
for(uint32_t i=0; i<LOG_FILE_SIZE;i+=3){
file.write(img_buffer[i]);
file.write(img_buffer[i+1]);
}
//Serial.println("Finished writing image data to SD");
file.close();
//Serial.println("Snapshot saved to SD");
}
}