LVGL学习笔记 21 - 图像Image

目录

1. 图像来源

1.1 图片源文件

1.2 颜色格式

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.2.5 LV_IMG_CF_RGB565A8

2. 显示图片

2.1 创建

2.2 申明

2.3 设置源

3. 样式

3.1 设置x/y方向上的偏移

3.2 设置支点

3.3 旋转

3.4 放大缩小

3.5 抗锯齿

3.6 设置图像大小模式


图像是显示来自闪存(作为数组)或来自文件的图像的基本对象。

1. 图像来源

和字库类似,可以通过在线转换工具将图片转换为LVGL支持的C数组或二进制文件。

Online image converter - BMP, JPG or PNG to C array or binary | LVGLhttps://lvgl.io/tools/imageconverter

离线版本(因为网络的问题,建议用这种方式)的使用方法:

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);

  • 8
    点赞
  • 36
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值