资源管理概述

对于嵌入式 GUI 项目而言,除了完成对控件的管理外,还需要对 GUI 所需的资源进行管理。一般来讲,GUI 项目的管理代码基本不大,主要占用 Code Size 的是图片和文字资源,如何合理管理这些资源对于整个 GUI 项目至关重要。

资源分类

EmbeddedGUI 将资源分为两大类:

内部资源(Internal Resource)

内部资源直接编译到固件中,存储在芯片的 Flash(ROM)里。

  • 访问速度快,无需额外的加载逻辑

  • 占用芯片内部 Code Size

  • 适合高频访问的小尺寸资源(常用图标、主界面字体等)

生成的文件格式:

  • 图片:egui_res_image_xxxxx.c,包含像素数组和配置信息

  • 字体:egui_res_font_xxxxx.c,包含字形像素矩阵和编码映射

外部资源(External Resource)

外部资源存储在外部存储介质(SPI Flash、SD 卡等),运行时按需加载。

  • 不占用芯片内部 Code Size

  • 需要实现 load_external_resource 平台接口

  • 适合大尺寸资源(高分辨率图片、多语言字体等)

生成的文件格式:

  • 图片:egui_res_image_xxxxx_bin.c(配置信息)+ .bin(二进制数据)

  • 字体:egui_res_font_xxxxx_bin.c(配置信息)+ .bin(二进制数据)

  • 合并文件:app_egui_resource_merge.bin(所有外部资源打包)

资源目录结构

每个示例应用的资源目录结构如下:

example/HelloXXX/
├── resource/
│   ├── src/
│   │   ├── app_resource_config.json    # 资源配置文件
│   │   ├── star.png                     # 原始图片文件
│   │   ├── optional_local_font.ttf      # 非 build-in 字体时放这里
│   │   └── supported_text.txt           # 所需文本列表
│   ├── font/                            # 生成的字体资源
│   ├── img/                             # 生成的图片资源
│   ├── app_egui_resource_generate.h     # 资源索引头文件
│   ├── app_egui_resource_generate.c     # 外部资源偏移表
│   ├── app_egui_resource_merge.bin      # 外部资源合并文件
│   └── app_egui_resource_generate_report.md  # 资源统计报告

app_resource_config.json 配置

资源配置使用 JSON5 格式(支持注释),包含 imgfont 两个数组。

图片资源配置

{
    "img": [
        {
            "file": "star.png",
            "name": "star",
            "external": "0",
            "format": "rgb565",
            "alpha": "4",
            "dim": "-1,-1",
            "rot": "-1",
            "swap": "0"
        }
    ]
}

参数

说明

可选值

file

原始图片文件名

*.png, *.jpg, *.bmp

name

资源名称(可选,默认用文件名)

自定义字符串

external

存储位置

0=内部, 1=外部, all=两者都生成

format

像素格式

rgb565, rgb32, gray8, all

alpha

Alpha 位深

0, 1, 2, 4, 8, all

dim

缩放尺寸

"宽,高", "-1,-1"=不缩放

rot

旋转角度

角度值, "-1"=不旋转

swap

RGB565 字节交换

0=不交换, 1=交换

字体资源配置

{
    "font": [
        {
            "file": "build_in/Montserrat-Medium.ttf",
            "name": "demo_font",
            "text": "supported_text.txt",
            "external": "0",
            "pixelsize": "16",
            "fontbitsize": "4"
        }
    ]
}

参数

说明

可选值

file

TTF 字体文件名

resource/src/*.ttfbuild_in/xxx.ttf

text

所需文本列表文件

*.txt(UTF-8 编码)

external

存储位置

0=内部, 1=外部, all=两者都生成

pixelsize

字体像素大小

4-32, all

fontbitsize

字形位深

1, 2, 4, 8, all

相同字体文件、相同参数的多个配置项会自动合并文本列表,重复文字会去重。 优先直接引用 scripts/tools/build_in/ 中的内置字体;只有 build-in 不满足时才把额外 TTF 放到 resource/src/

资源生成命令

# 生成资源(检查 merge.bin 是否存在,不存在才生成)
make resource APP=HelloResourceManager

# 强制重新生成资源
make resource_refresh APP=HelloResourceManager

资源生成脚本 app_resource_generate.py 会:

  1. 解析 app_resource_config.json 配置

  2. 调用 img2c.py 转换图片资源

  3. 调用 ttf2c.py 转换字体资源

  4. 生成 app_egui_resource_generate.h(资源声明和外部资源 ID 枚举)

  5. 生成 app_egui_resource_generate.c(外部资源偏移地址表)

  6. 将所有外部资源打包为 app_egui_resource_merge.bin

  7. 生成 app_egui_resource_generate_report.md(资源统计报告)

生成产物说明

app_egui_resource_generate.h

包含所有资源的 extern 声明和外部资源 ID 枚举:

// 资源声明
extern const egui_image_std_t egui_res_image_star_rgb565_4;
extern const egui_image_std_t egui_res_image_star_rgb565_4_bin;
extern const egui_font_std_t egui_res_font_test_16_4;

// 外部资源 ID 枚举
enum {
    EGUI_EXT_RES_ID_BASE = 0x00,
    EGUI_EXT_RES_ID_EGUI_RES_IMAGE_STAR_RGB565_4_DATA,
    EGUI_EXT_RES_ID_EGUI_RES_IMAGE_STAR_RGB565_4_ALPHA,
    // ...
    EGUI_EXT_RES_ID_MAX,
};

extern const uint32_t egui_ext_res_id_map[EGUI_EXT_RES_ID_MAX];

app_egui_resource_merge.bin

所有外部资源的二进制打包文件,可直接烧录到外部 Flash。egui_ext_res_id_map 数组记录了每个资源在 bin 文件中的偏移地址。

资源统计报告

app_egui_resource_generate_report.md 以 Markdown 表格形式展示每个资源的 Code Size 占用,方便开发者评估资源使用情况。

在代码中使用资源

#include "app_egui_resource_generate.h"

// 使用内部图片资源
egui_view_image_set_image(EGUI_VIEW_OF(&image), (egui_image_t *)&egui_res_image_star_rgb565_4);

// 使用外部图片资源(名称带 _bin 后缀)
egui_view_image_set_image(EGUI_VIEW_OF(&image), (egui_image_t *)&egui_res_image_star_rgb565_4_bin);

// 使用字体资源
egui_view_label_set_font(EGUI_VIEW_OF(&label), (egui_font_t *)&egui_res_font_test_16_4);

使用外部资源时,需要在 app_egui_config.h 中启用:

#define EGUI_CONFIG_FUNCTION_RESOURCE_MANAGER  1
#define EGUI_CONFIG_FUNCTION_EXTERNAL_RESOURCE 1

并在平台驱动中实现 load_external_resource 接口。