AI脑洞板
完整教案
自学课件
第 10 课 · 共 10/51 课

把照片装进板子——TF 卡里的图片 照片、文件和离线内容

课时
待定
器材
ESP32-S3 触摸屏板 + USB 线
前置知识
无
配套代码
见项目 demo 目录

你好,我是吴老师。这份是给你自己读的——看到让你停下来的地方,就照着做一遍。

前九课,屏幕有了颜色、能画点线圆方、能自己动、能听懂手指、还能显示中文。

可你有没有想过——照片怎么办?

你手机里那些照片,是怎么跑到这块小屏幕上的?它们不是画出来的,也不是写出来的,是拍出来的。一张照片,就是几万甚至几十万个颜色点,整整齐齐排在一起。

今天我们就把照片装进板子:插一张卡,读一张图,显示到屏幕上。顺便把一个很多人都会说错的常识弄明白——这张卡到底叫什么名字。


一、先说句让你安心的话:图片,还是像素点

你可能觉得"照片"很高级、很神秘。但它和我们已经学过的,是同一回事。

回想第 5 课:屏幕上每个点,都要告诉板子它是什么颜色。一张照片,不过是把这件事做到极致——把几十万个点的颜色,全部按位置记下来。

图片就是像素点

所以今天没有新概念,只补两件事:

  1. 这些点存在哪——在卡里的一个文件中;
  2. 怎么被读出来——照片通常被"压缩"过,要先"解压缩"才能显示。

打个比方:照片像一张巨大的马赛克拼图。第 5 课我们手动画几个点;照片是工厂预先拼好、几万个小方块一次性寄给你,你只要按编号贴到屏幕上。

比喻要修正:马赛克每块颜色是你定的;照片每块颜色是相机测出来的,你只负责"贴",不负责"选"。


二、文件、路径、目录:板子怎么找到一张图

这张卡对板子来说,像个小仓库。里面能放很多文件,用"路径"指路。

比如卡里 photo 文件夹里有张 cat.jpg,完整路径就是:

/photo/cat.jpg

开头的 / 是"仓库最外面那层",photo 是文件夹,cat.jpg 是文件。

板子要显示它,第一步就是顺着这条路找到它。路写错了(多一个斜杠、大小写不对),板子就睁眼说瞎话:"找不到。"

打个比方:路径像你家地址。"广州市天河区 xx 路 xx 号",错一个字快递员就送不到。给板子的路径也一样,一个字母都不能错。

比喻要修正:快递员会自己找;板子不会"猜",路径不对就直接放弃,连"大概附近"都不试。


三、贯穿全课的任务:让屏幕显示一只小猫

前面两节是铺垫:图片就是像素点、板子靠路径找文件。

现在真的动手。今天从头到尾只干一件事——

让这块屏幕上出现一只小猫。

听起来简单?可它要分四步,而且每一步都会遇到一个真实的坑:

步骤要做什么会在哪一节展开
第 1 步让 AI 画一只小猫本节
第 2 步转成板子认识的格式和尺寸本节
第 3 步存进 TF 卡第七节
第 4 步写程序,让它出现在屏幕上第七节

第 1、2 步现在就能做。 第 3、4 步要先学点东西(卡是什么、解码是怎么回事), 学到第七节我们再回来收尾。

从 AI 到 TF 卡的三步

后面每一节都会围着这只猫转 —— 所以请认真做第 1 步, 别随便找张图糊弄过去。它是你今天的作品。

第 1 步:让 AI 画一只小猫

请帮我生成一张图片,我要把它显示在一块小屏幕上。

【画什么】一只小猫

【画面要求】
- 只要一只猫,主体大、占满画面,不要背景里一堆东西;
- 构图简单,颜色明快,和背景对比明显;
- 不要文字、不要水印。

【尺寸要求】(这块屏幕是竖着的 240×320,比例 3:4)
请按 3:4 的竖幅构图生成,也就是"高比宽长"。
如果只能出正方形,请把猫放在中间,四周留出空间,方便我后面裁剪。

先只生成 1 张。

🐱 不想自己生成?这里有三只现成的

这三张已经处理成板子能读的格式(基线式 JPG、240×320、9~17 KB),挑一只你喜欢的:

橘猫 橘猫
黑猫 黑猫
虎斑猫 虎斑猫

在图片上右键 →「图片另存为」,存下来的就是能直接用的 JPG。 想一次拿全可以下整包:下载小猫示例包 cat-examples.zip (解压后直接是一个 photo 文件夹,拷进卡就能用)。

但强烈建议你先自己生成一只。 用现成的能跑通, 但"让 AI 画出我要的东西"这个本事,是今天真正要练的。 你可以先拿现成图跑通整条流程,再换自己生成的图 —— 这样最快。

想好了再点开:我们的参考选择

这不是标准答案。 但有几个选择会明显影响后面的效果:

你可以定参考做法为什么
什么猫橘猫、黑猫、戴帽子的猫…… 随你喜欢你后面要一直看着它,挑个你喜欢的
画面多复杂越简单越好:一只猫 + 纯色背景屏幕只有 240×320,细节多了糊成一团
什么风格扁平插画 / 卡通 / 简笔写实照片在小屏上反而看不清

为什么不建议"一只猫坐在花园里,后面有房子、树、云"?

  • 缩到 240×320 之后,猫只剩几十个像素,看不出是猫;
  • 而且画面越复杂,JPG 文件越大、解码越慢(第六节你会亲手量这个数字)。

挑图的原则:主体大、颜色少、对比强。 先在心里想一下:"这张图缩到巴掌大,我还能一眼看出是猫吗?"

第 2 步:转成板子认识的格式和尺寸

AI 画好的图,直接丢进板子是读不出来的。

这不是吓唬你。有三个真实的原因:

问题为什么板子受不了
格式是 PNG 或 WebP板子用的 TJpg_Decoder 只认 JPG,别的格式完全不认识
是"渐进式"JPG见下面 —— 这是最常见、也最坑的一个
尺寸太大(比如 1024×1024)解码慢、占内存;屏幕只有 240×320,多出来的像素纯属浪费

⚠️ 最坑的一个:渐进式 JPG

JPG 有两种"存法":

存法怎么读板子支持吗
基线式(Baseline)从上到下一行行解出来✅ 支持
渐进式(Progressive)先出一张模糊的,再一遍遍补细节❌ 不支持

很多 AI 生图工具、很多修图软件,默认就存成渐进式。

结果就是:图在电脑上看得好好的,一放进板子 —— 读不出来,或者花屏。 而且板子不会告诉你"这是渐进式的",它只会静静失败。又是一个"安安静静地做不好"。

基线式 vs 渐进式

这就是为什么"处理"这一步不能省。 不是多此一举,是必须把图转成板子认识的样子。

让 AI 帮你处理

请帮我写一个 Python 脚本,把一张图片处理成 ESP32 板子能读的 JPG。

【为什么要处理】板子用 TJpg_Decoder 库,它:
- 只认 JPG(不认 PNG/WebP);
- 只认"基线式"(baseline),不认"渐进式"(progressive);
- 屏幕只有 240×320(竖屏,比例 3:4)。

【脚本要做的事】
1. 读入我放在 ____ 文件夹里的小猫图;
2. 居中裁剪成 3:4,然后缩放到 ___×___(不超过 240×320);
3. 用 JPEG 保存,质量为 ___(你要在"文件大小"和"画质"之间选一个值);
4. **必须存成基线式(baseline),不能用渐进式** —— 这一点最重要;
5. 顺便打印处理后的:文件名、尺寸、文件大小(KB)。

【输出】存成 cat.jpg,我要放进板子的 /photo 文件夹。
请告诉我脚本需要装什么库,并说明每一句在干什么(我想看懂)。

处理完必须验证——别信"应该行了",要看数字:

请再写一个小脚本,检查我处理好的 cat.jpg:
1. 是不是基线式(baseline)?
2. 尺寸是不是 ____×____?
3. 多大(KB)?

如果不合格,告诉我不合格在哪。

本课附了一个现成的工具(在配套资源里):prepare_photos.py 它把上面两段提示词干的事一趟做完 —— 居中裁剪 → 缩放 → 存成基线式 → 逐张验证。

python prepare_photos.py --src 我的图 --out photo --size 240x320 --quality 85
python prepare_photos.py --src photo --check-only      # 只检查,不处理

但它只是个参考实现,不是唯一答案。建议你先按上面的提示词让 AI 自己写一版, 写完再和这个对一对 —— 看看它哪里做得比 AI 好、哪里不如。 (自己写一遍,才知道脚本里每一句在干什么。)

想好了再点开:我们的参考数字

这不是标准答案。 参考值:

参数参考值为什么
目标尺寸240×320正好铺满屏幕;想让解码更快可以填 120×160(缩小一半)
JPEG 质量85再高文件大、再低画面糊;85 足够
裁剪方式居中裁剪保证不变形(拉伸会让猫变扁)

**尺寸为什么值得你自己定?**它是"画质"和"速度"之间的取舍:

  • 240×320:最清晰,但解码最慢(第六节你会量出具体毫秒数);
  • 120×160:面积只有 1/4,解码快很多,代价是看得见颗粒;
  • 再小(比如 80×107):快是快了,但猫会糊成一团。

这个取舍,正是第六节"解码要多久"要量的东西。 你可以先按 240×320 做一版,等量完解码时间,再决定要不要改小 —— 这就是"用数据做决定"。

怎么判断"是不是渐进式"?

最省事的办法是让脚本自己报(上面那段验证提示词就是干这个的)。 如果你想知道它凭什么能判断出来,这里说破:

JPG 文件里有一个"标记",写着这张图是怎么存的:

标记含义
0xC0基线式(板子能读)
0xC2渐进式(板子读不了)

所谓"检查脚本",就是打开文件、找到这个字节、看一眼。不神秘。

另一个土办法:用看图软件"另存为"时,注意有没有 "渐进式 / Progressive" 这个勾选项 —— 把它勾掉,存出来的就是基线式。

顺便说一句:渐进式通常文件反而更小(它编码效率更高),所以很多工具默认就用它。 这就是"AI 生成的图直接丢进卡里读不出来"这么常见的原因 —— 不是你的错,是默认设置的问题。

到这儿,猫准备好了

现在你手上有一个 cat.jpg:基线式、240×320、9 KB 出头。

但屏幕还是黑的。 因为还差两件事没搞明白:

  1. 为什么要这么麻烦地转格式? JPG 到底是什么东西?→ 第四节
  2. 这张卡是什么?猫要怎么放进去? → 第五节

后面每一节,我们都会一直用这只猫当例子 —— 它有多大、它怎么被压缩、 它读出来要多久,全都围着它转。


四、为什么照片要"解压缩"才能看

前面你把猫转成了 cat.jpg,才 9 KB 左右 —— 小得可以塞进任何卡里。

可你有没有想过:屏幕上一只那么大的猫,怎么可能只占 9 KB?

答案在下面。这是今天最容易卡住的一点,也是为什么"转格式"不能省的原因。

一张 240×320 的图,每个点用 2 字节(RGB565,第 3 课学过)记颜色,原始大小是:

240 × 320 × 2 = 153,600 字节 ≈ 150 KB

但你在电脑里看到的 cat.jpg,只有 9 KB 多。

差了大约 十几倍。

原始与 JPG 的大小

为什么?因为 JPG 是压缩格式:把"相邻很像的颜色"合并记录,省掉大量重复。代价是——板子不能直接把 JPG 丢给屏幕,得先"解压缩",把那 150 KB 还原出来,才能一个点一个点地显示。这个过程叫解码,本板用 TJpg_Decoder 来干。

打个比方:原始图像是"每本书逐字抄一遍";JPG 是"第 3 页到第 10 页都和第 3 页一样,就不抄了,只记一句'同上'"。板子读 JPG 时,得先把那些"同上"还原成原文才能读。

比喻要修正:书你可以跳着读;解码必须完整还原,漏一块屏幕就花掉一块。


五、这块板插的是什么卡?——从 TF 卡说起

cat.jpg 现在只是个电脑里的文件。要让它跑到板子上,得先给它找一个"住的地方" —— 一张卡。

你可能已经听说过"SD 卡"这个名字。可你手上那张小卡片(你的猫要住进去的那张), 名字其实不止一个。

先认识一下:市面上"存东西的小卡片",到底有多少种。

常见存储卡家族

「SD」是个家族,不是一张卡

名字多大常见在哪
SD 卡(大卡)32 × 24 mm相机、摄像机
MiniSD21.5 × 20 mm老式手机(基本见不到了)
TF 卡(也叫 microSD)15 × 11 mm手机、无人机、行车记录仪、我们这块板子
CF 卡43 × 36 mm专业单反

看出来了吗?它们长得像,尺寸却差好几倍。我们这块板用的,是最小的那一张。

本板的卡,正式名字叫 microSD,大家习惯叫它 TF 卡。 TF 是 TransFlash 的缩写,是它最早的名字;后来并入 SD 协会,正式改名叫 microSD。 两个名字说的是同一张卡——你去买卡的时候,说"TF 卡"或"microSD",都是它。(别说成"SD 卡"——那是指大卡。)

⚠️ 有个地方最容易搞混:代码里的库名仍然叫 SD_MMC。这是老名字留下来的习惯,但插在板子上的,是那张最小的 TF 卡。别听名字就以为要塞大卡进去——大卡根本插不进这个卡槽。

卡背面的小字,是什么意思?

把卡翻过来,你会看到一串小字,比如:

microSDHC  I  C10  U1  A1  32GB

这不是乱码,每一段都在说一件事:

卡上的标识怎么读

标识说的是什么举例
32GB能装多少(容量等级)SDHC 是 232GB,SDXC 是 32GB2TB
C10最慢也不低于多快(Class 等级)Class 10 = 每秒至少 10 MB
U1UHS 速度等级U1 = 10 MB/s,U3 = 30 MB/s
V30视频速度等级给摄像机录 4K 用的,和存照片无关
A1手机装 App 用的档位我们这块板用不上

这里留一个问题给你自己想:我们从今天到以后,做的都是"读一张图"这一件事。上面这么多数字,到底该看哪一个?

想好了再点开:我们的理解

只看"读速度",不看"写速度"。

上面那些等级(C10 / U1 / V30)说的几乎都是最低写入速度——那是给"用卡拍视频、往卡里存东西"这种场景定的标准。而我们这块板主要是读卡:读图看的是读速度,而卡的读速度通常比写速度还快一些。

所以实话说:Class 10 / U1 这个级别的卡,读图已经绰绰有余。 卡上写着 V30、V60 也不会让你读得更快,那是为录视频准备的。

卡慢不慢,往往不是相册卡顿的主因。 真正卡的是"解码"——下一节就讲。

这不是标准答案。 你要是手边有两张不同档位的卡,各测一次,看看数字差多少——用你自己量出来的数据说话,比听我说强。


六、解码要多久?又回到第 7 课了

我要故意把你拉回第 7 课。

第 7 课算过:整屏重画每秒 30 次,数据量顶到 SPI 的带宽。今天解码一张图,其实也是"往屏幕送一大堆点"。

解码一张图要多久? 看图片大小。你那只猫刚好铺满屏幕(240×320),解码通常要 几百毫秒。

先猜一下:从"卡里读到 cat.jpg"到"猫出现在屏幕上",一共要多久?

这意味着:

  • 只显示你这一只猫,等几百毫秒——完全没问题,你几乎感觉不到;
  • 但要是做自动相册,一秒翻一张,这几百毫秒就会让切换明显卡顿。

这就回到第 7 课那句话:卡不卡,看你在预算里干了多少活。

打个比方:解码一张图,像把一整箱书从仓库搬到桌上。搬一次还行;要你一秒钟搬好几次,你就累趴下了——板子也是。

比喻要修正:书搬完就放那儿;照片解码完还要"贴"到屏幕,搬运 + 张贴都算在预算里。

但这里有个好消息:你只是要显示一只猫——等几百毫秒,你几乎感觉不到。

只有当你想让猫"动起来"(自动相册、连续播放)时,这几百毫秒才会变成问题。 到第七节做相册时,我们再回来算这笔账。


七、完成任务:把小猫请上屏幕

绕了这么大一圈,现在把开头那只猫请出来。

回忆一下任务的四步:第 1、2 步(生成 + 转格式)在第三节就做完了。 剩下两步 —— 存卡、写程序 —— 现在办。

第 3 步:把 cat.jpg 存进 TF 卡

办法一:读卡器(推荐)

  1. 把 TF 卡从板上轻轻取出来(先断电);
  2. 插进读卡器,接到电脑;
  3. 在卡里新建一个文件夹,名字叫 photo(全小写,不要写"照片");
  4. 把 cat.jpg 拖进去 —— 文件名随意(cat.jpg、mao.jpg、1.jpg 都行,程序会自己扫);
  5. 安全弹出,把卡插回板子。

⚠️ 为什么要新建 photo 文件夹,而不是直接丢根目录? 放根目录也能读,但卡里往往还有别的东西(系统文件、以前的文件)。 放一个自己的文件夹,路径干净,不容易读错。 而且后面做分类相册时你还要建子文件夹 —— 现在养成习惯。

办法二:没有读卡器怎么办

  • 找一个有读卡器的同学帮忙;
  • 或者用带卡槽的笔记本电脑(很多笔记本侧面直接有 microSD 槽)。

存完先验证,别急着烧程序

这是今天最省时间的一个习惯。

板子读不到图的时候,它不会报错,屏幕就是一片黑。到时候你要分别排查 "卡没插好?文件夹名错?文件名不对?格式不对?"——四五个可能,全凭猜。

不如存完立刻验证一次:

请写一个程序,开机后:
1. 按本板的针脚设置打开 TF 卡(SD_MMC.setPins(38, 40, 39, 41, 48, 47));
2. 列出 /photo 文件夹里所有文件的名字;
3. 每个文件顺便报一下它有多大(字节);
4. 通过串口打印出来。
如果 SD 卡打不开、或者 /photo 不存在,请分别给一句明确的中文提示,
告诉我该检查什么(而不是只打印一个错误代码)。
请用中文注释,烧录前先运行 arduino-cli board list 核对端口。

串口里应该出现 cat.jpg。 没出现就先别往下走 —— 按下面的清单逐条对。

检查清单

要检查的对了是什么样
卡插好了、板子能读到串口能列出 /photo 里的文件
猫图是 JPG不是 PNG、不是 WebP
猫图是 基线式不是渐进式(这一步最容易漏)
尺寸不超过 240×320太大解码慢;太小看不清
文件名随意,.jpg 结尾就行 —— 程序会自己扫目录

三道关

还有一件事,程序里必须做对:读卡前要先告诉板子卡走的是哪几根针脚 (本板是 SD_MMC.setPins(38, 40, 39, 41, 48, 47)),然后才是 SD_MMC.begin()。 顺序错了、或少了这一句,后面全白搭,卡根本读不到。

你不用背它 —— 上面的提示词里已经写好了。但得知道有这么一步, 因为万一 AI 写漏了,现象是"卡读不到",而不会有个报错告诉你是这里的问题。

第 4 步:写程序,让猫出现

我要用 ESP32-S3 触摸屏板从 TF 卡(microSD)显示一张 JPG,
板子用 TJpg_Decoder 库。卡槽走 SDIO,库名虽然叫 SD_MMC,但插的是 TF 卡。

请写一段 Arduino 代码:
1. 先 SD_MMC.setPins(38, 40, 39, 41, 48, 47) 设好针脚,再 SD_MMC.begin();
2. 设置 TJpg_Decoder 回调,把解码出的图像块 pushImage 到 TFT;
3. 扫描 /photo 文件夹,把里面的 .jpg 找出来(我要能随便改文件名,别写死);
4. 显示第一张,并在串口打印解码用了多少毫秒。

请用中文注释;烧录前先运行 arduino-cli board list 核对端口。

烧录,看屏幕 —— 你的猫出现了吗?

再回串口看一眼那个毫秒数 —— 这就是你的猫从卡里到屏幕上花的时间。

如果屏幕是黑的,别慌,按顺序查四件事: ① 串口能不能列出 /photo(不能 → 卡或路径问题) ② 文件名和程序里写的是不是一致 ③ 图片是不是基线式(用 prepare_photos.py --check-only 验一遍) ④ 尺寸有没有超过 240×320

把"我做了什么、看到什么"说清楚再问 AI —— 别只说"不显示"。

成功了?再往前走一步:从一只猫到一本相册

一只猫显示了,说明整条链路你已经打通:生成 → 处理 → 存卡 → 解码 → 上屏。

现在让它动起来——多来几张,轮流显示。

作品 A · 小猫相册

再生成几张(不同姿势的猫、或者换成你喜欢的别的主题),处理成同样的格式, 一起丢进 /photo,让板子每隔几秒自动翻一张。

请把刚才的程序改成自动相册:
1. 开机扫描 /photo 文件夹,把所有 .jpg 都收进一个列表;
2. 每 2 秒自动显示下一张,循环播放;
3. 串口打印当前显示的是第几张、文件名;
4. 如果一张都没有,屏幕上给一句明确提示,不要黑着。

间隔秒数你自己定 ___(参考 2 秒)。
请用中文注释;烧录前先运行 arduino-cli board list 核对端口;
另存一个新版本,保留旧的单张显示程序。
想好了再点开:我们的参考数字

这不是标准答案。 参考值:2 秒一张。

这个数字是"看得清"和"看得出在动"之间的取舍:

  • 2 秒:够你看清这张是什么,又能感觉到"它在换";
  • 0.5 秒:太快了,像故障闪烁,每张都看不清;
  • 10 秒:等得心焦,你会怀疑程序是不是卡住了。

顺带想一想:翻页的间隔,和"解码要多久"有关系吗? 第六节你会量出单张解码的毫秒数。如果解码要 300 毫秒, 你把间隔设成 0.2 秒会怎样?——板子根本来不及画完就被要求画下一张了。 这就是第七课"帧预算"那笔账的又一次出现。

📦 不想自己做多张?这里有一份现成的

我们准备了 4 张「四季」示例图(已处理成基线式 240×320):

春 春 · 樱花树
夏 夏 · 太阳与海
秋 秋 · 枫叶
冬 冬 · 雪夜

在图片上右键 →「图片另存为」,存下来的就是板子能读的原始 JPG, 中间没有再压缩过。想一次拿全(含分类目录)也可以下整包: 下载示例照片包 tfcards-photos.zip

作品 B · 分类相册(进阶)

建两个文件夹,用 BOOT 键切换"现在看哪一类":

photo/
├── cat/        ← 猫的图
│   ├── 1.jpg
│   └── 2.jpg
└── dog/        ← 别的主题
    ├── 1.jpg
    └── 2.jpg

按下 BOOT 就在两类之间切换,每类各自轮播。

难点不在"显示一张",而在怎么让板子知道卡里有哪些文件、怎么按类别翻。 这个你刚才在"作品 A"里已经练过了——扫目录。把同一套办法用到两个文件夹上就行。


八、自检:先猜,再烧

今天最值钱的验证,是亲手量一量"解码要多久"。先猜,再烧进去用串口看真实数字:

你做的事你的预测板子实测(串口毫秒数)
用一张很小的图(80×80)(猜:很快?)(烧进去看)
用一张铺满屏幕的图(240×320)(猜:一样?)(烧进去看)
用一张"细节很多"的图(树叶、草地)(猜:和解码时间有关吗?)(烧进去看)

重点:小图和大图的解码时间差很多。亲眼看到这个差,你就真正懂了"为什么相册会卡"。

卡的知识小测(先答,再点开)

1. 这块板子插的卡,正式名字叫什么?还有哪些"长得像"的亲戚?

正式名字是 microSD,大家习惯叫 TF 卡(TransFlash 的缩写,是它最早的名字),两者是同一张卡。

同一个家族里还有:SD 卡(大卡,32×24mm,相机用)、MiniSD(21.5×20mm,老式手机,基本淘汰)、CF 卡(43×36mm,专业单反)。尺寸差好几倍,插槽互不通用。

2. 代码里写的是 `SD_MMC`,为什么板子上插的是小卡?

因为 SD_MMC 是库的名字,是老习惯留下来的叫法——它管的是"用 SDIO 方式访问存储卡"这件事。库名 ≠ 卡的种类。就像"铅笔盒"里装的不一定是铅笔,名字只是历史。

所以别被名字骗了:这块板的卡槽只能插 microSD / TF 卡,大卡根本塞不进去。

3. 卡背后写着 `microSDHC C10 U1 32GB`,这些字分别是什么意思?
  • microSDHC + 32GB:容量等级,容量在 2~32GB 之间(SDHC);再大就是 SDXC,出厂可能是 exFAT。
  • C10:Class 速度等级,最低 10 MB/s。
  • U1:UHS 速度等级,也是 10 MB/s,是更新的一套标准。

⚠️ 这些数字说的几乎都是写速度(给拍视频、存文件用的)。我们只是读图,所以 Class 10 / U1 这个级别早就够用——卡上写 V30 也不会让相册更快。

4. AI 生成的图,为什么直接丢进卡里读不出来?

多半是格式不对。板子用的 TJpg_Decoder 有三个硬要求:

  1. 只认 JPG —— PNG / WebP 都不认识;
  2. 只认基线式(baseline) —— 不认渐进式(progressive),而后者恰恰是很多 AI 生图工具和修图软件的默认输出;
  3. 尺寸别超过屏幕(240×320)。

用 prepare_photos.py 处理一遍就能全解决(居中裁剪 → 缩放 → 存成基线式 → 逐张验证)。


九、最后留给你

今天只是"让板子看照片"的第一步。几个方向挑一个折腾:

方向你可以做什么
家庭电子相框插上 TF 卡,桌上摆一台永远在翻照片的小相框
拍立得接摄像头,拍一张立刻显示(接后面的摄像头课)
带说明的相册每张照片下面用第 9 课的中文,写一句说明
滑动切换用第 8 课的触摸,手指左右滑切换上一张/下一张
让它动起来多做几张图放进 /photo,做成自动翻页的相册(第七节作品 A)
给卡做体检找 2~3 张不同档位的卡(C4 / C10 / U3),各测一次读图速度,看档位到底差多少

第 10 课 · 显示第一张图

第 10 课 · 显示第一张图

从 TF 卡里读出 /cat.jpg,整张图铺满屏幕显示出来。

10TF卡图片入门
第 10 课 · 自动相册

第 10 课 · 自动相册

三张图片每隔 2 秒自动翻一张,循环播放,像一个小相框。

10TF卡相册定时切换
第 10 课 · 解码要多久

第 10 课 · 解码要多久

依次显示三张图,串口打印每张的解码耗时,看看大图慢多少。

10TF卡性能计时
第 10 课 · 作品 · 分类相册

第 10 课 · 作品 · 分类相册

照片分成 family 和 trip 两类,按一下 BOOT 键就换一类从头播。

10TF卡相册BOOT作品