目录
简介
我们自己制作精美的GUI界面的时候,加入一张我们自己需要的图片,可以放我们的GUI界面看起来更加的美观,我们LVGL中,可以轻松的实现加入一张图片,图片部件可用于显示图片,其图片源可以是 C 语言数组格式的文件、二进制的.bin 文件以及图标字体。值得注意的是,图片部件要显示 BMP、JPEG 等格式的图片,则必须经过解码。
图片部件的组成
图片部件的组成部分仅有一个:主体(LV_PART_MAIN)。关于部件样式设置的内容,请大家去看LVGL基础知识。
图片部件的相关知识
图片源选择
图片部件的图片来源分为三种:C 语言数组;存储在外部的图片文件;图标字体,接下来,我们详细介绍上述三种图片源的使用方法:
1.C 语言数组
采用 C 语言数组的方式来显示图片是较为简单的,整个配置流程分为以下四步:
第一步:生成图片相关的 C 语言数组。如果用户需要将 PNG、JPG 和 BMP 格式的图片转换成 C 语言数组,可以使用官方的在线转换工具进行格式转换,该在线工具的网址为:
https://lvgl.io/tools/imageconverter。当我们进入到该网页后,界面如图所示:
进入到该界面后,首先点击上图中“Sele image file(s)”按钮,导入所需要的图片,注意,这里图片的格式是有要求的,只能是PNG、JPG 和 BMP 格式的图片,并且我们最好提前命名好图片的名字,因为之后生成的c文件的名字就是这张名字的图片。如图所示:
导入完成后, 点击图中 Color format 选项,根据需求选择颜色格式(不需要透明度通道就选择 True color),如图所示:
然后点击图中 Output format 选项,选择输出格式为“C array”,最后点击“Convert”按钮即可生成 C 语言数组相关的文件(文件路径自选)。
第二步:将 C 语言数组文件添加到工程当中,如图所示:
然后调用 LV_IMG_DECLARE(xxx)宏定义对图片源进行声明。如图所示:
第三步:调用 lv_img_create 函数创建图片部件。
第四步:调用 lv_img_set_src 函数设置图片源。
我们运行一下,可以看到我们导入的图片成功在屏幕上面显示了:
2.外部图片源文件
第一步:生成外部源文件(.bin)。如果用户需要将 PNG、JPG和 BMP格式的图片转换成 bin 文件,同样也可以使用官方的在线转换工具进行格式转换,与 C 语言数组转换不同的是:在 Output format 选项中,输出格式需要选择 Binary RGB565。转换完成后,我们即可得到图片相关的 bin 文件。
第二步:使能 LVGL 的文件系统。
第三步:拷贝 bin 文件到指定的 SD 卡目录中。
第三步:调用 lv_img_create 函数创建图片部件。
第四步:调用 lv_img_set_src 函数设置图片源。值得注意的是,该函数中需要指定文件路径,例如:"0:APP/my_img.bin";
3.图标字体
图标字体在LVGL内部就已经给我们了,它们可以作为图片部件的图片源,用户只需要调用lv_img_set_src 函数进行设置即可,示例源码如下:
lv_img_set_src(img, LV_SYMBOL_DUMMY);
我们举个例子看看:
img = lv_img_create(lv_scr_act());
lv_img_set_src(img, LV_SYMBOL_AUDIO); /* 设置图片源 */
lv_obj_center(img);
LVGL内部给了我们非常多的国标字体,这里我们列举一下,读者可以自己一个个去尝试看看。
#define LV_SYMBOL_AUDIO "\xef\x80\x81" /*61441, 0xF001*/
#define LV_SYMBOL_VIDEO "\xef\x80\x88" /*61448, 0xF008*/
#define LV_SYMBOL_LIST "\xef\x80\x8b" /*61451, 0xF00B*/
#define LV_SYMBOL_OK "\xef\x80\x8c" /*61452, 0xF00C*/
#define LV_SYMBOL_CLOSE "\xef\x80\x8d" /*61453, 0xF00D*/
#define LV_SYMBOL_POWER "\xef\x80\x91" /*61457, 0xF011*/
#define LV_SYMBOL_SETTINGS "\xef\x80\x93" /*61459, 0xF013*/
#define LV_SYMBOL_HOME "\xef\x80\x95" /*61461, 0xF015*/
#define LV_SYMBOL_DOWNLOAD "\xef\x80\x99" /*61465, 0xF019*/
#define LV_SYMBOL_DRIVE "\xef\x80\x9c" /*61468, 0xF01C*/
#define LV_SYMBOL_REFRESH "\xef\x80\xa1" /*61473, 0xF021*/
#define LV_SYMBOL_MUTE "\xef\x80\xa6" /*61478, 0xF026*/
#define LV_SYMBOL_VOLUME_MID "\xef\x80\xa7" /*61479, 0xF027*/
#define LV_SYMBOL_VOLUME_MAX "\xef\x80\xa8" /*61480, 0xF028*/
#define LV_SYMBOL_IMAGE "\xef\x80\xbe" /*61502, 0xF03E*/
#define LV_SYMBOL_ENVELOPE "\xef\x83\xa0" /*61664, 0xF0E0*/
#define LV_SYMBOL_EDIT "\xef\x8C\x84" /*62212, 0xF304*/
#define LV_SYMBOL_TINT "\xef\x81\x83" /*61507, 0xF043*/
#define LV_SYMBOL_PREV "\xef\x81\x88" /*61512, 0xF048*/
#define LV_SYMBOL_PLAY "\xef\x81\x8b" /*61515, 0xF04B*/
#define LV_SYMBOL_PAUSE "\xef\x81\x8c" /*61516, 0xF04C*/
#define LV_SYMBOL_STOP "\xef\x81\x8d" /*61517, 0xF04D*/
#define LV_SYMBOL_NEXT "\xef\x81\x91" /*61521, 0xF051*/
#define LV_SYMBOL_EJECT "\xef\x81\x92" /*61522, 0xF052*/
#define LV_SYMBOL_LEFT "\xef\x81\x93" /*61523, 0xF053*/
#define LV_SYMBOL_RIGHT "\xef\x81\x94" /*61524, 0xF054*/
#define LV_SYMBOL_PLUS "\xef\x81\xa7" /*61543, 0xF067*/
#define LV_SYMBOL_MINUS "\xef\x81\xa8" /*61544, 0xF068*/
#define LV_SYMBOL_EYE_OPEN "\xef\x81\xae" /*61550, 0xF06E*/
#define LV_SYMBOL_EYE_CLOSE "\xef\x81\xb0" /*61552, 0xF070*/
#define LV_SYMBOL_WARNING "\xef\x81\xb1" /*61553, 0xF071*/
#define LV_SYMBOL_SHUFFLE "\xef\x81\xb4" /*61556, 0xF074*/
#define LV_SYMBOL_UP "\xef\x81\xb7" /*61559, 0xF077*/
#define LV_SYMBOL_DOWN "\xef\x81\xb8" /*61560, 0xF078*/
#define LV_SYMBOL_LOOP "\xef\x81\xb9" /*61561, 0xF079*/
#define LV_SYMBOL_DIRECTORY "\xef\x81\xbb" /*61563, 0xF07B*/
#define LV_SYMBOL_UPLOAD "\xef\x82\x93" /*61587, 0xF093*/
#define LV_SYMBOL_CALL "\xef\x82\x95" /*61589, 0xF095*/
#define LV_SYMBOL_CUT "\xef\x83\x84" /*61636, 0xF0C4*/
#define LV_SYMBOL_COPY "\xef\x83\x85" /*61637, 0xF0C5*/
#define LV_SYMBOL_SAVE "\xef\x83\x87" /*61639, 0xF0C7*/
#define LV_SYMBOL_BARS "\xef\x83\x89" /*61641, 0xF0C9*/
#define LV_SYMBOL_CHARGE "\xef\x83\xa7" /*61671, 0xF0E7*/
#define LV_SYMBOL_PASTE "\xef\x83\xAA" /*61674, 0xF0EA*/
#define LV_SYMBOL_BELL "\xef\x83\xb3" /*61683, 0xF0F3*/
#define LV_SYMBOL_KEYBOARD "\xef\x84\x9c" /*61724, 0xF11C*/
#define LV_SYMBOL_GPS "\xef\x84\xa4" /*61732, 0xF124*/
#define LV_SYMBOL_FILE "\xef\x85\x9b" /*61787, 0xF158*/
#define LV_SYMBOL_WIFI "\xef\x87\xab" /*61931, 0xF1EB*/
#define LV_SYMBOL_BATTERY_FULL "\xef\x89\x80" /*62016, 0xF240*/
#define LV_SYMBOL_BATTERY_3 "\xef\x89\x81" /*62017, 0xF241*/
#define LV_SYMBOL_BATTERY_2 "\xef\x89\x82" /*62018, 0xF242*/
#define LV_SYMBOL_BATTERY_1 "\xef\x89\x83" /*62019, 0xF243*/
#define LV_SYMBOL_BATTERY_EMPTY "\xef\x89\x84" /*62020, 0xF244*/
#define LV_SYMBOL_USB "\xef\x8a\x87" /*62087, 0xF287*/
#define LV_SYMBOL_BLUETOOTH "\xef\x8a\x93" /*62099, 0xF293*/
#define LV_SYMBOL_TRASH "\xef\x8B\xad" /*62189, 0xF2ED*/
#define LV_SYMBOL_BACKSPACE "\xef\x95\x9A" /*62810, 0xF55A*/
#define LV_SYMBOL_SD_CARD "\xef\x9F\x82" /*63426, 0xF7C2*/
#define LV_SYMBOL_NEW_LINE "\xef\xA2\xA2" /*63650, 0xF8A2*/
图片重新着色
图片重新着色是指将一种特定的颜色与图片的每个像素进行混合,这可以用于显示图片的不同状态,例如选中、未激活、按下等。
用户需要让图片重新着色,就必须要调用以下两个函数:
lv_obj_set_style_img_recolor_opa (重着色透明度)
lv_obj_set_style_img_recolor(颜色设置)
注意:重着色透明度的范围是 0-255,在默认的情况下,该透明度为 0(完全透明),因此,如果不改变该透明度,将看不到颜色混合效果。
图片自动大小
如果把图片部件的宽度或高度设置为 LV_SIZE_CONTENT,那它的大小将会根据图片源的大小而自动变化。
lv_obj_t *img = lv_img_create(lv_scr_act()); // 创建图片部件
// 设置图片源
lv_img_set_src(img, &img_text);
// 设置宽度和高度为 LV_SIZE_CONTENT,自适应图片源的大小
lv_obj_set_width(img, LV_SIZE_CONTENT);
lv_obj_set_height(img, LV_SIZE_CONTENT);
// 居中显示
lv_obj_center(img);
图片偏移
图片偏移是指对图片部件的内部所显示的图片进行偏移,值得注意的是,如果图片偏移出了图片部件的范围,则超出的部分会显示在与偏移方向相反的一侧,如图所示:
设置图片偏移可调用以下函数:
lv_img_set_offset_x(img, x_ofs)
/* 图片往 X 轴偏移 */lv_img_set_offset_y ( img , y_ofs )/* 图片往 Y 轴偏移 */
图片缩放
在 LVGL 中,用户可调用 lv_img_set_zoom 函数设置图片的缩放,该函数具有两个形参,第一个形参为图片部件,而第二个形参为缩放的比例。
注意:如果缩放的比例设置为 256 或 LV_IMG_ZOOM_NONE,则表示禁用缩放;如果缩放的比例设置为 128,则表示缩放到原来的 1/2;如果缩放的比例设置为 512,则表示放大 2 倍,示意图如下所示:
示例:
lv_obj_t *img = lv_img_create(lv_scr_act()); // 创建图片部件
// 设置图片源
lv_img_set_src(img, &img_text);
// 设置宽度和高度为 LV_SIZE_CONTENT,自适应图片源的大小
lv_obj_set_width(img, LV_SIZE_CONTENT);
lv_obj_set_height(img, LV_SIZE_CONTENT);
lv_img_set_zoom(img,128);
// 居中显示
lv_obj_center(img);
图片旋转
图片旋转是指图片以某一点为中心,旋转一定的角度。在默认的情况下,旋转的中心点通常就是图片的中心。用户需要旋转图片,可调用 lv_img_set_angle 函数进行设置,该函数的第二个形参代表旋转的角度值,值得注意的是,角度值/10 = 实际的旋转角度,因此,如果用户想把图片顺时针 旋转 45°,则需要将角度值设置为 450。图片旋转的示例如下:
lv_obj_t *img = lv_img_create(lv_scr_act()); // 创建图片部件
// 设置图片源
lv_img_set_src(img, &img_text);
// 设置宽度和高度为 LV_SIZE_CONTENT,自适应图片源的大小
lv_obj_set_width(img, LV_SIZE_CONTENT);
lv_obj_set_height(img, LV_SIZE_CONTENT);
lv_img_set_angle(img,450);
// 居中显示
lv_obj_center(img);
在上图中,图片是围绕其中心点进行旋转的,如果用户需要改变旋转的中心点,可以调用 lv_img_set_pivot(img, pivot_x, pivot_y)函数,该函数的第二和第三个形参代表旋转中心点的 x和y 轴坐标。
图片部件的 API 函数
函数名称 | 功能描述 | 形参 | 返回值 |
---|---|---|---|
lv_img_create() | 创建图片部件 |
| 返回创建的图片对象指针 ( |
lv_img_set_src() | 设置图片源 |
| 无返回值 |
lv_img_set_offset_x() | 设置图片的 x 轴偏移量 |
| 无返回值 |
lv_img_set_offset_y() | 设置图片的 y 轴偏移量 |
| 无返回值 |
lv_img_set_pivot() | 设置图片的旋转中心点 |
| 无返回值 |
lv_img_set_angle() | 设置图片的旋转角度 |
| 无返回值 |
lv_img_set_zoom() | 设置图片的缩放系数 |
| 无返回值 |
lv_img_set_antialias() | 启用/禁用转换的抗锯齿功能 |
| 无返回值 |
lv_img_set_size_mode() | 设置图片的模式(如拉伸或缩放以适应部件大小) |
| 无返回值 |
lv_img_get_src() | 获取图片的来源 |
| 返回图片的源地址 ( |
lv_img_get_offset_x() | 获取图片的 x 轴偏移量 |
| 返回 x 轴偏移量 ( |
lv_img_get_offset_y() | 获取图片的 y 轴偏移量 |
| 返回 y 轴偏移量 ( |
lv_img_get_angle() | 获取图片的旋转角度 |
| 返回旋转角度(单位:0.1°)( |
lv_img_get_pivot() | 获取图片的旋转中心点 |
| 无返回值 |
lv_img_get_zoom() | 获取图片的缩放系数 |
| 返回缩放系数(256 = 100%)( |
lv_img_get_antialias() | 获取转换是否开启抗锯齿功能 |
| 返回是否开启抗锯齿 ( |
lv_img_get_size_mode() | 获取图片模式 |
| 返回图片模式 ( |
备注
-
图片模式:通过
lv_img_set_size_mode()
和lv_img_get_size_mode()
可指定或获取图片的适应模式,比如是否按原图尺寸显示或适配容器大小。 -
旋转与缩放:旋转中心点默认位于图片的左上角,缩放比例以
256
为基准(即256 = 100%
,缩放为原大小)。 -
抗锯齿:对于非整数倍缩放或旋转的图片,启用抗锯齿功能可提升显示效果。
图片部件的实验
本实验主要测试图片部件 API 函数的使用,实验现象:开机后,屏幕上显示六个滑块以及一张图片(齿轮),当我们滑动不同的滑块时,系统会根据这些滑动的值来修改图片的样式属性。注意:如果碰到不会的控件,可以先去学习对应的控件再回头来看这里。
程序设计:
/* 获取当前活动屏幕的宽高 */
#define scr_act_width() lv_obj_get_width(lv_scr_act())
#define scr_act_height() lv_obj_get_height(lv_scr_act())
/* 定义图片部件、滑块部件 */
static lv_obj_t *img;
static lv_obj_t *slider_zoom, *slider_angle, *slider_r, *slider_g, *slider_b, *slider_opa;
LV_IMG_DECLARE(img_gear); /* 声明图片 */
/**
* @brief 滑块事件回调
* @param *e :事件相关参数的集合,它包含了该事件的所有数据
* @return 无
*/
static void slider_event_cb(lv_event_t *e)
{
lv_img_set_zoom(img, lv_slider_get_value(slider_zoom)); /* 设置图片缩放 */
lv_img_set_angle(img, lv_slider_get_value(slider_angle)); /* 设置图片旋转角度 */
/* 设置图片重新着色 */
lv_obj_set_style_img_recolor(img,
lv_color_make(lv_slider_get_value(slider_r), lv_slider_get_value(slider_g), lv_slider_get_value(slider_b)),
LV_PART_MAIN);
lv_obj_set_style_img_recolor_opa(img, lv_slider_get_value(slider_opa), LV_PART_MAIN); /* 设置重新着色透明度 */
}
/**
* @brief 创建滑块
* @param color:颜色值
* @return *slider:创建成功的滑块部件
*/
static lv_obj_t *my_slider_create(lv_color_t color)
{
lv_obj_t *slider = lv_slider_create(lv_scr_act()); /* 创建滑块 */
lv_obj_set_height(slider, scr_act_height() / 20); /* 设置高度 */
lv_obj_set_width(slider, scr_act_width() / 3); /* 设置宽度 */
lv_obj_remove_style(slider, NULL, LV_PART_KNOB); /* 移除旋钮 */
lv_obj_set_style_bg_color(slider,color,LV_PART_INDICATOR); /* 设置滑块指示器颜色 */
lv_obj_set_style_bg_color(slider,lv_color_darken(color, 100),LV_PART_MAIN); /* 设置滑块主体颜色、透明度 */
lv_obj_add_event_cb(slider, slider_event_cb, LV_EVENT_VALUE_CHANGED, NULL); /* 设置滑块回调 */
return slider;
}
/**
* @brief 图片部件实例
* @param 无
* @return 无
*/
static void lv_example_img(void)
{
img = lv_img_create(lv_scr_act()); /* 创建图片部件 */
lv_img_set_src(img, &img_gear); /* 设置图片源 */
lv_obj_align(img, LV_ALIGN_CENTER, -scr_act_width() / 5, 0); /* 设置图片位置 */
lv_obj_update_layout(img); /* 更新图片参数 */
/* 图片缩放控制滑块 */
slider_zoom = my_slider_create(lv_color_hex(0x989c98)); /* 创建滑块 */
lv_slider_set_range(slider_zoom, 128, 512); /* 设置滑块的范围 */
lv_slider_set_value(slider_zoom, 256, LV_ANIM_OFF); /* 设置滑块的值 */
lv_obj_align(slider_zoom, LV_ALIGN_CENTER, scr_act_width() / 4, -scr_act_height() / 4); /* 设置滑块位置 */
/* 旋转角度控制滑块 */
slider_angle = my_slider_create(lv_color_hex(0x989c98)); /* 创建滑块 */
lv_slider_set_range(slider_angle, 0, 3600); /* 设置滑块的范围 */
lv_obj_align_to(slider_angle, slider_zoom, LV_ALIGN_OUT_BOTTOM_LEFT, 0, scr_act_height() / 20); /* 设置滑块位置 */
/* 红色通道控制滑块 */
slider_r = my_slider_create(lv_color_hex(0xff0000)); /* 创建滑块 */
lv_slider_set_range(slider_r, 0, 255); /* 设置滑块的范围 */
lv_obj_align_to(slider_r, slider_angle, LV_ALIGN_OUT_BOTTOM_LEFT, 0, scr_act_height() / 20); /* 设置滑块位置 */
/* 绿色通道控制滑块 */
slider_g = my_slider_create(lv_color_hex(0x00ff00)); /* 创建滑块 */
lv_slider_set_range(slider_g, 0, 255); /* 设置滑块的范围 */
lv_obj_align_to(slider_g, slider_r, LV_ALIGN_OUT_BOTTOM_LEFT, 0, scr_act_height() / 20); /* 设置滑块位置 */
/* 蓝色通道控制滑块 */
slider_b = my_slider_create(lv_color_hex(0x0000ff)); /* 创建滑块 */
lv_slider_set_range(slider_b, 0, 255); /* 设置滑块的范围 */
lv_obj_align_to(slider_b, slider_g, LV_ALIGN_OUT_BOTTOM_LEFT, 0, scr_act_height() / 20); /* 设置滑块位置 */
/* 着色透明度控制滑块 */
slider_opa = my_slider_create(lv_color_hex(0x000000)); /* 创建滑块 */
lv_slider_set_range(slider_opa, 0, 255); /* 设置滑块的范围 */
lv_slider_set_value(slider_opa, 150, LV_ANIM_OFF); /* 设置滑块的值 */
lv_obj_align_to(slider_opa, slider_b, LV_ALIGN_OUT_BOTTOM_LEFT, 0, scr_act_height() / 20); /* 设置滑块位置 */
}
/**
* @brief LVGL演示
* @param 无
* @return 无
*/
void lv_mainstart(void)
{
lv_example_img();
}
上述源码可分为以下三个部分:
① lv_mainstart 接口函数。在该函数中,我们调用了图片相关的示例函数;
② 图片、滑块的创建和配置。我们先创建图片部件,设置图片源,然后再创建六个滑块部件,并设置相关的回调函数;
③ 回调函数的逻辑处理。在滑块的回调函数中,我们将不同滑块的当前值获取回来,然后将这些返回值应用到图片样式的设置中,例如:图片缩放、图片旋转、图片重新着色等。
CodeBlocks 中进行运行查看: