什么是屏幕快照?#
屏幕快照允许你将 LVGL 在显示器上渲染的内容精确捕获为二进制文件。可以将其视为嵌入式 GUI 的"打印屏幕"按钮,将每个像素保存到磁盘。
本教程向你展示如何在 LVGL 项目中实现快照捕获。虽然具体实现可能需要适应你的代码库,但核心概念普遍适用。
为什么捕获屏幕快照?#
屏幕快照有两个主要用例:
**像素级分析:**在 GIMP 等工具中打开捕获的图像有助于你分析精确的颜色、测量元素位置并微调 GUI 布局。这在完善主题或调试视觉问题时非常宝贵。
**自动化 GUI 测试:**通过将当前输出与参考图像进行比较,你可以自动检测意外的视觉回归。这对于在项目演进时保持 GUI 质量至关重要。
捕获显示缓冲区#
第一步是将整个显示缓冲区 flush 到二进制文件。以下是实现:
全局变量#
static FILE* pFileOut;
static BOOL_E bSnapshot;c快照触发函数#
创建一个函数来启动快照捕获:
/** Flush 缓冲区。
*
* 将缓冲区 flush 到二进制文件。
*
* @note: 数据像素应格式化为 uint32_t RGBA。Imagemagick 要求。
*
* @param[in] pFileName 输出二进制文件名。
*
*/
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(); /* 将调用我们的 disp_drv.disp_flush 函数 */
bSnapshot = BOOL_FALSE;
fclose(pFileOut);
printf(("[Display] data flushed to %s", pFileName));
}c将像素写入文件#
修改显示 flush 回调函数,在快照模式激活时写入像素数据:
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]); /* 将 LittlevGL 像素格式转换为 RGB888 的函数 */
fwrite(&data,
sizeof(uint32_t),
1,
pFileOut);
}
}
}c像素格式转换#
将像素转换为所需的输出格式。此示例将 RGB565 转换为 RGB888 并校正灰度颜色:
/** 将 lvgl RGB565 像素转换为 RGB888 像素
*
* @note: 将潜在的灰色转换为真正的灰色。
*
*/
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;
/* 将潜在的灰色转换为真正的灰色 */
if (color.red == color.blue) {
uint32_t dif = data.green - data.red;
if (dif <= 8) {
data.red += dif;
data.blue += dif;
}
}
/* BGR 转 RGB */
aux = data.blue;
data.blue = data.red;
data.red = aux;
return data.full;
}c像素格式转换取决于你的 LV_COLOR_DEPTH 设置。调整 DISP_IMPL_lvgl_formatPixel 函数以匹配你的显示配置。
将二进制文件转换为图像#
捕获二进制数据后,使用 ImageMagick 将其转换为标准图像格式:
#!/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
donebash调整 -size 参数以匹配你的显示分辨率。
自动化 GUI 测试#
将捕获的快照与参考图像进行比较以检测视觉回归:
#!/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
fibash当检测到差异时,ImageMagick 的 compare 命令会生成一个差异图像,突出显示视觉差异发生的确切位置。
示例输出#
以下是展示快照比较在实践中如何工作的示例:



差异图像清楚地显示了参考和当前输出之间哪些像素发生了变化,使得很容易识别意外的视觉变化或验证有意的更新。
