当前位置:首页>java>LVGL应用编程:图像(lv_img)控件详解

LVGL应用编程:图像(lv_img)控件详解

  • 2026-09-11 16:28:43
LVGL应用编程:图像(lv_img)控件详解

本文理论知识居多,开始一遍了解功能即可,后续用到再当字典查,文中涉及的实操界面,需要先搭建环境,需观看我上一篇文章:创建第一个LVGL工程https://mp.weixin.qq.com/s/zJ8hf4f36GGpJW_8vHf0Jw

LVGL应用编程:图像控件详解

一、图像在UI中的重要性

想象一下这些场景:

  • • 应用的图标(设置、返回、主页)
  • • 产品的Logo,用户头像
  • • 天气应用的天气图标(晴天、雨天)

这些都需要使用图像控件来显示!在嵌入式UI中,一图胜千言,好的图像能让界面更直观、更美观。

二、两种图像加载方式:如何选择?

2.1 方式一:转换为C数组(无文件系统设备)

适用场景:单片机、无文件系统、图片数量少且固定

步骤1:使用LVGL官方转换工具

访问:https://lvgl.io/tools/imageconverter

image-20260203203804668

重要设置:

  1. 1. Color format(颜色格式):
    • • CF_TRUE_COLOR - 真彩色,效果最好,文件最大
    • • CF_TRUE_COLOR_ALPHA - 带透明度的真彩色
    • • CF_INDEXED_1/2/4/8BIT - 索引色,文件小但颜色少
  2. 2. Output format(输出格式):
    • • C array - C数组格式,直接嵌入代码
    • • Binary - 二进制格式,需要文件系统支持

步骤2:下载并使用

// 1. 将生成的icon_back.c文件放到工程目录main.c同一路径下// 2. 在代码中声明和使用// 声明图片(在文件顶部)LV_IMG_DECLARE(icon_back);void show_image() {    // 创建图像控件    lv_obj_t *img = lv_img_create(lv_scr_act());    // 设置图像源(使用声明的图片)    lv_img_set_src(img, &icon_back);    // 居中显示    lv_obj_center(img);}

优点:运行速度快,不依赖文件系统缺点:图片大小固定,更新麻烦,占用程序空间大

image-20260203210248996

2.2 方式二:直接使用图片文件(有文件系统设备)

适用场景:Linux嵌入式设备、图片数量多或需要动态更新

步骤1:配置工程目录结构

你的工程/├── res/                    # 资源文件夹│   ├── font/              # 字体文件夹│   ├── image/             # 图片文件夹│   │   ├── image_conf.h│   │   ├── icon_back.png│   │   └── lvgl-logo.png│   └── res_conf.h         # 资源配置文件├── main.c└── CMakeLists.txt

步骤2:更新资源配置文件

res_conf.h - 统一管理所有资源路径:

#ifndef _RES_CONF_H_#define _RES_CONF_H_// 区分PC仿真和开发板环境#ifdef SIMULATOR_LINUX    // PC仿真路径(相对路径)    #define FONT_PATH  "./build/app1/res/font/"    #define IMAGE_PATH "./build/app1/res/image/"#else    // 开发板路径(绝对路径)    #define FONT_PATH  "/usr/res/font/"    #define IMAGE_PATH "/usr/res/image/"#endif#endif

image_conf.h - 图片配置头文件:

#ifndef _IMAGE_CONF_H_#define _IMAGE_CONF_H_#include "res_conf.h"// 定义盘符(LVGL文件系统使用)#define DRIVER_LETTER "A:"// 获取图片完整路径的宏#define GET_IMAGE_PATH(name) (DRIVER_LETTER IMAGE_PATH name)#endif

步骤3:配置LVGL文件系统

PC仿真环境(platform/x86linux/src/porting/lv_conf.h):

// 启用标准I/O文件系统#define LV_USE_FS_STDIO 1#if LV_USE_FS_STDIO#define LV_FS_STDIO_LETTER 'A'     /* 盘符,对应A: */#define LV_FS_STDIO_PATH ""        /* 工作目录,为空表示当前目录 */#define LV_FS_STDIO_CACHE_SIZE 0   /* 缓存大小,0表示不缓存 */#endif

开发板环境(platform/t113/src/porting/lv_conf.h):

// 根据实际情况配置文件系统#define LV_USE_FS_STDIO 1  // 或LV_USE_FS_POSIX,取决于你的系统#if LV_USE_FS_STDIO#define LV_FS_STDIO_LETTER 'A'#define LV_FS_STDIO_PATH "/usr/res/"  // 注意:这里设置基础路径#define LV_FS_STDIO_CACHE_SIZE 0#endif

步骤4:修改CMakeLists.txt

cmake_minimum_required(VERSION 3.15)project(app1)# 定义宏,用于区分PC仿真环境if(SIMULATOR_LINUX)    add_compile_definitions(SIMULATOR_LINUX)endif()# 复制资源文件到构建目录file(COPY res DESTINATION ${PROJECT_BINARY_DIR})# 添加源代码aux_source_directory(. SOURCES)add_executable(app1 ${SOURCES})# 添加头文件路径target_include_directories(app1 PRIVATE    ./    res/    res/font/    res/image/    ${CMAKE_SOURCE_DIR}/component/font    ${CMAKE_SOURCE_DIR}/lvgl)# 链接库target_link_libraries(app1 PRIVATE    lvgl    font)

步骤5:使用图片文件

#include "image_conf.h"void show_image_from_file() {    // 创建图像控件    lv_obj_t *img = lv_img_create(lv_scr_act());    // 使用文件路径设置图像源    lv_img_set_src(img, GET_IMAGE_PATH("lvgl-logo.png"));    // 居中显示    lv_obj_center(img);}
image-20260203213621833

三、处理透明背景图片

问题:白色图标在白色背景上看不见

很多图标是白色背景透明的,在白色背景上显示为"空白"。

解决方案:

void show_transparent_icon() {    // 1. 创建黑色背景容器    lv_obj_t *container = lv_obj_create(lv_scr_act());    lv_obj_set_size(container, LV_PCT(100), LV_PCT(100));    lv_obj_set_style_bg_color(container, lv_color_hex(0x000000), LV_PART_MAIN);    // 去除容器的边距、边框等    lv_obj_set_style_pad_all(container, 0, LV_PART_MAIN);    lv_obj_set_style_border_width(container, 0, LV_PART_MAIN);    lv_obj_set_style_outline_width(container, 0, LV_PART_MAIN);    lv_obj_set_style_radius(container, 0, LV_PART_MAIN);    // 2. 在容器中显示图标    lv_obj_t *img = lv_img_create(container);    lv_img_set_src(img, GET_IMAGE_PATH("icon_back.png"));    lv_obj_center(img);}

原理:透明图标显示为它自身的颜色(通常是白色),在黑色背景上就能清晰可见。

image-20260203214004932

四、图像的高级操作

4.1 缩放图像

重要:不能使用lv_obj_set_size()设置图像大小!

void scale_image() {    lv_obj_t *img = lv_img_create(lv_scr_act());    lv_img_set_src(img, GET_IMAGE_PATH("icon_back.png"));    lv_obj_center(img);    // 缩放图像    // 256 = 原始大小(100%) 512 = 放大2倍(200%)128 = 缩小一半(50%)    lv_img_set_zoom(img, 512);  // 放大2倍    // 获取当前缩放值    uint16_t zoom = lv_img_get_zoom(img);    printf("当前缩放: %d (%.1f倍)\n", zoom, zoom / 256.0);}
image-20260203214700094

4.2 旋转图像

void rotate_image() {    lv_obj_t *img = lv_img_create(lv_scr_act());    lv_img_set_src(img, GET_IMAGE_PATH("icon_back.png"));    lv_obj_center(img);    // 旋转图像(角度精度为0.1度)    // 90° = 900 45.8° = 458 180° = 1800    lv_img_set_angle(img, 900);  // 旋转90度    // 获取当前旋转角度    uint16_t angle = lv_img_get_angle(img);    printf("当前角度: %d (%.1f度)\n", angle, angle / 10.0);}
image-20260203214910205

4.3 组合缩放和旋转

void transform_image() {    lv_obj_t *img = lv_img_create(lv_scr_act());    lv_img_set_src(img, GET_IMAGE_PATH("icon_back.png"));    lv_obj_center(img);    // 先缩放    lv_img_set_zoom(img, 384);  // 1.5倍    // 再旋转    lv_img_set_angle(img, 450);  // 45度    // 设置旋转中心点(默认是图像中心)    lv_img_set_pivot(img, 50, 50);  // 设置旋转中心为(50,50)像素}
image-20260203215056576

五、让图像可点击(图标按钮)

默认情况下,图像控件不可点击。我们需要手动添加点击功能:

// 图像点击事件处理函数static void image_click_cb(lv_event_t *e) {    printf("图像被点击了!\n");    // 可以获取事件源(被点击的图像)    lv_obj_t *img = lv_event_get_target(e);    // 根据图像做不同处理    const char *src = lv_img_get_src(img);    printf("图像源: %s\n", src);    // 切换图像(实现按钮状态切换)    if (strstr(src, "lvgl-logo")) {        lv_img_set_src(img, GET_IMAGE_PATH("icon_back.png"));    } else {        lv_img_set_src(img, GET_IMAGE_PATH("lvgl-logo.png"));    }}void create_clickable_image() {    // 创建图像    lv_obj_t *img = lv_img_create(lv_scr_act());    lv_img_set_src(img, GET_IMAGE_PATH("icon_back.png"));    lv_obj_center(img);    // 添加可点击标志    lv_obj_add_flag(img, LV_OBJ_FLAG_CLICKABLE);    // 绑定点击事件    lv_obj_add_event_cb(img, image_click_cb, LV_EVENT_CLICKED, NULL);    // 也可以添加其他事件    lv_obj_add_event_cb(img, image_click_cb, LV_EVENT_PRESSED, NULL);    lv_obj_add_event_cb(img, image_click_cb, LV_EVENT_RELEASED, NULL);}
Recording 2026-02-03 220632

快速参考卡片

// 创建图像lv_obj_t *img = lv_img_create(parent);// 设置图像源(C数组)LV_IMG_DECLARE(icon);lv_img_set_src(img, &icon);// 设置图像源(文件)lv_img_set_src(img, GET_IMAGE_PATH("icon.png"));// 缩放图像lv_img_set_zoom(img, 512);  // 200%// 旋转图像lv_img_set_angle(img, 900);  // 90度// 使图像可点击lv_obj_add_flag(img, LV_OBJ_FLAG_CLICKABLE);lv_obj_add_event_cb(img, click_handler, LV_EVENT_CLICKED, NULL);
往期推荐:
LVGL应用编程入门:从零开始打造炫酷嵌入式界面
Linux系统编程完整指南
LVGL应用编程:创建第一个LVGL工程(Hello World!)
LVGL应用编程:交互UI设计
专科,二本,小公司:我的技术扎根年

最新文章

随机文章