基于ESP-IDF的ESP32-C3驱动TFT屏幕播放GIF图片方案
创作时间:
作者:
@小白创作中心
基于ESP-IDF的ESP32-C3驱动TFT屏幕播放GIF图片方案
引用
CSDN
1.
https://blog.csdn.net/qq_41126242/article/details/143907673
本文介绍了一种基于ESP-IDF框架的解决方案,展示了如何使用ESP32-C3驱动TFT屏幕播放GIF图片。该方案重点解决了内存限制问题,通过逐帧解码和部分屏幕更新实现了GIF的流畅播放。
方案实现思路
- 逐帧解码 GIF:使用流式读取方式逐帧解码 GIF 文件。
- 优化屏幕刷新:采用小区域更新,减少显示缓冲区的内存使用。
- SPIFFS 文件系统:将 GIF 文件存储在 SPIFFS 文件系统中。
- 内存优化:使用较小的解码缓冲区并分段更新显示。
完整代码
1. 设置项目配置
在 ESP-IDF 项目中,先配置 SPIFFS 文件系统和 TFT 屏幕:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "esp_system.h"
#include "esp_log.h"
#include "esp_spiffs.h"
#include "driver/spi_master.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "tftspi.h"
#include "tft.h"
#include "gifdec.h"
#define TAG "GIF_PLAYER"
// 屏幕分辨率
#define SCREEN_WIDTH 240
#define SCREEN_HEIGHT 320
// SPIFFS 文件路径
#define GIF_FILE_PATH "/spiffs/sample.gif"
2. 初始化 SPIFFS 文件系统
SPIFFS 用于存储和读取 GIF 文件:
void init_spiffs() {
esp_vfs_spiffs_conf_t conf = {
.base_path = "/spiffs",
.partition_label = NULL,
.max_files = 5,
.format_if_mount_failed = true
};
esp_err_t ret = esp_vfs_spiffs_register(&conf);
if (ret != ESP_OK) {
ESP_LOGE(TAG, "Failed to initialize SPIFFS");
return;
}
size_t total = 0, used = 0;
ret = esp_spiffs_info(NULL, &total, &used);
if (ret != ESP_OK) {
ESP_LOGE(TAG, "Failed to get SPIFFS partition information");
} else {
ESP_LOGI(TAG, "SPIFFS total: %d, used: %d", total, used);
}
}
3. 初始化 TFT 屏幕
使用 TFT_eSPI 或 TFT 自定义库初始化屏幕:
void init_tft() {
tft_spi_init();
TFT_init();
TFT_fillScreen(TFT_BLACK);
TFT_setRotation(LANDSCAPE);
TFT_setFont(DEFAULT_FONT, NULL);
}
4. GIF 解码和显示逻辑
使用 gifdec 库解码 GIF 文件,每次仅加载一帧到内存:
static gd_GIF *gif;
void display_frame(gd_GIF *gif) {
uint8_t *frame = heap_caps_malloc(gif->width * gif->height * 3, MALLOC_CAP_8BIT);
if (!frame) {
ESP_LOGE(TAG, "Failed to allocate memory for GIF frame");
return;
}
if (gd_get_frame(gif, frame)) {
for (int y = 0; y < gif->height; y++) {
for (int x = 0; x < gif->width; x++) {
int index = (y * gif->width + x) * 3;
uint16_t color = TFT_Color565(frame[index], frame[index + 1], frame[index + 2]);
TFT_drawPixel(gif->fx + x, gif->fy + y, color);
}
}
}
free(frame);
}
5. 播放 GIF 的任务
实现一个任务逐帧解码和显示 GIF:
void gif_player_task(void *pvParameter) {
FILE *f = fopen(GIF_FILE_PATH, "r");
if (!f) {
ESP_LOGE(TAG, "Failed to open GIF file");
vTaskDelete(NULL);
}
gif = gd_open_gif(f);
if (!gif) {
ESP_LOGE(TAG, "Failed to decode GIF");
fclose(f);
vTaskDelete(NULL);
}
while (1) {
display_frame(gif);
vTaskDelay(pdMS_TO_TICKS(gif->gce.delay * 10)); // 根据 GIF 帧延迟设置播放间隔
if (!gd_next_frame(gif)) {
gd_rewind(gif); // 播放完毕重新开始
}
}
gd_close_gif(gif);
fclose(f);
vTaskDelete(NULL);
}
6. 主程序入口
初始化系统并创建 GIF 播放任务:
void app_main(void) {
ESP_LOGI(TAG, "Initializing SPIFFS...");
init_spiffs();
ESP_LOGI(TAG, "Initializing TFT...");
init_tft();
ESP_LOGI(TAG, "Starting GIF player...");
xTaskCreate(gif_player_task, "gif_player_task", 8192, NULL, 5, NULL);
}
关键优化点
- 逐帧解码:
- 每次解码并显示一帧,释放上一帧的内存,避免一次性占用大量 RAM。
- 显示区域优化:
- 只更新变化的帧部分,减少显示缓冲区的大小。
- GIF 文件压缩:
- 尽量使用低分辨率、较少颜色的 GIF 文件。
- SPIFFS 文件系统:
- 确保 GIF 文件位于 SPIFFS 中,减少 I/O 操作开销。
测试与结果
运行此代码后,你的 ESP32-C3 应能流畅地在 TFT 屏幕上播放 GIF 动画,且不会占用过多内存。如果需要进一步优化或解决问题,可以分享更多详细场景和需求,我会协助调整代码!
热门推荐
蛇年第一天,这样庆祝才够味儿!
崩坏:星穹铁道【V1.1攻略】银狼 最好的选择是击破特攻?如何做到五重降防
Word中截图的四种实用方法,让文档更生动!
在《英雄联盟》中轻松截图的完美技巧与方法
《崩坏:星穹铁道》加拉赫培养心得
淄博曹村:千年古村的文化保护与传承之路
曹村马家坡杏花季摄影大赛,快来秀出你的大片吧!
淄博古村落一日游:千年古迹与文化传承
依折麦布片的副作用
了解 Ozempic:用途、副作用和饮食注意事项
依折麦布片的功效及副作用分别是什么
洗发水含有水杨酸,孕妈妈们还能放心洗头吗?
【母乳喂养日】宝宝要出生了,准父母们需要备点奶粉带去医院吗?
未来势不可挡!2024 年农业科技的 9 项发展趋势。
巴中高质量发展:农业工业化、工业高端化、文旅市场化
从主题设定到后续反馈:一场完美聚会的全方位策划指南
从青牛白马到九城之路:唐诗中的长安盛景
2023版高血压食养指南发布:限盐减钠是关键
邯郸:3000年古城里的成语故事与太极传奇
舟山:千岛之城的海景、文化与美食全攻略
成语之都邯郸:交通文化遗产融入现代交旅体系
外星人之谜:科学幻想下的宇宙探索
中科院团队揭示贵德沙蜥体色适应性进化机制
什么是结构色,结构色的发展历程
颜色错觉:揭秘视觉感知的奇妙迷雾
央视蛇年春晚首次联排阵容、内容曝光,最担心的事情还是发生了
事实证明,逼赵本山退出央视春晚的不是宋丹丹,更不是老搭档范伟
【健康科普】科学预防 健康同行---秋季常见传染病防控知识宣传
为带状疱疹患者解除病痛
哪些人容易得带状疱疹?关注带状疱疹3大高风险人群,积极预防主动免疫