详细代码注释:esp32通过 SD 卡读取图片文件,并在 TFT 显示屏上循环展示
·
// 引入SD卡功能库 - 让开发板能读取SD卡中的文件
#include <SD.h> // 提供SD卡文件系统操作功能
#include <SPI.h> // SPI通信协议库,用于与SD卡通信
#include <TFT_eSPI.h> // TFT显示屏驱动库
#include <TJpg_Decoder.h> // JPEG图片解码库
#define SD_CS 5 // 定义SD卡的片选引脚为5号
const int maxFiles = 100; // 最多存储100个图片文件名
TFT_eSPI tft = TFT_eSPI(); // 创建显示屏对象
String jpgFiles[maxFiles]; // 存储JPG文件名称的数组
int fileCount = 0; // 当前找到的JPG文件数量
String folder = "/test"; // 图片存放的文件夹路径
// JPEG解码回调函数,将解码后的图像块显示到屏幕
bool tft_output(int16_t x, int16_t y, uint16_t w, uint16_t h, uint16_t *bitmap) {
if (y >= tft.height()) return 0; // 如果图像超出屏幕底部则停止解码
tft.pushImage(x, y, w, h, bitmap); // 将图像块推送到屏幕指定位置
return 1; // 返回继续解码信号
}
// 遍历指定文件夹,查找并记录所有JPG文件
void listJpgFiles(String dir) {
File root = SD.open(dir); // 打开指定目录
if (!root) { // 检查目录是否成功打开
Serial.println("文件夹打开失败"); // 打印错误信息
return; // 目录打开失败则退出函数
}
Serial.println("正在扫描JPG文件:"); // 提示开始扫描文件
while (true) { // 无限循环,直到遍历完所有文件
File file = root.openNextFile(); // 获取下一个文件
if (!file) break; // 没有更多文件时退出循环
// 检查是否为文件且为JPG格式
if (!file.isDirectory() && isJpgFile(file.name())) {
Serial.print("找到文件: "); // 打印找到的文件名
Serial.println(file.name());
if (fileCount < maxFiles) { // 检查是否超过最大文件数
jpgFiles[fileCount] = file.name(); // 保存文件名到数组
fileCount++; // 文件计数加1
} else {
Serial.println("已达到最大文件数限制"); // 提示文件数量已达上限
break; // 退出循环
}
}
file.close(); // 关闭当前文件
}
root.close(); // 关闭目录
}
// 缩放并显示指定路径的JPG图片
void scalePic(String fileName) {
tft.fillScreen(TFT_BLACK); // 清屏为黑色
uint16_t w = 0, h = 0; // 定义变量存储图片宽高
TJpgDec.getSdJpgSize(&w, &h, fileName); // 获取图片尺寸
Serial.print("图片尺寸: "); // 打印图片原始尺寸
Serial.print(w);
Serial.print("x");
Serial.println(h);
// 计算图片高度与屏幕高度的比例
float heightRatio = static_cast<float>(h) / tft.height();
// 根据比例设置缩放因子
if (heightRatio > 4) {
TJpgDec.setJpgScale(8); // 高度超过屏幕4倍时,缩放8倍
} else if (heightRatio > 2) {
TJpgDec.setJpgScale(4); // 高度超过屏幕2倍时,缩放4倍
} else if (heightRatio > 1) {
TJpgDec.setJpgScale(2); // 高度超过屏幕时,缩放2倍
} else {
TJpgDec.setJpgScale(1); // 高度小于屏幕时,不缩放
}
Serial.print("缩放比例: "); // 打印缩放比例
Serial.println(heightRatio);
// 从SD卡读取并绘制JPG图片,从坐标(0,0)开始
TJpgDec.drawSdJpg(0, 0, fileName);
}
// 判断文件是否为JPG格式
bool isJpgFile(String name) {
// 检查文件名是否以常见JPG扩展名结尾,且不是隐藏文件
return !name.startsWith(".") &&
(name.endsWith(".jpg") || name.endsWith(".JPG") ||
name.endsWith(".jpeg") || name.endsWith(".JPEG"));
}
// 开发板启动时执行的初始化函数
void setup() {
Serial.begin(115200); // 初始化串口通信,波特率115200
SPI.begin(); // 初始化SPI通信
if (!SD.begin(SD_CS)) { // 初始化SD卡
Serial.println("SD卡初始化失败"); // SD卡初始化失败提示
return; // 失败则退出setup函数
}
Serial.println("SD卡初始化成功"); // SD卡初始化成功提示
tft.begin(); // 初始化TFT显示屏
tft.fillScreen(TFT_BLACK); // 清屏为黑色
tft.setSwapBytes(true); // 设置字节交换,确保颜色显示正确
tft.setRotation(0); // 设置屏幕旋转角度为0度
// 设置JPEG解码器的回调函数为tft_output
TJpgDec.setCallback(tft_output);
// 扫描指定文件夹中的JPG文件
listJpgFiles(folder);
Serial.print("共找到 "); // 打印找到的文件数量
Serial.print(fileCount);
Serial.println(" 个JPG文件");
}
// 开发板主循环,不断重复执行
void loop() {
// 遍历所有找到的JPG文件
for (int i = 0; i < fileCount; i++) {
String filePath;
// 构建完整文件路径
if (folder == "/") {
filePath = "/" + jpgFiles[i]; // 根目录下的文件
} else {
filePath = folder + "/" + jpgFiles[i]; // 子目录下的文件
}
scalePic(filePath); // 显示当前图片
Serial.print("显示图片: "); // 打印当前显示的图片名称
Serial.println(filePath);
delay(5000); // 延时5秒后切换下一张
}
}
更多推荐
所有评论(0)