LVGL图片显示开发指南*
第一章 概述*
国芯微针对 GIF 格式的图片,实现了自有专利的 QGIF 动画技术,让 GX8302 大幅降低了 Flash 的占用,并提升动画帧率。典型动画压缩率可达10倍以上,帧率>30fps。 国芯微针对 PNG 格式的图片,也实现了自有专利的压缩技术,可以快速的解码显示和降低 Flash 占用。
注意
原始图片长和宽需要4像素对齐,比如40*40,360*120
第二章 图片转化工具*
2.1 linux本地工具*
在 linux pc 上,输入:pip install qgif
注意:python版本要求>=2.6
2.2 在线工具*
在线工具: https://imageconverter.nationalchip.com/
第三章 图片转换和显示开发*
2.3 GIF图片转化*
假设我们有一张gif图片,名称为:hello.gif,大小是 360x360
如果安装了linux本地工具,使用命令:
qgif convert -i hello.gif -o output.qgif -f gx96 -l
在目录下会生产output.c文件,该文件是 lvgl 的图片C格式,可以被 lvgl 直接使用
在 output.c 里,可以看到已经定义了如下结构体:
const lv_img_dsc_t output = {
.header.cf = LV_IMG_CF_RAW_CHROMA_KEYED,
.header.always_zero = 0,
.header.reserved = 0,
.header.w = 360,
.header.h = 360,
.data_size = 691537,
.data = output_bin,
};
可以使用 --scale-size 参数进行缩放:
qgif convert -i hello.gif -o output.qgif -f gx96 --scale-size 240 240 -l
不过,为了保证图片的最佳效果,建议美工直接做好,不使用缩放功能
或者使用在线转换工具:
gx96 的图片质量会好于 gx64,但是图片体积也会更大。用户可以自己根据情况选择。
2.4 PNG图片转化*
使用在线转换工具:
gx96 不带 Alpha 通道的,gx96a 带 Alpha 通道的 gx96 的图片质量会好于 gx64,但是图片体积也会更大
第三章 示例演示*
3.1 图片资源作为C数组方式*
参考 SDK 里 apps\lvgl_gif_sample 这个例子
支持 QGIF 需要在 app_lv_conf.h 开启如下宏:
#define LV_USE_GX_GA_LITE 1
程序运行后,可以在命令行输入:
qgif_img_test 或者 png_img_test 看两种图片的显示效果
QGIF 效果示例:
3.2 图片资源作为文件形式*
app_lv_conf.h中定义:
#define LV_USE_QGIF 1
#define LV_USE_FS_FATFS 1
#define LV_FS_FATFS_LETTER 'S'
代码中读SD卡中文件:
lv_obj_t * hello1_obj = lv_qgif_create(lv_scr_act(), malloc, free);
lv_qgif_set_src(hello1_obj, "S:/qgif/hello1.qgif"); // 驱动器号S需要和LV_FS_FATFS_LETTER相同
整体视频效果: https://mp.weixin.qq.com/s/HKsvxZA_dhdKWtXMmzk4Jg
3.3 图片资源作为bin文件格式*
使用A.bmp图片测试,文件大小为240x135
lvgl官方在线图片转换工具地址:https://lvgl.io/tools/imageconverter
选择:LV_IMG_CF_TRUE_COLOR 和 Binary RGB565 Swap方式生成A.bin文件,并自定义文件存放于flash 0x100000的位置
将图片资源烧录到指定的flash位置
#define TO_XIP_ADDR(addr) (unsigned char*)(0x13000000 + (unsigned int)addr)
const lv_img_dsc_t test_img_origin = {
.header.always_zero = 0,
.header.reserved = 0,
.header.w = 240,
.header.h = 135,
.data_size = 240*135 * LV_COLOR_SIZE / 8,
.header.cf = LV_IMG_CF_TRUE_COLOR,
.data = TO_XIP_ADDR(0x100000+0x04), // lvgl生成的bin文件,从 bin 文件读取,每个图片 bin 的前 4 bytes 为 header 信息。因此图片数据需要偏移4字节
};
static void normal_img_test(void)
{
lv_obj_t * act_scr = lv_scr_act();
if (act_scr)
{
lv_obj_clean(act_scr);
}
LV_IMG_DECLARE(test_img_origin);
lv_obj_t * img1 = lv_img_create(lv_scr_act());
lv_img_set_src(img1, &test_img_origin);
}
重要
如果使用qgif的话,生成的bin文件是不带4字节头部信息的,因此不需要偏移
#define TO_XIP_ADDR(addr) (unsigned char*)(0x13000000 + (unsigned int)addr)
const lv_img_dsc_t standby_ani = {
.header.cf = LV_IMG_CF_RAW_CHROMA_KEYED,
.header.always_zero = 0,
.header.reserved = 0,
.header.w = 360,
.header.h = 360,
.data_size = 672285,
.data = TO_XIP_ADDR(0xC00000),
};
static void *qgif_malloc(uint32_t size)
{
return (void*)psram_malloc(size);
}
static void qgif_free(void *ptr)
{
psram_free(ptr);
}
static void qgif_img_test(void)
{
lv_obj_t * act_scr = lv_scr_act();
if (act_scr)
{
lv_obj_clean(act_scr);
}
LV_IMG_DECLARE(standby_ani);
lv_obj_t * qgif_gx96_obj = lv_qgif_create(lv_scr_act(), qgif_malloc, qgif_free);
lv_qgif_set_src(qgif_gx96_obj, &standby_ani);
lv_obj_align(qgif_gx96_obj, LV_ALIGN_CENTER, 0, 0);
}