图片资源
Solution 采用一套代码适配 SiFli 全系列芯片,并兼容多种选型方案。为确保跨芯片、跨方案的一致性,图片资源的存放与管理遵循统一规范。Butterfli 工具会根据 menuconfig 的配置(对应不同方案)自动适配编译逻辑,满足各类场景下的资源生成需求。
图片资源的位置
图片仅支持png、gif、h264的视频
内置图片资源统一放在
solution\examples\xxx\resource\images
目录下面。为便于管理,同时针对NAND/eMMC文件系统方案打开文件太慢,建议每个应用单独一个文件夹。在文件夹下面,则由分辨率子目录以及common来组成。
分辨率子目录说明如下:
分辨率目录 |
说明 |
---|---|
common |
所有分辨率共用的图片资源 |
410x494 |
某工程使用分辨率,存放该分辨率下专门的图片。一个产品类型可以支持很多产品,需要换行的地方因此,可以根据客户的需求存放多个分辨率。Butterfli会根据工程支持的分辨率, |
图片存放类型子目录说明如下:
图片存放目录 |
说明 |
---|---|
ezip_dither |
支持565时,存放需要非旋转但有渐进色的图片 |
ezip |
存放非旋转的图片 |
no_ezip |
存放需要旋转的图片 |
gif |
存放gif图片 |
h264 |
存放h264的视频 |
mask |
存放作为mask的图片。ezip会抽取该图片所有像素的alpha |
jpg |
存放jpg图片,支持Baseline类型 |
png的图片会使用ezip压缩工具进行转换,实现图片资源到方案所需格式的转换。图片的压缩率视图片的复杂度决定,压缩后的图片可以达到1/2~1/20之间,其中,png的转换原则是:
带alpha的图片默认转换为带alpha的图片;不带alpha的图片默认转换为不带alpha的图片
如果方案仅支持565,则ezip在转换888到565的时候,考虑到渐进色,需要使用dither避免图片出现分层和失真。因此,对于有渐进色的图片,需要专门放在dither目录。ezip默认会直接转换(不做dither),以降低转换后的size
外置表盘/应用
外置表盘/应用需要单独编译和推送,因此其资源是直接放在应用的目录下。遵循存放规则同上

图片访问
NAND/eMMC方案,可以使用文件系统的方式也可以使用builtin_res的方式。
使用文件系统的方式时,图片资源是放在文件系统中的,因此访问图片的时候,需要传路径+文件名
使用builtin_res的方式时,图片资源是以C数组的形式参与编译的,因此访问图片资源时,实际上传的是地址
NOR方案时,图片资源是以C数组的形式参与编译的,因此访问图片资源时,实际上传的是地址。
外置表盘/应用是以文件方式是存储资源的,因此访问图片的时候,传的是路径+文件名
所有的图片访问,将使用app_moudle.h中定义的宏。编译时,会根据menuconfig配置的
SOLUTION_RES_USING_NAND
、SOLUTION_RES_BUILT_IN
来决定获取图片的方式没有定义
SOLUTION_RES_USING_NAND
时,则为nor方案定义
SOLUTION_RES_USING_NAND
,但没有定义SOLUTION_RES_BUILT_IN
时,则使用的是文件系统定义
SOLUTION_RES_USING_NAND
,且定义SOLUTION_RES_BUILT_IN
时,则使用的是builtin_res的方案
使用APP_GET_IMG
获取png图片:
lv_obj_t *bg_clock = lv_img_create(bg_cont, NULL);
lv_img_set_src(bg_clock, APP_GET_IMG(img_analog_bg_clock));
使用APP_GET_GIF
获取gif图片:
lvsf_gif_anim_t *charge_gif = lvsf_gif_anim_init(parent,
APP_GET_GIF(gif_charge_flash),
APP_GET_IMG(img_charge_flash),
0,
0,
LV_DISP_DEF_REFR_PERIOD * 3,
100);
使用APP_GET_IMG_FROM_PTR
获取png图片,针对结构数组的场景:
static ezipa_src_t ezipa_src[] =
{
{APP_GET_IMG(spark1_thum), APP_GET_IMG(spark1) },
{APP_GET_IMG(spark2_thum), APP_GET_IMG(spark2) },
};
lv_obj_t *apng_img = lv_ezipa_create(parent, NULL);
lv_ezipa_set_src(apng_img, APP_GET_IMG_FROM_PTR(ezipa_src[ezipa_idx].ezipa));
使用APP_GET_GIF_FROM_PTR
获取gif图片,针对结构数组的场景。
static gif_src_t gif_src[] =
{
{APP_GET_IMG(spark1_thum), APP_GET_GIF(gif_spark1) },
{APP_GET_IMG(spark2_thum), APP_GET_GIF(gif_spark2) },
};
lvsf_gif_anim_t *charge_gif = lvsf_gif_anim_init(parent,
APP_GET_GIF(gif_src[gif_idx].gif)),
APP_GET_IMG(img_charge_flash),
0,
0,
LV_DISP_DEF_REFR_PERIOD * 3,
100);
使用APP_GET_H264
获取h264视频。
p_clk_video->video_player.fd = open(APP_GET_H264(VIDEO_SRC), O_RDONLY | O_BINARY);
文件系统中,图片存放的路径
参见“FLASH分配”中excel表格中定义的图片路径
外置应用的具体路径参见“app_module.h”
NAND/eMMC方案分目录访问图片
NAND/eMMC方案使用文件系统,为加速open图片的时间,方案提供了分目录存放在文件系统的方案。为此,需要遵守以下规则:
每个访问图片的C文件需要指明其图片访问哪一个子目录 \
例:app_mainmenu.c是一个主菜单的应用,该程序访问的图片在“mainmenu”的子目录下面,因此需要做如下的定义
#include "global.h"
#include "app_mainmenu.h"
#define _MODULE_NAME_ "mainmenu"
#include "app_module.h"
支持序列帧打包
文件系统中,每张图片都会生成一个bin,在一个page的UI上的元素特别多的情况下,会生成特别多的文件,造成存储空间较大且浪费,而且访问较慢的情况出现。为此,Solution提供了序列帧打包的机制。
需要打包的序列帧,需要每张图片图片名遵循:图片名_序列号组成
添加子目录,子目录的名字规则为: 图片名___seq,图片名___seq___xxx。注意,三个下划线。其中,图片名___seq默认是从序号0开始(也可以写作___seq___);___seq___xxx默认是从序号xxx开始
访问图片通过
lv_img_set_src_seq(lv_obj_t * obj, const void * src, uint16_t no)
进行设置。
Solution使用butterfli一键编译以后,图片生成之后存放的位置
butterfli调用ezip遍历resource/images目录,对common目录以及对应分辨率目录的图片资源(png)进行转换
图片存放目录 |
说明 |
---|---|
ezip_dither |
转换为ezip bin/c file,当分辨率为565时,做dither |
ezip |
转换为ezip bin/c file,当分辨率为565时,不做dither |
no_ezip |
转换为pixel bin/c file, 当分辨率为565时,做dither |
gif |
转换为agif bin/c file |
h264 |
转换h264或c file |
mask |
ezip会抽取该图片所有像素的alpha,转换为pixel bin/c file |
jpg |
转换jpg或c file |
图片以文件访问时,butterfli会调用ezip生成的bin文件,bin文件的位置如下:
说明:其中,bin是以文件的方式打包在文件系统中。存放在文件系统中的位置由flash_map.xls定义图片以NOR方案或builtin_res访问时,butterfli会调用ezip生成的c文件,c文件的位置如下: