diff --git a/tasmota/xdrv_52_3_berry_lvgl.ino b/tasmota/xdrv_52_3_berry_lvgl.ino index af435851b..9a2973df1 100644 --- a/tasmota/xdrv_52_3_berry_lvgl.ino +++ b/tasmota/xdrv_52_3_berry_lvgl.ino @@ -956,11 +956,53 @@ extern "C" { if (!glue) { be_return_nil(vm); } char fname[32]; - snprintf(fname, sizeof(fname), "/screenshot-%d.raw", Rtc.utc_time); + snprintf(fname, sizeof(fname), "/screenshot-%d.bmp", Rtc.utc_time); File f = dfsp->open(fname, "w"); if (f) { glue->setScreenshotFile(&f); + uint32_t bmp_width = lv_disp_get_hor_res(nullptr); + uint32_t bmp_height = lv_disp_get_ver_res(nullptr); + + // write BMP header + static const uint8_t bmp_sign[] = { 0x42, 0x4d }; // BM = Windows + f.write(bmp_sign, sizeof(bmp_sign)); + size_t bmp_size = bmp_width * bmp_height * LV_COLOR_DEPTH / 8 + 0x44; + f.write((uint8_t*)&bmp_size, sizeof(bmp_size)); + uint32_t zero = 0; + f.write((uint8_t*) &zero, sizeof(zero)); // reserved 4-bytes + uint32_t bmp_offset_to_pixels = 0x44; // TODO + f.write((uint8_t*) &bmp_offset_to_pixels, sizeof(bmp_offset_to_pixels)); + + // DIB Header BITMAPINFOHEADER + size_t bmp_dib_header_size = 52; // BITMAPV2INFOHEADER + f.write((uint8_t*) &bmp_dib_header_size, sizeof(bmp_dib_header_size)); + + f.write((uint8_t*) &bmp_width, sizeof(bmp_width)); + f.write((uint8_t*) &bmp_height, sizeof(bmp_height)); + + // rest of header + // BITMAPV2INFOHEADER = 52 bytes header, 40 bytes sub-header + static const uint8_t bmp_dib_header[] = { + 0x01, 0x00, // planes + 16, 0x00, // bits per pixel = 16 + 0x03, 0x00, 0x00, 0x00, // compression = BI_BITFIELDS uncrompressed + 0x00, 0x00, 0x00, 0x00, // Image size, 0 is valid for BI_RGB (uncompressed) TODO + 0x00, 0x00, 0x00, 0x00, // X pixels per meter + 0x00, 0x00, 0x00, 0x00, // Y pixels per meter + 0x00, 0x00, 0x00, 0x00, // Colors in table + 0x00, 0x00, 0x00, 0x00, // Important color count + + // RGB masks + 0x00, 0xF8, 0x00, 0x00, // Red channel mask + 0xE0, 0x07, 0x00, 0x00, // Green channel mask + 0x1F, 0x00, 0x00, 0x00, // Blue channel mask + + 0x00, 0x00, // Padding to align on 4 bytes boundary + }; + f.write(bmp_dib_header, sizeof(bmp_dib_header)); + // now we can write the pixels array + // redraw screen lv_obj_invalidate(lv_scr_act()); lv_refr_now(lv_disp_get_default());