ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

LVGL GIF 解码器集成指南:在 X-TRACK 码表模拟器中播放 GIF 动画

LVGL GIF 解码器集成指南:在 X-TRACK 码表模拟器中播放 GIF 动画 智能硬件嵌入式硬件开发【免费下载链接】X-TRACKA GPS bicycle speedometer that supports offline maps and track recording项目地址https://gitcode.com/gh_mirrors/xt/X-TRACK点击查看免费下载导读本文围绕 LVGL 官方文档 libs/gif.md 展开系统讲解在 LVGL 中启用并播放 GIF 动图的完整链路从lv_conf.h开关配置、lv_gif_create/lv_gif_set_src核心 API、两种图片来源C 数组与文件系统到帧播放与内存占用原理。X-TRACK 的 PC 模拟器正是基于 LVGL.Simulator 构建见 Simulator/LVGL.Simulator 目录本文同时结合仓库内lvgl/src/extra/libs/gif的源码实现进行纵深剖析读完你可以在 X-TRACK 模拟器环境中复现动图播放、为开机动画等场景接入 GIF 资源并能准确评估不同色深下的 RAM 开销。GIF 解码器是什么LVGL 内置的 GIF 解码器允许在 LVGL 应用中直接使用 GIF 图片其底层基于轻量级 GIF 解码库gifdeclecram/gifdec的移植仓库内实现位于 lvgl/src/extra/libs/gifgifdec.h / gifdec.cGIF 文件解析、LZW 解压与逐帧渲染lv_gif.h / lv_gif.c面向 LVGL 对象的封装把解码器输出包装成一个可自动逐帧刷新的控件。在文档 gif.md 中明确在lv_conf.h中启用LV_USE_GIF后即可调用lv_gif_create(parent)创建 GIF 控件而lv_gif_set_src(obj, src)的用法与lv_img_set_src高度一致——图片来源既可以是内存中的图片变量lv_img_dsc_t也可以是文件路径。第一步在 lv_conf.h 中启用 GIF 支持LVGL 各功能模块默认由lv_conf.h中的编译宏控制。在 X-TRACK 模拟器工程中配置文件位于 Software/X-Track/Simulator/LVGL.Simulator/lv_conf.h其中第 681 行#define LV_USE_GIF 0当前仓库默认将该功能关闭值为0。要使用 GIF 动画需将其改为1并重新编译工程#define LV_USE_GIF 1与之联动的是一个重要宏——颜色深度。同文件第 29 行#define LV_COLOR_DEPTH 16X-TRACK 模拟器运行在 16bit 色深下这直接决定了 GIF 解码所需的内存规模详见下文内存需求小节。文件来源还需启用文件系统驱动如果打算从文件系统读取.gif文件还需要在lv_conf.h中开启至少一个文件系统驱动。文档 gif.md 指出必须注册文件系统驱动后才能通过文件路径打开图片可选的开关形如LV_USE_FS_...。仓库lv_conf.h第 636661 行提供了四类候选#define LV_USE_FS_STDIO 0 #define LV_USE_FS_POSIX 0 #define LV_USE_FS_WIN32 0 #define LV_USE_FS_FATFS 0PC 模拟器Linux/Windows 桌面环境下通常开启LV_USE_FS_STDIO或LV_USE_FS_POSIX其挂载盘符在宏下方的配置块中设定如A或S若只使用 C 数组形式的内存来源则无需任何文件系统驱动。注意LV_USE_GIF、LV_COLOR_DEPTH、LV_USE_FS_*均为编译期配置改动后必须全量重新编译 LVGL 及其上层应用。核心 API 与对象模型三个公开接口从 lv_gif.h 可以看到 GIF 模块对外只暴露三个接口lv_obj_t * lv_gif_create(lv_obj_t * parent); /* 创建 GIF 控件 */ void lv_gif_set_src(lv_obj_t * obj, const void * src); /* 设置图片来源 */ void lv_gif_restart(lv_obj_t * gif); /* 从头重新播放 */lv_gif_create创建一个继承自lv_img_class的控件源码中lv_gif_class的.base_class lv_img_class见 lv_gif.c因此它也拥有普通图片控件的全部布局、对齐、事件能力lv_gif_set_src负责打开 GIF 并启动播放lv_gif_restart内部调用gd_rewind(gifobj-gif)lv_gif.c将解码位置回绕到第一帧重新播放适合点击重播类交互。控件内部结构lv_gif.h 中的lv_gif_t揭示了实现机制typedef struct { lv_img_t img; /* 内嵌一个图片控件作为显示载体 */ gd_GIF * gif; /* gifdec 解码器上下文 */ lv_timer_t * timer; /* 帧刷新定时器 */ lv_img_dsc_t imgdsc; /* 每帧解码结果包装成的图片描述符 */ uint32_t last_call; /* 上一帧的时间戳用于计算帧间隔 */ } lv_gif_t;可以推断GIF 控件本质上是一个图片控件 一个周期性定时器的组合。定时器在对象构造时创建、默认暂停lv_gif.c直到lv_gif_set_src成功加载资源后才恢复运行。两种图片来源与完整示例方式一使用 C 数组内存变量将 GIF 文件转换为字节数组后以lv_img_dsc_t变量形式传入。转换方式参考文档 gif.md使用 LVGL 官方提供的在线图片转换工具Image Converter输出格式选择C array颜色格式选择Raw。转换结果形如仓库示例 img_bulb_gif.c 中声明的img_blub_gif_map[]——一个以0x47, 0x49, 0x46即 ASCII GIF开头的原始字节数组本质就是原 GIF 文件的完整二进制内容。使用时代码如下LV_IMG_DECLARE(img_bulb_gif); /* 声明外部变量 */ lv_obj_t * gif lv_gif_create(lv_scr_act()); /* 创建控件 */ lv_gif_set_src(gif, img_bulb_gif); /* 以变量形式传入 */ lv_obj_align(gif, LV_ALIGN_CENTER, 0, 0); /* 与普通图片一致的布局接口 */方式二从文件系统读取文档给出的文件路径示例为lv_gif_set_src(obj, S:path/to/example.gif);其中S:是文件系统挂载盘符path/to/example.gif为盘符内的相对路径。仓库示例 lv_example_gif_1.c 演示了与变量方式并存的使用img lv_gif_create(lv_scr_act()); /* 假定文件系统挂载在盘符 A 上 */ lv_gif_set_src(img, A:lvgl/examples/libs/gif/bulb.gif); lv_obj_align(img, LV_ALIGN_RIGHT_MID, -20, 0);完整可运行示例结合两种来源一个完整的播放示例可组织为#include ../../lv_examples.h #if LV_USE_GIF LV_BUILD_EXAMPLES void lv_example_gif_1(void) { LV_IMG_DECLARE(img_bulb_gif); /* 引用转换好的 GIF 字节数组 */ /* 1) 从内存变量加载 */ lv_obj_t * img lv_gif_create(lv_scr_act()); lv_gif_set_src(img, img_bulb_gif); lv_obj_align(img, LV_ALIGN_LEFT_MID, 20, 0); /* 2) 从文件加载需已启用 LV_USE_FS_* 且挂载盘符为 A */ img lv_gif_create(lv_scr_act()); lv_gif_set_src(img, A:lvgl/examples/libs/gif/bulb.gif); lv_obj_align(img, LV_ALIGN_RIGHT_MID, -20, 0); } #endif播放结束后如需从头再来调用lv_gif_restart(img)即可。源码级原理解码、定时与帧渲染打开与校验流程lv_gif_set_src首先判断来源类型lv_gif.cif(lv_img_src_get_type(src) LV_IMG_SRC_VARIABLE) { gifobj-gif gd_open_gif_data(img_dsc-data); /* 内存变量 */ } else if(lv_img_src_get_type(src) LV_IMG_SRC_FILE) { gifobj-gif gd_open_gif_file(src); /* 文件路径 */ }gd_open_gif_file/gd_open_gif_datagifdec.c先建立统一的gd_GIF上下文再交由gif_open解析头部gifdec.c校验要点包括文件签名必须为GIF、版本必须为89a否则直接失败并输出LV_LOG_WARN逻辑屏幕描述符中必须存在全局颜色表fdsz 0x80缺失同样判定失败读取宽度、高度、色深、背景色索引等字段填入gd_GIF结构。打开成功后lv_gif_set_src将解码缓冲区包装成LV_IMG_CF_TRUE_COLOR_ALPHA格式的图片描述符并交给底层lv_img_set_srclv_gif.c随后恢复定时器并立即渲染首帧。逐帧播放的定时机制GIF 控件在构造函数中创建了一个10ms 周期的 LVGL 定时器lv_gif.c回调next_frame_task_cb负责推进帧。其核心逻辑lv_gif.cuint32_t elaps lv_tick_elaps(gifobj-last_call); if(elaps gifobj-gif-gce.delay * 10) return; /* 帧间隔未到跳过 */ gifobj-last_call lv_tick_get(); int has_next gd_get_frame(gifobj-gif); /* 解码下一帧 */ if(has_next 0) { /* 播放到结尾 */ if(gifobj-gif-loop_count 1) { /* 只播一次发就绪事件 */ lv_event_send(obj, LV_EVENT_READY, NULL); } else { /* 循环播放 */ if(gifobj-gif-loop_count 1) gifobj-gif-loop_count--; gd_rewind(gifobj-gif); } } gd_render_frame(gifobj-gif, (uint8_t *)gifobj-imgdsc.data); lv_img_cache_invalidate_src(lv_img_get_src(obj)); lv_obj_invalidate(obj);几个值得注意的细节帧间隔GIF 图形控制扩展GCE中的delay单位是 1/100 秒源码中乘以 10 换算为毫秒后与 10ms 定时器节拍比较决定是否绘制新帧循环次数gd_GIF.loop_count由 NETSCAPE 应用扩展读取。等于 1 表示只播一次播完发送LV_EVENT_READY可监听该事件做播放结束回调大于 1 则每轮递减并回绕继续播放渲染与失效gd_render_frame将当前帧合成到canvas缓冲区随后使图片缓存失效并标记控件重绘触发 LVGL 在下一轮刷新周期显示新帧。内存需求与 X-TRACK 色深评估文档 gif.md 给出的内存公式为解码并显示一张 GIF 动画所需 RAMLV_COLOR_DEPTH所需内存83 × 图片宽 × 图片高164 × 图片宽 × 图片高325 × 图片宽 × 图片高该公式与源码完全吻合gifdec.c 在gif_open阶段按色深一次性分配#if LV_COLOR_DEPTH 32 gif lv_mem_alloc(sizeof(gd_GIF) 5 * width * height); #elif LV_COLOR_DEPTH 16 gif lv_mem_alloc(sizeof(gd_GIF) 4 * width * height); #elif LV_COLOR_DEPTH 8 || LV_COLOR_DEPTH 1 gif lv_mem_alloc(sizeof(gd_GIF) 3 * width * height); #endif从源码结构可以推断多出的内存用于同时容纳canvas完整帧合成画布与frame当前帧解码缓冲两块区域色深越高、单像素字节越多开销越大。X-TRACK 模拟器配置的是LV_COLOR_DEPTH 16lv_conf.h因此播放一张 100×100 的 GIF 约需4 × 100 × 100 40 KB额外堆内存设计界面动图资源时应提前按此公式估算 RAM 预算若目标为真机如 AT32F4xx 系列见 MDK-ARM_F435 平台还需要与 LVGL 显示的帧缓冲等内存需求一并统筹。在 X-TRACK 模拟器中的应用与验证X-TRACK 是支持离线地图与轨迹记录的 GPS 自行车码表其 Simulator/LVGL.Simulator 是一个可在 PC 上运行的 LVGL 模拟器工程入口见 LVGL.Simulator.cpp仓库根目录的 Images/开机动画.mp4 也说明项目存在开机动画类动效需求。GIF 解码器可以为此类场景提供一种低成本的动图播放方案在模拟器中可按如下步骤验证将 lv_conf.h 中的LV_USE_GIF改为1若从文件读取将LV_USE_FS_STDIO或LV_USE_FS_POSIX改为1并把.gif文件放入对应挂载目录参考 lv_example_gif_1.c 编写页面代码将lv_gif_create创建的控件添加到目标页面如Pages下的页面见 USER/App/Pages重新编译并运行模拟器即可观察到逐帧播放的动画。需要注意GIF 解码属于逐帧软件渲染帧率受 CPU 与内存带宽影响模拟器上的表现与真机存在差异若页面较多、动画尺寸较大建议先用上文内存公式评估开销再决定动画素材的分辨率与帧数。常见问题与排查清单控件创建后不显示确认LV_USE_GIF已置 1 并重新编译确认图片来源路径/变量声明无误lv_gif_set_src加载失败会打印LV_LOG_WARN(Couldt load the source)见 lv_gif.c文件方式打不开检查LV_USE_FS_*是否启用、盘符字母是否与lv_conf.h挂载配置一致示例中为A:文档示例为S:解码失败确保 GIF 为 89a 版本且带全局颜色表参见 gifdec.c 的校验逻辑部分老旧 87a 文件或仅含局部色表的动图可能无法解析内存不足按LV_COLOR_DEPTH对应倍数核算每帧缓冲占用16bit 为 4×W×H必要时压缩 GIF 尺寸或帧数仅播放一次/不循环检查 GIF 的 NETSCAPE 循环扩展设置loop_count单次播放会触发LV_EVENT_READY事件可据此实现播放完毕跳转页面等逻辑。小结LVGL 的 GIF 解码器为嵌入式 UI 提供了一条开箱即用的动图能力LV_USE_GIF一个宏即可开启lv_gif_createlv_gif_set_src两个函数即可完成播放来源支持 C 数组与文件两种形态颜色深度直接决定内存开销。结合 X-TRACK 模拟器工程与 gif.md 文档你可以快速在模拟器中完成从配置、加载到播放的完整闭环并以此评估真机移植时的 RAM 预算。赞分享智能硬件嵌入式硬件开发【免费下载链接】X-TRACKA GPS bicycle speedometer that supports offline maps and track recording项目地址https://gitcode.com/gh_mirrors/xt/X-TRACK点击查看免费下载相关推荐在 Remotion 中播放 GIF / APNG / AVIF / WebP 动画图片AnimatedImage 与 Gif 组件完全指南在 Remotion 中播放 GIF / APNG / AVIF / WebP 动画图片 AnimatedImage 与 Gif 组件完全指南 本篇指南聚人工智能AI 应用前端MCP 服务【亲测免费】 jsgif: 在浏览器中生成和播放GIF动画的JavaScript库jsgif: 在浏览器中生成和播放GIF动画的JavaScript库 是一个轻量级、易于使用的JavaScript库用于在浏览器中生成和播放GIF动画。它提供前端音视频开发工具Chart.js终极指南从零开始掌握数据可视化神器Chart.js终极指南从零开始掌握数据可视化神器 Chart.js是一款功能强大且易用的数据可视化库它允许开发者通过简单的JavaScript代码创建各种文档教程上一篇jsoup CSS选择器完全教程像jQuery一样操作HTML的终极指南下一篇终极指南Vimium C跨浏览器兼容性全解析 - Chrome、Firefox、Edge最佳实践与常见问题解决创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表