跳到主要内容

使用外部图像文件

此前,我们仅支持将图像变量作为图像组件的图像源,这就要求所有引用的图像都必须经过转换并硬编码到应用程序中。

但在某些情况下,你可能希望使用外部图像文件作为图像组件的图像源。常见的情况之一是在不重新构建应用程序的情况下替换图像。

从 v0.28.0 版本开始,我们已经支持这一功能。

启用配置

  • 前往 项目 - 项目配置...,启用 使用外部图像文件,并配置 路径前缀

  • lv_conf.h 定义解码器

    #define LV_USE_FS_STDIO 1 // Enable file system support

    #define LV_USE_PNG 1 // Enable PNG decoder
    #define LV_USE_JPEG 1 // Enable JPEG decoder
    #define LV_USE_BMP 1 // Enable BMP decoder
  • 实现并注册文件系统驱动程序以进行文件 I/O

    我们为模拟器提供了一个实现,你可以参考它并实现自己的。


    // simulator/dummy.c

    /* 1️⃣
    * File system callbacks for LVGL
    */
    static void *fs_open(lv_fs_drv_t *drv, const char *path, lv_fs_mode_t mode) {
    LV_UNUSED(drv);
    const char *flags = (mode == LV_FS_MODE_WR) ? "wb" : "rb";
    return fopen(path, flags);
    }

    static lv_fs_res_t fs_close(lv_fs_drv_t *drv, void *file) {
    LV_UNUSED(drv);
    fclose((FILE *)file);
    return LV_FS_RES_OK;
    }

    static lv_fs_res_t fs_read(lv_fs_drv_t *drv, void *file, void *buf,
    uint32_t btr, uint32_t *br) {
    LV_UNUSED(drv);
    *br = fread(buf, 1, btr, (FILE *)file);
    return (*br > 0) ? LV_FS_RES_OK : LV_FS_RES_UNKNOWN;
    }

    static lv_fs_res_t fs_seek(lv_fs_drv_t *drv, void *file, uint32_t pos,
    lv_fs_whence_t whence) {
    LV_UNUSED(drv);
    int origin = (whence == LV_FS_SEEK_SET) ? SEEK_SET
    : (whence == LV_FS_SEEK_CUR) ? SEEK_CUR
    : SEEK_END;
    fseek((FILE *)file, pos, origin);
    return LV_FS_RES_OK;
    }

    static lv_fs_res_t fs_tell(lv_fs_drv_t *drv, void *file, uint32_t *pos) {
    LV_UNUSED(drv);
    *pos = ftell((FILE *)file);
    return LV_FS_RES_OK;
    }

    /* 2️⃣ Register the file system */
    void register_fs() {
    static lv_fs_drv_t fs_drv;
    lv_fs_drv_init(&fs_drv);
    fs_drv.letter = 'S'; // Drive letter
    fs_drv.open_cb = fs_open;
    fs_drv.close_cb = fs_close;
    fs_drv.read_cb = fs_read;
    fs_drv.seek_cb = fs_seek;
    fs_drv.tell_cb = fs_tell;
    lv_fs_drv_register(&fs_drv);
    }
    // simulator/main.c
    extern void register_fs(void);

    int main() {
    ...
    register_fs();
    ...
    }

  • simulator 文件夹下的 lv_conf.h 文件中定义 USE_SIMULATOR,以在模拟器上启用模拟功能。

    #define USE_SIMULATOR
信息

如果由于内存分配失败而无法打开图像,请尝试增大 lv_conf.h 文件中的 LV_MEM_SIZE。

#  define LV_MEM_SIZE    (? * 1024U * 1024U)
注意

所有图像都应放置在设备 “路径前缀” 指定的目录中。 img 组件的尺寸应与图像的尺寸一致,因为将显示原始图像。