目录
1.2.1 LV_IMG_CF_ALPHA_1/2/4/8BIT
1.2.2 LV_IMG_CF_INDEXED_1/2/4/8BIT
1.2.3 LV_IMG_CF_RAW/_ALPHA/_CHROME_KEYED
1.2.4 LV_IMG_CF_TRUE_COLOR/_ALPHA/_CHROMA_KEYED
图像是显示来自闪存(作为数组)或来自文件的图像的基本对象。
1. 图像来源
和字库类似,可以通过在线转换工具将图片转换为LVGL支持的C数组或二进制文件。
离线版本(因为网络的问题,建议用这种方式)的使用方法:
a. 安装nodejs
nodejs安装及环境配置_Mr.羽猫君的博客-CSDN博客https://blog.csdn.net/qq_57210034/article/details/124823972
b. 进入CMD运行‘npm install’和'npm install -g typescript'
最好在运行前改一下镜像的地址,例如:
npm config set registry http://registry.cnpmjs.org/
npm config set registry https://registry.npmjs.org/
c. 通过git clone克隆离线工具
git clone https://github.com/lvgl/lv_img_conv.git
d. 在CMD界面进入文件夹lib中,运行'npm install -g ts-node'
e. 在lib文件中运行命令转换图片,例如:
ts-node cli.ts logo_lvgl.png -f -c CF_TRUE_COLOR_ALPHA
也可以在文件夹内建立bat文件,例如:
1.1 图片源文件
支持的格式有BMP, JPG, PNG和SVG,可以一次选择多个文件。为了便于理解格式问题,新建一个像素8x8的bmp文件,用画图软件打开编辑:
输出格式选择C数组。
1.2 颜色格式
为了节约空间,图像需要选择合适的格式,LVGL支持5大类颜色格式。
1.2.1 LV_IMG_CF_ALPHA_1/2/4/8BIT
存储 1、2、4 或 8 位的 Alpha 值,源图像必须是 Alpha 通道,整个图像是一种可以更改的颜色。
如果用windows的画图软件编辑保存,即第一个像素为黑色,其他颜色是白色,如下图。这时会发现转换工具转换出来的数据都是0xFF,这是因为需要原图像要有Alpha通道。
可以使用GIMP(或PS)的图像处理软件,将白色改为透明色,再导出为png图片。
LV_IMG_CF_ALPHA_8BIT格式生成的数组如下:
const LV_ATTRIBUTE_MEM_ALIGN LV_ATTRIBUTE_LARGE_CONST LV_ATTRIBUTE_IMG_E uint8_t e_map[] = {
0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
在图片上再增加一个点判断工具扫描方向
const LV_ATTRIBUTE_MEM_ALIGN LV_ATTRIBUTE_LARGE_CONST LV_ATTRIBUTE_IMG_E uint8_t e_map[] = {
0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
可以看出扫描方向是从左到右,再从上到下。
将格式改为CF_ALPHA_1_BIT,生成的数组为:
const LV_ATTRIBUTE_MEM_ALIGN LV_ATTRIBUTE_LARGE_CONST LV_ATTRIBUTE_IMG_E uint8_t e_map[] = {
0x80,
0x80,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
};
1.2.2 LV_IMG_CF_INDEXED_1/2/4/8BIT
使用2、4、16或256色调色板,并以1、2、4或8位存储每个像素。同样,以第一个像素为黑色的8x8图片为例,生成CF_INDEXED_1_BIT格式的数据如下:
const LV_ATTRIBUTE_MEM_ALIGN LV_ATTRIBUTE_LARGE_CONST LV_ATTRIBUTE_IMG_E uint8_t e_map[] = {
0x00, 0x00, 0x00, 0x00, /*Color of index 0*/
0x00, 0x00, 0x00, 0xff, /*Color of index 1*/
0x80,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
};
可以看到前面8个字节就是Index,Index 0表示白色或者透明色,Index 1表示黑色。
1.2.3 LV_IMG_CF_RAW/_ALPHA/_CHROME_KEYED
RAW表示数组是图片的原始数据。把图片导出为bmp文件,格式为CF_RAW(好像是和CF_RAW_CHROME_KEYED一样,生成的格式变量是LV_IMG_CF_RAW_CHROMA_KEYED)
可以看到数组就是图片的二进制文件。
CF_RAW_ALPHA格式表示为每个像素添加了Alpha字节。
CF_RAW_CHROME_KEYED格式表示如果像素具有LV_COLOR_TRANSP(在lv_conf.h中设置)颜色,则该像素将是透明的。
通过同样的图片对比三种格式,没发现三者生成的数据有差别。
1.2.4 LV_IMG_CF_TRUE_COLOR/_ALPHA/_CHROMA_KEYED
LV_IMG_CF_TRUE_COLOR:只存储RGB颜色(使用LVGL配置的任何颜色深度)。 如果采用之前的图片,得到的结果相反,每个像素得到的值都是0x00,即没有参考ALPHA。
#if LV_COLOR_DEPTH == 1 || LV_COLOR_DEPTH == 8
/*Pixel format: Red: 3 bit, Green: 3 bit, Blue: 2 bit*/
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
#endif
如果把黑色改为红色就可以看到数据变化。
LV_IMG_CF_TRUE_COLOR_ALPHA:每个像素添加了Alpha字节,如下,每个像素变为2个字节
#if LV_COLOR_DEPTH == 1 || LV_COLOR_DEPTH == 8
/*Pixel format: Alpha 8 bit, Red: 3 bit, Green: 3 bit, Blue: 2 bit*/
0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
#endif
LV_IMG_CF_TRUE_COLOR_CHROMA_KEYED:如果像素具有LV_COLOR_TRANSP(在lv_conf.h中设置)颜色,则该像素将是透明的。
1.2.5 LV_IMG_CF_RGB565A8
这种格式是数组有RGB565+Alpha8两组数据组合。例如:
const LV_ATTRIBUTE_MEM_ALIGN LV_ATTRIBUTE_LARGE_CONST LV_ATTRIBUTE_IMG_E uint8_t e_map[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/*alpha channel*/
0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
2. 显示图片
将工具转换出来的c文件加载到工程中。
以下图为例,文件名为imgSnowFlake.png,生成imgSnowFlake.c,图像结构体名为imgSnowFlake
2.1 创建
使用lv_img_create创建图像对象句柄。
lv_obj_t* img = lv_img_create(lv_scr_act());
2.2 申明
使用LV_IMG_DECLARE申明。
LV_IMG_DECLARE(imgSnowFlake);
注意,因为VisualStudio模拟器是C++环境,这里要加上extern "C",否则会链接错误,如下:
extern "C" {
LV_IMG_DECLARE(imgSnowFlake);
}
2.3 设置源
通过函数lv_img_set_src设置图像的源。
void lv_img_set_src(lv_obj_t * obj, const void * src)
而源有3种情况,分别为文件,结构体指针,Symbol,程序会判断是哪种情况。
lv_img_set_src(img, &imgSnowFlake);
不同格式显示效果如下:
CF_ALPHA_2_BIT:
CF_ALPHA_4_BIT:
CF_ALPHA_8_BIT(data_size = 65536):
CF_INDEXED_1_BIT(data_size = 8200):
CF_INDEXED_2_BIT(data_size = 16400):
CF_INDEXED_4_BIT(data_size = 32832):
CF_INDEXED_8_BIT(data_size = 66560):
CF_TRUE_COLOR(data_size = 262144):
CF_TRUE_COLOR_ALPHA(data_size = 262144):
CF_RGB565A8(data_size = 196608):显示错误,怀疑是工具有问题,生成的数据是全0。
3. 样式
3.1 设置x/y方向上的偏移
这个偏移是图片内的偏移,不是在屏幕上的偏移。
void lv_img_set_offset_x(lv_obj_t * obj, lv_coord_t x)
void lv_img_set_offset_y(lv_obj_t * obj, lv_coord_t y)
例如x方向偏移-128,可以试试偏移128,显示结果是类似的。
lv_obj_align(img, LV_ALIGN_CENTER, 0, 0);
lv_img_set_offset_x(img, -128);
lv_img_set_offset_y(img, 128);
3.2 设置支点
设置图片旋转等操作时的支点,坐标值是以图片的左顶点为原点。
void lv_img_set_pivot(lv_obj_t * obj, lv_coord_t x, lv_coord_t y)
3.3 旋转
void lv_img_set_angle(lv_obj_t * obj, int16_t angle)
角度angle有0.1度精度,所以45.8°设置为458,默认是以图片中心旋转。
lv_img_set_angle(img, 36 * 10);
注意,有些格式不支持旋转,例如INDEXED。
3.4 放大缩小
void lv_img_set_zoom(lv_obj_t * obj, uint16_t zoom)
参数zoom为256时,图片是原始大小,小于256表示缩小,大于256表示放大。
lv_img_set_zoom(img, 128);
lv_img_set_zoom(img, 512);
3.5 抗锯齿
抗锯齿开关通过lv_img_set_antialias开关。启用反锯齿后,转换的质量会更高,但速度会更慢。
void lv_img_set_antialias(lv_obj_t * obj, bool antialias)
3.6 设置图像大小模式
当图像大小和对象大小不同时,主要影响缩放时的显示效果
void lv_img_set_size_mode(lv_obj_t * obj, lv_img_size_mode_t mode)
LV_IMG_SIZE_MODE_VIRTUAL: 缩放不会影响对象的坐标,默认。
LV_IMG_SIZE_MODE_REAL:如果对象大小设置为size_CONTENT,则对象大小等于缩放的图像大小。如果显式设置了对象大小,则放大时将裁剪图像
lv_img_set_zoom(img, 128);
lv_img_set_size_mode(img, LV_IMG_SIZE_MODE_REAL);
lv_img_set_zoom(img, 512);
lv_img_set_size_mode(img, LV_IMG_SIZE_MODE_REAL);