陈拓 2022/12/07-2022/12/10
1. 概述
在《ESP32 ESP-IDF LVGL8.3.3移植(ST7735)》
ESP32 ESP-IDF LVGL8.3.3移植_晨之清风的博客-CSDN博客ESP32 ESP-IDF LVGL8.3.3移植。https://blog.csdn.net/chentuo2000/article/details/128269394?spm=1001.2014.3001.5502一文中,我们遇到了LVGL显示额颜色问题,本文给出了一种解决方法,修正widget的颜色,供参考。不同版本有差异,其他版本可参照本文的方法进行颜色校正。
1. 小部件(widget)的颜色
在LVGL中,用户界面的基本构建单元是小部件(widget)。例如,按钮,标签,图像,列表,图表或文本区域等。
- widget的默认颜色在主题theme中定义
Theme的默认配置选项是:A simple, impressive and very complete theme
对应~/esp442/esp32_lvgl833/sdkconfig中的:
CONFIG_LV_USE_THEME_DEFAULT=y
在程序中是这样判断:
#if LV_USE_THEME_DEFAULT
下面看符合条件的相关代码。
- 默认主题的初始化
在
/home/ct/esp442/esp32_lvgl833/components/lvgl/src/extra/themes/default/lv_theme_default.h
中有默认theme的初始化函数lv_theme_default_init的声明:
/**
* Initialize the theme
* @param color_primary the primary color of the theme
* @param color_secondary the secondary color for the theme
* @param font pointer to a font to use.
* @return a pointer to reference this theme later
*/
lv_theme_t * lv_theme_default_init(lv_disp_t * disp, lv_color_t color_primary, lv_color_t color_secondary, bool dark,
const lv_font_t * font);
color_primary是主题的基本色,color_secondary主题的次要颜色。
在
~/esp442/esp32_lvgl833/components/lvgl/demos/widgets/lv_demo_widgets.c
中有对lv_theme_default_init的调用:
#if LV_USE_THEME_DEFAULT
lv_theme_default_init(NULL, lv_palette_main(LV_PALETTE_BLUE), lv_palette_main(LV_PALETTE_RED), LV_THEME_DEFAULT_DARK,
font_normal);
#endif
- 默认颜色预定义
在lv_theme_default_init中的lv_palette_main函数在
~/esp442/esp32_lvgl833/components/lvgl/src/misc/lv_color.h
中声明为预定义的颜色:
/**********************
* PREDEFINED COLORS
**********************/
/*Source: https://vuetifyjs.com/en/styles/colors/#material-colors*/
lv_color_t lv_palette_main(lv_palette_t p);
static inline lv_color_t lv_color_white(void)
{
return lv_color_make(0xff, 0xff, 0xff);
}
static inline lv_color_t lv_color_black(void)
{
return lv_color_make(0x00, 0x0, 0x00);
}
lv_color_t lv_palette_lighten(lv_palette_t p, uint8_t lvl);
lv_color_t lv_palette_darken(lv_palette_t p, uint8_t lvl);
在
~/esp442/esp32_lvgl833/components/lvgl/src/misc/lv_color.c
中有lv_palette_main函数的实现代码:
lv_color_t lv_palette_main(lv_palette_t p)
{
static const lv_color_t colors[] = {
LV_COLOR_MAKE(0xF4, 0x43, 0x36), LV_COLOR_MAKE(0xE9, 0x1E, 0x63), LV_COLOR_MAKE(0x9C, 0x27, 0xB0), LV_COLOR_MAKE(0x67, 0x3A, 0xB7),
LV_COLOR_MAKE(0x3F, 0x51, 0xB5), LV_COLOR_MAKE(0x21, 0x96, 0xF3), LV_COLOR_MAKE(0x03, 0xA9, 0xF4), LV_COLOR_MAKE(0x00, 0xBC, 0xD4),
LV_COLOR_MAKE(0x00, 0x96, 0x88), LV_COLOR_MAKE(0x4C, 0xAF, 0x50), LV_COLOR_MAKE(0x8B, 0xC3, 0x4A), LV_COLOR_MAKE(0xCD, 0xDC, 0x39),
LV_COLOR_MAKE(0xFF, 0xEB, 0x3B), LV_COLOR_MAKE(0xFF, 0xC1, 0x07), LV_COLOR_MAKE(0xFF, 0x98, 0x00), LV_COLOR_MAKE(0xFF, 0x57, 0x22),
LV_COLOR_MAKE(0x79, 0x55, 0x48), LV_COLOR_MAKE(0x60, 0x7D, 0x8B), LV_COLOR_MAKE(0x9E, 0x9E, 0x9E)
};
if(p >= _LV_PALETTE_LAST) {
LV_LOG_WARN("Invalid palette: %d", p);
return lv_color_black();
}
return colors[p];
}
该函数主要是预定义颜色数组。
另外还有lv_color_t lv_palette_lighten(lv_palette_t p, uint8_t lvl)
和lv_color_t lv_palette_darken(lv_palette_t p, uint8_t lvl)
的预定义颜色。
- 预定义颜色的使用
在这里颜色是用3字节RGB888格式定义的,在使用时有程序代码会将其裁剪为2字节RGB565格式。
宏LV_COLOR_MAKE在~/esp442/esp32_lvgl833/components/lvgl/src/misc/lv_color.h
中定义:
#define LV_COLOR_MAKE(r8, g8, b8) LV_CONCAT(LV_COLOR_MAKE, LV_COLOR_DEPTH)(r8, g8, b8)
其中,宏LV_CONCAT实现颜色裁剪,在~/esp442/esp32_lvgl833/components/lvgl/src/misc/lv_types.h
中定义:
#define _LV_CONCAT(x, y) x ## y
#define LV_CONCAT(x, y) _LV_CONCAT(x, y)
- 修正ST7735的颜色
对于ST7735显示屏将颜色格式从RGB565改成BGR565格式。增加针对ST7735的宏LV_COLOR_MAKE,代码如下:
#if defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_ST7735S
#define LV_COLOR_MAKE(r8, g8, b8) LV_CONCAT(LV_COLOR_MAKE, LV_COLOR_DEPTH)(b8, g8, r8)
#else
#define LV_COLOR_MAKE(r8, g8, b8) LV_CONCAT(LV_COLOR_MAKE, LV_COLOR_DEPTH)(r8, g8, b8)
#endif
3. 效果对比
- 修正之前
- 修正之后