Try out LVGL Pro - A complete toolkit to build, test, share, and ship UIs efficiently!
LVGL
Tutorial

Taking Screen Snapshots in LVGL

Learn how to capture LVGL screen snapshots for pixel-level analysis and automated GUI testing using binary file exports and ImageMagick.

Mario Rubio GomezMario Rubio Gomez4 min read

What Are Screen Snapshots?#

Screen snapshots allow you to capture exactly what LVGL is rendering on your display as a binary file. Think of it as a "Print Screen" button for your embedded GUI that saves every pixel to disk.

This tutorial shows you how to implement snapshot capture in your LVGL project. While the specific implementation may need adaptation for your codebase, the core concepts apply universally.

Why Capture Screen Snapshots?#

There are two primary use cases for screen snapshots:

Pixel-level analysis: Opening captured images in tools like GIMP helps you analyze exact colors, measure element positions, and fine-tune your GUI layout. This is invaluable when perfecting themes or debugging visual issues.

Automated GUI testing: By comparing current output against reference images, you can detect unintended visual regressions automatically. This is essential for maintaining GUI quality as your project evolves.

Capturing the Display Buffer#

The first step is to flush the entire display buffer to a binary file. Here's the implementation:

Global Variables#

static FILE* pFileOut;
static BOOL_E bSnapshot;
c

Snapshot Trigger Function#

Create a function to initiate snapshot capture:

/** Flush buffer.
 *
 * Flush buffer into a binary file.
 *
 * @note: data pixel should be formated to uint32_t RGBA. Imagemagick requirements.
 *
 * @param[in] pFileName   Output binary file name.
 *
 */
void DISP_IMPL_flushBuffer (const char_t* pFileName)
{
  pFileOut = fopen(pFileName, "w");
 
  if (pFileOut == NULL) {
    printf(("[Display] error: %s cannot be opened", pFileName));
    return;
  }
 
  bSnapshot = BOOL_TRUE;
  lv_obj_invalidate(lv_scr_act());
  lv_refr_now();                    /* Will call our disp_drv.disp_flush function */
  bSnapshot = BOOL_FALSE;
 
  fclose(pFileOut);
  printf(("[Display] data flushed to %s", pFileName));
}
c

Writing Pixels to File#

Modify your display flush callback to write pixel data when snapshot mode is active:

void APP_DISP_lvgl_flush (const lv_color_t* pData, const DISPLAY_BOUNDS_T* const pPxBounds)
{
  uint32_t data;
  if (bSnapshot == BOOL_TRUE) {
    for (uint32_t i = 0; i < (pPxBounds->dimension.width * pPxBounds->dimension.height); i++) {
      data = DISP_IMPL_lvgl_formatPixel(pData[i]);  /* Function for converting LittlevGL pixel format to RGB888 */
      fwrite(&data,
             sizeof(uint32_t),
             1,
             pFileOut);
    }
  }
}
c

Pixel Format Conversion#

Convert pixels to the required output format. This example converts RGB565 to RGB888 and corrects grayscale colors:

/** Convert lvgl RGB565 pixel to RGB888 pixel
 *
 * @note: convert potential gray colors to true gray color.
 *
 */
static uint32_t DISP_IMPL_lvgl_formatPixel (lv_color_t color){
 
  lv_color32_t data = (lv_color32_t) lv_color_to32(color);
  uint8_t aux;
 
  /* Make potential gray color true gray color */
  if (color.red == color.blue) {
    uint32_t dif = data.green - data.red;
    if (dif <= 8) {
      data.red += dif;
      data.blue += dif;
    }
  }
 
  /* BGR to RGB */
  aux = data.blue;
  data.blue = data.red;
  data.red = aux;
 
  return data.full;
}
c
Adapt to Your Color Depth

The pixel format conversion depends on your LV_COLOR_DEPTH setting. Adjust the DISP_IMPL_lvgl_formatPixel function to match your display configuration.

Converting Binary Files to Images#

Once you've captured the binary data, use ImageMagick to convert it to standard image formats:

#!/bin/bash
# convert_bin_images.bash
OUT_BIN_LIST="${IMAGES_DIR}/*.bin"
for BIN_FILE in $OUT_BIN_LIST
do
  convert -size 320x240 -depth 8 rgba:${BIN_FILE} ${BIN_FILE}.bmp
done
bash

Adjust the -size parameter to match your display resolution.

Automated GUI Testing#

Compare captured snapshots against reference images to detect visual regressions:

#!/bin/bash
#run_test.bash
 
for i in ${BIN_LIST[@]}
do
  diff -q ${IMAGES_DIR_OUT}/$i ${IMAGES_DIR_REF}/$i
  if [ $? != 0 ]; then
    $SCRIPT_DIR/convert_bin_images.bash ${IMAGES_DIR_REF}/$i
    compare ${IMAGES_DIR_OUT}/$i.bmp ${IMAGES_DIR_REF}/$i.bmp -compose src ${IMAGES_DIR_OUT}/diff_$i.png
    TEST_SUITE_OK=0
  fi
done
 
if [ $TEST_SUITE_OK -eq 0 ]; then
  exit 1
fi
bash

When differences are detected, ImageMagick's compare command generates a difference image highlighting exactly where the visual discrepancies occur.

Example Output#

Here are examples showing how snapshot comparison works in practice:

Output snapshot from test run
Current test output
Reference snapshot for comparison
Reference image for comparison
Visual difference highlighting changed pixels
Difference visualization showing where the images diverge

The difference image clearly shows which pixels have changed between the reference and current output, making it easy to identify unintended visual changes or validate intentional updates.

About the author

Mario Rubio Gomez
Mario Rubio Gomez

Community Contributor

Embedded developer and LVGL community contributor focused on display driver development and MicroPython integration.

Meet the people behind the blog

Discover the talented writers sharing their knowledge about LVGL

View Authors

Subscribe to our newsletter to not miss any news about LVGL. We will send maximum of 2 mails per month.

LVGL

LVGL is the most popular free and open source embedded graphics library targeting any MCU, MPU and display type to build beautiful UIs.

We also do services like UI design, implementation and consulting.

© 2026 LVGL. All rights reserved.
YouTubeGitHubLinkedIn