LVGL控件篇:图片部件(lv_img)

目录

简介

图片部件的组成 

图片部件的相关知识 

图片源选择

1.C 语言数组

2.外部图片源文件

3.图标字体 

图片重新着色 

图片自动大小  

图片偏移  

图片缩放

图片旋转

图片部件的 API 函数

图片部件的实验 


简介

我们自己制作精美的GUI界面的时候,加入一张我们自己需要的图片,可以放我们的GUI界面看起来更加的美观,我们LVGL中,可以轻松的实现加入一张图片,图片部件可用于显示图片,其图片源可以是 C 语言数组格式的文件、二进制的.bin 文件以及图标字体。值得注意的是,图片部件要显示 BMPJPEG 等格式的图片,则必须经过解码。

图片部件的组成 

图片部件的组成部分仅有一个:主体(LV_PART_MAIN)。关于部件样式设置的内容,请大家去看LVGL基础知识

图片部件的相关知识 

图片源选择

图片部件的图片来源分为三种:C 语言数组;存储在外部的图片文件;图标字体,接下来,我们详细介绍上述三种图片源的使用方法:

1.C 语言数组

采用 C 语言数组的方式来显示图片是较为简单的,整个配置流程分为以下四步:

第一步:生成图片相关的 C 语言数组。如果用户需要将 PNGJPG BMP 格式的图片转换成 C 语言数组,可以使用官方的在线转换工具进行格式转换,该在线工具的网址为:

https://lvgl.io/tools/imageconverter。当我们进入到该网页后,界面如图所示:

进入到该界面后,首先点击上图中“Sele image file(s)”按钮,导入所需要的图片,注意,这里图片的格式是有要求的,只能是PNGJPG 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)。如果用户需要将 PNGJPGBMP格式的图片转换成 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_obj_t *parent: 父对象

返回创建的图片对象指针 (lv_obj_t*)

lv_img_set_src()

设置图片源

lv_obj_t *img: 图片对象
const void *src: 图片数据或路径

无返回值

lv_img_set_offset_x()

设置图片的 x 轴偏移量

lv_obj_t *img: 图片对象
lv_coord_t x: 偏移量

无返回值

lv_img_set_offset_y()

设置图片的 y 轴偏移量

lv_obj_t *img: 图片对象
lv_coord_t y: 偏移量

无返回值

lv_img_set_pivot()

设置图片的旋转中心点

lv_obj_t *img: 图片对象
lv_coord_t x: 中心点的 x 坐标
lv_coord_t y: 中心点的 y 坐标

无返回值

lv_img_set_angle()

设置图片的旋转角度

lv_obj_t *img: 图片对象
int16_t angle: 旋转角度(单位:0.1°,360° = 3600)

无返回值

lv_img_set_zoom()

设置图片的缩放系数

lv_obj_t *img: 图片对象
uint16_t zoom: 缩放比例(256 = 100%,512 = 200%)

无返回值

lv_img_set_antialias()

启用/禁用转换的抗锯齿功能

lv_obj_t *img: 图片对象
bool antialias: true 开启,false 关闭

无返回值

lv_img_set_size_mode()

设置图片的模式(如拉伸或缩放以适应部件大小)

lv_obj_t *img: 图片对象
lv_img_size_mode_t mode: 模式(LV_IMG_SIZE_MODE_VIRTUALLV_IMG_SIZE_MODE_REAL 等)

无返回值

lv_img_get_src()

获取图片的来源

lv_obj_t *img: 图片对象

返回图片的源地址 (const void*)

lv_img_get_offset_x()

获取图片的 x 轴偏移量

lv_obj_t *img: 图片对象

返回 x 轴偏移量 (lv_coord_t)

lv_img_get_offset_y()

获取图片的 y 轴偏移量

lv_obj_t *img: 图片对象

返回 y 轴偏移量 (lv_coord_t)

lv_img_get_angle()

获取图片的旋转角度

lv_obj_t *img: 图片对象

返回旋转角度(单位:0.1°)(int16_t)

lv_img_get_pivot()

获取图片的旋转中心点

lv_obj_t *img: 图片对象
lv_point_t *pivot: 输出参数,用于接收旋转中心点的坐标

无返回值

lv_img_get_zoom()

获取图片的缩放系数

lv_obj_t *img: 图片对象

返回缩放系数(256 = 100%)(uint16_t)

lv_img_get_antialias()

获取转换是否开启抗锯齿功能

lv_obj_t *img: 图片对象

返回是否开启抗锯齿 (bool)

lv_img_get_size_mode()

获取图片模式

lv_obj_t *img: 图片对象

返回图片模式 (lv_img_size_mode_t)

 备注

  • 图片模式:通过 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 中进行运行查看:

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值