本笔记以我示例项目中的 obj/myexample.c 系列函数作为核心代码示例进行讲解
配置好跨平台规则的项目链接:跨平台 LVGL 项目模板
1. 图像
从 C 数组加载 (有限图像场景)
这种方法适合图标、背景图等固定不变的图像资源。它将图片数据直接编译进程序中,运行效率高,但不灵活。
核心步骤:
转换:
使用 LVGL 官方的 在线图像转换工具 将你的图片转换为一个 C 语言源文件。
这个 C 文件中会包含一个
lv_img_dsc_t类型的数组,存储了图像的所有像素数据按照下图选项来输出适合 v8 版本的图片
注意:如果图片里带有透明图层,颜色格式需要选择
CF_TRUE_COLOR_ALPHA而不是CF_TRUE_COLOR,只有保存了ALPHA通道信息才能正常显示透明部分编译:
将生成的
.c文件添加到你的项目 CMake 中,并确保它能被编译链接使用:
在代码中通过
LV_IMG_DECLARE声明该图像资源,然后使用lv_img_set_src将其设置给一个图像对象
代码示例
以下代码演示了如何显示一个已经通过工具转换好的,名为 abc 的图像。
1 | // obj/myexample.c |
从文件系统加载 (不限图像场景)
当需要显示不固定的图片(如照片、网络下载的图片)时,就需要使用此方法。它要求 LVGL 能够访问设备的文件系统。
核心步骤:
- 配置
lv_conf.h:- 开启文件系统支持:将
LV_USE_FS_STDIO或其他文件系统接口设置为1。 - 定义 “盘符”:设置
LV_FS_STDIO_LETTER为一个大写字母,例如'A'。此后,所有文件路径都必须以A:/开头。
- 开启文件系统支持:将
- 放置文件:将图片文件(如
small_image.sjpg)放置到你的设备文件系统的某个路径下(如/mnt/nfs/)。 - 使用:在代码中,使用
lv_img_set_src并传入盘符 + 绝对路径格式的字符串。
代码示例
以下代码演示了如何从设备的 /mnt/nfs/ 目录下加载并显示 small_image.sjpg 图片。
1 | void demo_sjpg_from_file( ) { |
安装 PNG 解码库 (依赖 zlib)
PNG 库依赖 zlib 库,因此需要先编译安装 zlib,再编译安装 libpng。以下教程针对交叉编译环境,提供了避免常见陷阱的详细步骤。
1. 安装 zlib 压缩库
Ubuntu/Linux
用一句命令即可直接安装
1
sudo apt install zlib1g-dev
开发板 / 其他平台
需手动下载、交叉编译并链接:进入 zlib 源码目录进行配置和编译。
关键提示: 为了避免后续在链接动态库时出现
recompile with -fPIC的错误,我们必须在编译静态库时就生成“位置无关代码”(Position-Independent Code)。推荐的编译命令 (生成静态库
.a):1
2
3
4
5
6
7
8# 指定交叉编译器
export CC=arm-linux-gcc
# 使用 CMAKE_POSITION_INDEPENDENT_CODE=ON 来添加 -fPIC 标志
cmake -B build -D CMAKE_BUILD_TYPE=Release -D CMAKE_POSITION_INDEPENDENT_CODE=ON
# 编译
cmake --build build -j12编译完成后,会在
build目录下生成libz.a文件。
2. 安装 libpng 库
Ubuntu/Linux
用一句命令即可直接安装
1
sudo apt install libpng-dev
开发板 / 其他平台
需手动下载、交叉编译并链接:进入 libpng 源码目录进行配置和编译。
关键提示: 在交叉编译时,libpng 的构建系统无法自动找到我们刚刚编译好的 zlib。我们必须通过 CMake 参数明确地告诉它 zlib 的头文件和库文件在哪里。
推荐的编译命令 (生成静态库
.a):1
2
3
4
5
6
7
8
9
10
11
12
13
14# 指定交叉编译器
export CC=arm-linux-gcc
# 运行 cmake,并用 -D 参数明确指定 zlib 的路径
# 注意:请将 <path/to> 替换为你的实际路径,不要使用 '~'
cmake -B build \
-D CMAKE_BUILD_TYPE=Release \
-D BUILD_SHARED_LIBS=OFF \
-D ZLIB_INCLUDE_DIR=<path/to>/zlib-1.3.1 \
-D ZLIB_LIBRARY=<path/to>/zlib-1.3.1/build/libz.a \
-D CMAKE_C_FLAGS="-I<path/to>/zlib-1.3.1/build"
# 编译
cmake --build build -j12参数详解:
-D ZLIB_INCLUDE_DIR: 指向 zlib 的源码根目录,用于找到zlib.h。-D ZLIB_LIBRARY: 明确指向编译生成的libz.a静态库文件。-D CMAKE_C_FLAGS="-I...": 额外添加一个头文件搜索路径,指向 zlib 的构建目录,用于找到编译时生成的zconf.h。
编译完成后,会在
build目录下生成libpng16.a文件。CMake 工程链接 PNG 与 ZLIB
在链接时,必须同时链接 libpng 和 zlib。由于我们编译的是静态库,CMake 中也应配置为链接静态库。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42if(CMAKE_CROSSCOMPILING)
# ARM 平台
set(TARGET_PLATFORM "arm")
# --- 为 FreeType 添加 (静态库示例) ---
add_library(freetype_local STATIC IMPORTED GLOBAL)
set_target_properties(freetype_local PROPERTIES
IMPORTED_LOCATION "${CMAKE_CURRENT_SOURCE_DIR}/libs/freetype/lib/arm/libfreetype.a"
)
# --- 为 PNG 添加 (静态库) ---
add_library(png_local STATIC IMPORTED GLOBAL)
set_target_properties(png_local PROPERTIES
# 假设你已将编译好的 libpng16.a 复制到此路径
IMPORTED_LOCATION "${CMAKE_CURRENT_SOURCE_DIR}/libs/png/lib/arm/libpng16.a"
)
# --- 为 ZLIB 添加 (静态库) ---
add_library(zlib_local STATIC IMPORTED GLOBAL)
set_target_properties(zlib_local PROPERTIES
# 假设你已将编译好的 libz.a 复制到此路径
IMPORTED_LOCATION "${CMAKE_CURRENT_SOURCE_DIR}/libs/zlib/lib/arm/libz.a"
)
# --- 将所有库加入列表 (注意链接顺序) ---
set(PLATFORM_LIBS pthread freetype_local png_local zlib_local m)
elseif(UNIX AND NOT APPLE)
# Linux PC 平台
set(TARGET_PLATFORM "pc")
find_package(SDL2 REQUIRED)
find_package(Threads REQUIRED)
find_package(Freetype REQUIRED)
# --- 查找 PNG 和 ZLIB ---
find_package(PNG REQUIRED)
find_package(ZLIB REQUIRED)
# --- 将所有库加入列表 (使用现代CMake目标) ---
set(PLATFORM_LIBS SDL2::SDL2 Threads::Threads Freetype::Freetype PNG::PNG ZLIB::ZLIB m)
endif()使用方法和之前一样,如果还是不行,用下面的函数调试:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33static void debug_load_image(const char* path_to_test)
{
LV_LOG_USER("--- 开始终极调试: %s ---", path_to_test);
// 步骤 1: 检查 LVGL 文件系统驱动是否就绪
if (!lv_fs_is_ready('A')) {
LV_LOG_ERROR("错误: LVGL 文件系统驱动 'A' 未就绪!");
return;
}
LV_LOG_USER("调试信息: LVGL 文件系统驱动 'A' 已就绪。");
// 步骤 2: 尝试用 LVGL 的 API 打开文件
lv_fs_file_t f;
lv_fs_res_t res = lv_fs_open(&f, path_to_test, LV_FS_MODE_RD);
if (res != LV_FS_RES_OK) {
LV_LOG_ERROR("错误: LVGL lv_fs_open 失败! 错误码: %d", res);
} else {
LV_LOG_USER("调试成功: LVGL lv_fs_open 成功!");
lv_fs_close(&f);
}
// 步骤 3: 作为对比,尝试用标准 C 的 API 打开同一个文件
FILE* std_f = fopen(path_to_test, "rb");
if (std_f == NULL) {
LV_LOG_ERROR("错误: 标准 C fopen 失败!");
} else {
LV_LOG_USER("调试成功: 标准 C fopen 成功!");
fclose(std_f);
}
LV_LOG_USER("--- 终极调试结束 ---");
}可以开启 lv_conf.h 里面的这个选项来缓存图片,使 cpu 占用降低:
1
2. 字体
LVGL 内置字体对中文支持不佳,推荐使用外部字体。最灵活、支持最全面的方式是集成 FreeType 字体库
使用 FreeType 加载外部字体(不限汉字场景)
此方法支持动态加载标准字体文件(如 .ttf),可直接显示任意汉字,无需预先转换
1. 配置与编译
开启 LVGL FreeType 支持
在lv_conf.h中设置:1
安装 FreeType 库
Ubuntu/Linux
用一句命令即可直接安装
1
sudo apt install libfreetype6-dev
开发板 / 其他平台
需手动下载、交叉编译并链接:将源码下载下来放到项目根目录
进入 freetype 源码目录命令行,进行以下配置和编译操作
编译为动态库:
1
2
3
4
5
6# 指定交叉编译器
export CC=arm-linux-gcc
cmake -B build -D BUILD_SHARED_LIBS=true -D CMAKE_BUILD_TYPE=Release
#编译
cmake --build build -j12或者编译为静态库:
1
2
3
4
5
6# 指定交叉编译器
export CC=arm-linux-gcc
cmake -B build -D BUILD_SHARED_LIBS=OFF -D CMAKE_BUILD_TYPE=Release
# 编译
cmake --build build -j12
CMake 工程链接 FreeType
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20if(CMAKE_CROSSCOMPILING)
# ARM 平台
set(TARGET_PLATFORM "arm")
add_library(freetype_local SHARED IMPORTED GLOBAL)
set_target_properties(freetype_local PROPERTIES
# ARM 平台需要指定库程序路径
IMPORTED_LOCATION "${CMAKE_CURRENT_SOURCE_DIR}/libs/freetype/lib/arm/libfreetype.so"
)
set(PLATFORM_LIBS pthread freetype_local m)
elseif(UNIX AND NOT APPLE)
# Linux PC 平台
set(TARGET_PLATFORM "pc")
find_package(SDL2 REQUIRED)
find_package(Threads REQUIRED)
# 直接去系统库里面找
set(PLATFORM_LIBS SDL2::SDL2 Threads::Threads freetype m)
endif()
2. 准备字体文件
将所需 .ttf 文件(如 MiSans.ttf)放到设备文件系统中,保证程序运行时可访问。
3. 使用方法
代码初始化 FreeType 字体 → 创建样式 → 应用到控件。
1 | void demo_freetype_text(void) { |




