跳转至

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