22. 图片部件
一、图片部件
图片部件可用于显示图片,其图片源可以是 C 语言数组格式的文件、二进制的.bin 文件以及图标字体。图片部件要显示 BMP、JPEG 等格式的图片,则必须经过解码。图片部件的组成部分仅有一个:主体(LV_PART_MAIN
)。
LVGL 官方提供了一些与图片部件相关 API。
#define lv_img_create lv_image_create
lv_obj_t * lv_image_create(lv_obj_t * parent); // 创建图片部件
#define lv_img_set_src lv_image_set_src
void lv_image_set_src(lv_obj_t * obj, const void * src); // 设置图片源
#define lv_img_get_src lv_image_get_src
const void * lv_image_get_src(lv_obj_t * obj); // 获取图片的来源
#define lv_img_set_offset_x lv_image_set_offset_x
void lv_image_set_offset_x(lv_obj_t * obj, int32_t x); // 设置图片的x轴偏移量
#define lv_img_get_offset_x lv_image_get_offset_x
int32_t lv_image_get_offset_x(lv_obj_t * obj); // 获取图片的x轴偏移量
#define lv_img_set_offset_y lv_image_set_offset_y
void lv_image_set_offset_y(lv_obj_t * obj, int32_t y); // 设置图片的y轴偏移量
#define lv_img_get_offset_y lv_image_get_offset_y
int32_t lv_image_get_offset_y(lv_obj_t * obj); // 获取图片的y轴偏移量
#define lv_img_set_pivot lv_image_set_pivot
void lv_image_set_pivot(lv_obj_t * obj, int32_t x, int32_t y); // 设置图片的旋转中心点
#define lv_img_get_pivot lv_image_get_pivot
void lv_image_get_pivot(lv_obj_t * obj, lv_point_t * pivot); // 获取图片的旋转中心点
#define lv_img_set_angle lv_image_set_rotation
void lv_image_set_rotation(lv_obj_t * obj, int32_t angle); // 设置图片的旋转角度
#define lv_img_get_angle lv_image_get_rotation
int32_t lv_image_get_rotation(lv_obj_t * obj); // 获取图片的旋转角度
#define lv_img_set_zoom lv_image_set_scale
void lv_image_set_scale(lv_obj_t * obj, uint32_t zoom); // 设置图片的缩放
#define lv_img_get_zoom lv_image_get_scale
int32_t lv_image_get_scale(lv_obj_t * obj) // 获取图片的缩放系数
#define lv_img_set_antialias lv_image_set_antialias
void lv_image_set_antialias(lv_obj_t * obj, bool antialias); // 启用/禁用转换的抗锯齿功能
#define lv_img_get_antialias lv_image_get_antialias
bool lv_image_get_antialias(lv_obj_t * obj); // 获取转换是否开启抗锯齿功能
我们使用 lv_img_create()
函数 创建图片部件。
/**
* @brief 创建图片部件
*
* @param parent 指向父部件的指针
* @return lv_obj_t* 指向图片部件的指针
*/
lv_obj_t * lv_img_create(lv_obj_t * parent);
在创建完图片部件后,我们可以使用 lv_img_set_src()
函数 设置图片源。
/**
* @brief 设置图片源
*
* @param obj 指向图片部件的指针
* @param src 图片源地址
*/
void lv_img_set_src(lv_obj_t * obj, const void * src);
图片重新着色是指将一种特定的颜色与图片的每个像素进行混合,这可以用于显示图片的不同状态,例如选中、未激活、按下等。用户需要让图片重新着色,就必须要调用以下两个函数:lv_obj_set_style_img_recolor_opa()
(重着色透明度)和 lv_obj_set_style_img_recolor()
(颜色设置)。重着色透明度的范围是 0 ~ 255,在默认的情况下,该透明度为 0
(完全透明),因此,如果不改变该透明度,将看不到颜色混合效果。
/**
* @brief 设置图片重着色
*
* @param obj 指向部件的指针
* @param value 颜色值
* @param selector 刷选器,刷选部件
*/
#define lv_obj_set_style_img_recolor lv_obj_set_style_image_recolor
void lv_obj_set_style_image_recolor(lv_obj_t * obj, lv_color_t value, lv_style_selector_t selector);
/**
* @brief 设置图片的透明度
*
* @param obj 指向部件的指针
* @param value 透明度值
* @param selector 刷选器,刷选部件
*/
#define lv_obj_set_style_img_opa lv_obj_set_style_image_opa
void lv_obj_set_style_image_opa(lv_obj_t * obj, lv_opa_t value, lv_style_selector_t selector);
如果把图片部件的宽度或高度设置为 LV_SIZE_CONTENT
,那它的大小将会根据图片源的大小而自动变化。
图片偏移 是指对图片部件的内部所显示的图片进行偏移,值得注意的是,如果图片偏移出了图片部件的范围,则超出的部分会显示在与偏移方向相反的一侧。设置图片偏移可调用以下函数:
/**
* @brief 设置图片的x轴偏移量
*
* @param obj 指向图片部件的指针
* @param x x轴偏移量
*/
void lv_img_set_offset_x(lv_obj_t * obj, int32_t x);
/**
* @brief 设置图片的y轴偏移量
*
* @param obj 指向图片部件的指针
* @param y y轴偏移量
*/
void lv_img_set_offset_y(lv_obj_t * obj, int32_t y);
在 LVGL 中,用户可调用 lv_img_set_zoom()
函数 设置图片的缩放。如果缩放的比例设置为 256
或 LV_IMG_ZOOM_NONE
,则表示 禁用缩放;如果缩放的比例设置为 128
,则表示 缩放到原来的 1/2;如果缩放的比例设置为 512
,则表示 放大 2 倍,示意图如下所示:
/**
* @brief 设置图片的缩放
*
* @param obj 指向图片部件的指针
* @param zoom 缩放的比例
*/
void lv_img_set_zoom(lv_obj_t * obj, uint32_t zoom);
图片旋转是指图片以某一点为中心,旋转一定的角度。在默认的情况下,旋转的中心点通常就是图片的中心。用户需要 旋转图片,可调用 lv_img_set_angle()
函数进行设置。
/**
* @brief 设置图片的旋转角度
*
* @param obj 指向图片部件的指针
* @param angle 旋转的角度值,角度值/10 = 实际的旋转角度
*/
void lv_img_set_angle(lv_obj_t * obj, int32_t angle);
如果用户需要 改变旋转的中心点,可以调用 lv_img_set_pivot()
函数。
/**
* @brief 设置图片的旋转中心点
*
* @param obj 指向图片部件的指针
* @param x 旋转中心点的x轴坐标
* @param y 旋转中心点的y轴坐标
*/
void lv_img_set_pivot(lv_obj_t * obj, int32_t x, int32_t y);
二、图片源选择
2.1、C语言数组
图片部件的图片来源分为三种:C 语言数组、存储在外部的图片文件 和 图标字体。
采用 C 语言数组 的方式来显示图片是较为简单的,整个配置流程分为以下四步:
第一步:生成图片相关的 C 语言数组。如果用户需要将 PNG、JPG 和 BMP 格式的图片转换成 C 语言数组,可以使用官方的在线转换工具进行格式转换,该在线工具的网址为:https://lvgl.io/tools/imageconverter。
进入到该界面后,首先点击上图中 “Select image file(s)” 按钮,导入所需要的图片,导入完成后,点击图中 Color format 选项,根据需求选择颜色格式,然后点击图中 Convert 选项,选择输出格式为“C array”,最后点击“Convert”按钮即可生成 C 语言数组相关的文件(文件路径自选)。
第二步:将 C 语言数组文件添加到工程当中,然后调用 LV_IMG_DECLARE(xxx)
宏定义对图片源进行声明。
第三步:调用 lv_img_create()
函数创建图片部件。
第四步:调用 lv_img_set_src()
函数设置图片源。
这里推荐使用 png 格式的图片进行转化。
2.2、外部图片源文件
第一步:生成外部源文件(.bin)。如果用户需要将 PNG、JPG和 BMP格式的图片转换成 bin 文件,官方的在线转换工具进行格式转换提供一个 Python 编写图片格式转换的 GitHub 仓库链接。
下载完代码后,我们需要安装 pypng 和 lz4 模块,这里,我们在终端中使用 pip 指令安装 pypng 和 lz4 模块。
pip install pypng
pip install lz4
如果由于网络原因导致下载出错,我们可以在后面加上 -i 镜像源
选项加速下载。
- 阿里云 https://mirrors.aliyun.com/pypi/simple/
- 中国科技大学 https://pypi.mirrors.ustc.edu.cn/simple/
- 清华大学 https://pypi.tuna.tsinghua.edu.cn/simple
- 中国科学技术大学 https://pypi.mirrors.ustc.edu.cn/simple
安装完模块后,我们在终端中运行 Python 文件。
LVGLImage.py [-h] [–ofmt {C,BIN,PNG}] [–cf {L8,I1,I2,I4,I8,A1,A2,A4,A8,ARGB8888,XRGB8888,RGB565,RGB565A8,ARGB8565,RGB888,AUTO}] [–compress {NONE,RLE,LZ4}] [–align [byte]] [–background [color]] [-o OUTPUT] [-v] input
-h
、--help
: 显示使用脚本的帮助信息。–ofmt {C,BIN,PNG}
: 指定处理后图像的输出格式。C
: 作为 C 源代码(数组)输出。BIN
: 作为二进制文件输出。PNG
: 作为 PNG 图像输出(可能用于调试)。
–cf {L8,I1,I2,I4,I8,A1,A2,A4,A8,ARGB8888,XRGB8888,RGB565,RGB565A8,ARGB8565,RGB888,AUTO}
:选择图像转换的颜色格式。- 选项包括不同位深度和色彩模式,如 L8(8 位灰度)、I1(1 位索引色)、ARGB8888(32 位真彩色带透明)、RGB565(16 位色彩),以及 AUTO 自动选择合适的格式。
–compress {NONE,RLE,LZ4}
:确定用于图像数据的压缩方法。NONE
: 无压缩。RLE
: 行程长度编码,对有大块单一颜色区域的图像效果好。LZ4
: LZ4 压缩算法,平衡了压缩速度和压缩率。
–align [字节]
:指定输出数据对齐到指定的字节边界,某些嵌入式系统对数据对齐有特定要求。–background [color]
:设置图像填充或转换为非透明格式时透明像素的背景色。-o 输出文件
:指定输出文件路径,如果不指定,默认输出在 output 文件夹下的同名 bin 文件。-v
:启用详细模式,在处理过程中提供更多信息。input
:输入文件,需要被处理的输入图像文件路径。
这里,我们使用如下命令运行 Python 脚本生成 bin 文件。
python LVGLImage.py --ofmt BIN --cf RGB565 --align 1 --compress NONE image.png
第二步:使能 LVGL 的文件系统。
第三步:拷贝 bin 文件到指定的 SD 卡目录中。
第四步:调用 lv_img_create()
函数创建图片部件。
第四步:调用 lv_img_set_src()
函数设置图片源。
如果 GitHub 链接打不开,可以下载 Watt Toolkit(原名 Steam++),然后选择平台加速,勾选上 GitHub 进行加速。
这里推荐使用 png 格式的图片进行转化。
三、实验例程
#include "lvgl.h"
#include "lv_port_disp_template.h"
#include "lv_port_indev_template.h"
#include "image.c"
int main(void)
{
LV_IMG_DECLARE(image); // 声明图片源
HAL_Init();
System_Clock_Init(8, 336, 2, 7);
Delay_Init(168);
SPI_Simulate_Init();
// SRAM_Init();
TIM_Base_Init(&g_tim6_handle, TIM6, 83, 999);
__HAL_TIM_CLEAR_IT(&g_tim6_handle, TIM_IT_UPDATE); // 清除更新中断标志位
HAL_TIM_Base_Start_IT(&g_tim6_handle); // 使能更新中断,并启动计数器
lv_init();
lv_port_disp_init();
lv_port_indev_init();
// 测试代码
lv_obj_t *img = lv_img_create(lv_scr_act()); // 创建图片部件
lv_img_set_src(img, &image); // 设置图片部件的图片
lv_obj_center(img); // 设置图片部件居中对齐
lv_obj_set_style_img_recolor(img, lv_color_hex(0xFF1493), LV_PART_MAIN); // 设置图片重新着色
lv_obj_set_style_img_recolor_opa(img, 150, LV_PART_MAIN); // 设置图片的透明度
lv_obj_update_layout(img); // 更新图片布局信息
lv_img_set_pivot(img, 0, 0); // 设置图片中心点
lv_img_set_zoom(img, 300); // 设置图片所防止
lv_img_set_angle(img, 300); // 设置图片旋转
while (1)
{
lv_timer_handler();
Delay_ms(5);
}
return 0;
}
生成的 C 语言数组名字一般与文件名一致。