【ESP32】Platformio+Arduino+LVGL | 如何加载图片(使用C语言数组方法)

发布时间 2023-11-16 00:13:48作者: MaxBruce

原文:https://blog.csdn.net/JackieCoo/article/details/128621681

前言
最近在做项目的时候,有一个使用LVGL库往屏幕显示图片的需求。
虽然LVGL的官网有对应操作的说明文档,但描述得比较模糊,对于初学者不太友好,所有我就详细讲一下具体如何操作。

我使用的是LVGL中的lv_img组件实现图片的加载,根据LVGL的说明文档,该组件创建图片的方式有3种:

使用C语言数组创建
读取文件系统中的文件创建
使用LVGL自带的符号
在这里我只会介绍第一种方法——使用C语言数组创建,如果以后有机会可以介绍第二种,这也是一种比较好的方式,如果你想加载多张图片的话。

教程
首先,通过这种方法创建图片,组件接收的是一个数组,因此我们必须把本地的图片转换成对应的数组才行。转换的工具我推荐Img2Lcd。下载链接:Img2Lcd, 提取码:aita

准备图片的时候最好在Photoshop等图片编辑工具中,设置好图片的大小,输出成常用的图片格式,推荐导出为bmp格式。
点击左上方“打开”,选择图片打开。左侧可以进行基本的调整,一般只需要修改“最大宽度和高度”,这里要对应图片的宽和高;右下方可以选择输出的色彩格式,这里就要看需求了,越高的色彩宽度图片越接近真实图片,但这要看单片机和屏幕支不支持,我的屏幕是16位色的,所以如图选择RGB565的这一种格式。


设置好后点击左上角“保存”,就可以导出对应的.c文件,将文件放到项目中。
软件生存的只有一个数组,我们需要对源文件进行修改,使其适配LVGL的要求。
对于生成的数组,需要去掉前8个字节的内容,前8个字节保存的是图片的图片头,是一些描述信息,与图片显示是无关的。
包含LVGL的头文件,然后像下面这样设置数组。LV_ATTRIBUTE_MEM_ALIGN宏定义是让数组进行4字节对齐,LV_ATTRIBUTE_LARGE_CONST宏定义是提醒LVGL这是一个超大的只读数组。

#include "lvgl.h"

const LV_ATTRIBUTE_MEM_ALIGN LV_ATTRIBUTE_LARGE_CONST uint8_t author_avatar[] = {
0X31,0XA5,0XF0,0X94,0XB0,0X94,0X31,0XA5,0XB3,0XBD,0X35,0XCE,0X76,0XD6,0X76,0XD6,
0XF5,0XC5,0X73,0XAD,0XF1,0X9C,0XF1,0X9C,0X72,0XAD,0XF5,0XC5,0X76,0XD6,0X77,0XD6,
0X77,0XDE,0XB8,0XDE,0XB9,0XDE,0XF9,0XE6,0XFA,0XE6,0XFA,0XE6,0XFA,0XE6,0XFA,0XE6,
0XFA,0XE6,0XFA,0XE6,0XFA,0XE6,0XFA,0XE6,0XF9,0XE6,0XB9,0XE6,0XB9,0XDE,0XB9,0XDE,
0XB9,0XDE,0XB9,0XDE,0XB8,0XDE,0XB7,0XDE,0X77,0XDE,0XB8,0XDE,0XB8,0XDE,0XB8,0XDE,
0XB8,0XDE,0XB7,0XDE,0X77,0XD6,0X77,0XD6,0XB8,0XDE,0XB8,0XDE,0X78,0XD6,0X78,0XD6,
/* 太多了,此处省略 */
0X8C,0X7B,0X4B,0X7B,0X4B,0X73,0X4B,0X73,0X09,0X63,0X47,0X4A,0X47,0X4A,0X47,0X4A,
0X07,0X4A,0X07,0X4A,0X06,0X42,0X06,0X42,0XC6,0X39,0XC6,0X39,0XC6,0X39,0XC6,0X39,
0XC6,0X39,0XC6,0X39,0XC6,0X39,0XC6,0X39,0XC6,0X31,0XC6,0X31,0XC6,0X39,0XC6,0X39,
0XC6,0X39,0XC6,0X39,0XC6,0X39,0XC6,0X39,0XC6,0X31,0X86,0X31,0X86,0X31,0X86,0X31,
0X86,0X31,0X86,0X31,0X86,0X31,0X86,0X31,0X86,0X31,0X86,0X31,0X86,0X31,0X86,0X31,
0X86,0X31,0X86,0X31,0X86,0X31,0X86,0X31,0X86,0X31,0X86,0X29,0X86,0X29,0X86,0X31,
0X86,0X29,0X86,0X31,0X86,0X31,0XC7,0X39
};

const lv_img_dsc_t img_author_avatar = {
.header.always_zero = 0,
.header.w = 150,
.header.h = 150,
.data_size = sizeof(author_avatar),
.header.cf = LV_IMG_CF_TRUE_COLOR,
.data = author_avatar,
};

下面在数组的下面创建一个lv_img_dsc_t,用于定义图片的信息,header.always_zero跟图片头有关,因为我们在一开始就删掉了数组的前8字节数据,所以这里填0即可;header.w和header.h对应图片的宽高;data_size为数组的大小;header.cf为图片的色彩格式,LV_IMG_CF_TRUE_COLOR意思是该图片的色彩格式和LVGL上面设置的一样,除此之外还有很多的色彩格式可选,具体可进定义里面看;data为数组的首地址。

下面就是加载这张图片了。通过LV_IMG_DECLARE宏定义声明图片,变量名一定要和我们创建的lv_img_dsc_t结构体变量同名。接下来就是一些LVGL的常规操作了,看下面代码就可以看懂了。

LV_IMG_DECLARE(img_author_avatar);
lv_obj_t* avatar = lv_img_create(content);
lv_img_set_src(avatar, &img_author_avatar);
lv_obj_set_size(avatar, 150, 150);

下面给一张效果图。

 

总结
总的来说,通过这种方法加载图片的好处就是简单、快捷,比较适合整个项目只有一两张图片这种需求。但缺点也很明显,因为图片是直接被保存在内存中的,所以能加载多少图片取决于你的单片机内存有多大,像我的这一张图片,150X150的分辨率,16位色彩,就需要占掉150x150x(16/8)=45000B≈45KB的内存。所以如果项目中需要加载很多的图片,那么搭建一个文件系统,把图片存在Flash中,需要的时候再加载是更好的方法。
————————————————
版权声明:本文为CSDN博主「马浩同学」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/JackieCoo/article/details/128621681