docs(AGENTS): codify asset size limits and batch-editing discipline

把这轮媒体治理沉淀成规范,核心是一张体积上限表:

  静态图 300KB/500KB  ·  SVG 500KB/1MB
  3 秒内动图 WebP 500KB/1MB(严禁 GIF,超 5 秒别用 WebP)
  5 秒以上动图 MP4 1MB/2MB,等效 1080p 1Mbps(录屏类 0.5Mbps)
  画质对比样片放宽到 4MB;再大的传 B 站/YouTube 内嵌,不进仓库

新增三节:
- MP4 按「等效 1080p 码率」衡量而不是只看文件大小。实测一个 2.2MB
  的小动图折合 1080p 高达 39.6Mbps,按 1Mbps 重编后 57KB;反过来
  7.7MB 的长录屏折合才 1098k,压它只会糊。先看帧率再调码率,
  120fps 降 30fps 直接省 3/4。
- 不要重复存放同一张图:没有中英差异的只放中文目录一份。清理历史
  重复要同时满足「文件名相同」和「不含同族两个型号」,后者防止把
  lpi3a/lpi4a 这类独立产品线绑在一起。
- 批量处理素材的纪律:基线对比、以构建产物为准、保留 CRLF 行尾、
  替换带定界符、通用文件名不自动匹配、删引用要删整个标记。

自检清单与坑速查表同步更新。
This commit is contained in:
zepan
2026-10-07 21:37:48 +08:00
parent 0724332cf8
commit 79f839bbf0

View File

@@ -162,17 +162,24 @@ update:
- **禁用**:工程样机裸板、手机随手拍、桌面/木纹等生活化背景、带水印或截图工具红字的图。
- 产品图统一白底棚拍或渲染。
### 压缩(硬指标)
### 体积上限(硬指标)
单张 **<300KB 为宜,500KB 为上限**。
这不是洁癖:**git 会永久保存每张图的每个历史版本**,一张没压的大图即使以后删掉,也会让之后每一个完整 clone 的人多下载一次。本仓库历史已积到约 1GB,README 因此建议贡献者用 `--depth=1`。你现在省下的每一 MB,是替后面所有人省的。
| 素材类型 | 建议 | 上限 | 格式 |
|---|---:|---:|---|
| 静态图片 | **300 KB** | 500 KB | JPEG / PNG(见下方分类) |
| 矢量图 SVG | **500 KB** | 1 MB | SVG,上传前先 `svgo` |
| **3 秒内**动图 | **500 KB** | 1 MB | **WebP,严禁 GIF**;超过 5 秒就别用 WebP |
| **5 秒以上**动图 | **1 MB** | 2 MB | MP4,等效 1080p **1 Mbps**;录屏类大范围不动的可降到 **0.5 Mbps** |
| 画质对比类视频 | — | 4 MB | 仅限传感器对比、微光夜视这类画质即内容的样片 |
| 再大的视频 | — | — | **传 B 站 / YouTube,网页内嵌播放器**,不要进仓库 |
```bash
# 检查自己新加的图
find docs/hardware/zh/logic_analyzer/<product> -type f -size +500k -printf '%s\t%p\n' | sort -rn
# 提交前检查自己新加的素材
find docs/hardware/zh/<product> -type f -size +500k -printf '%s\t%p\n' | sort -rn
```
**为什么要较真到 KB**:git 会永久保存每张图的每个历史版本,一张没压的大图即使以后删掉,也会让之后每一个完整 clone 的人多下载一次。本仓库历史已积到约 1GB,README 因此建议贡献者用 `--depth=1`。你现在省下的每一 MB,是替后面所有人省的。
### 静态图:先分清是「照片」还是「合成图形」
这是选对压缩方式的**唯一关键**,两类的处理方向完全相反:
@@ -189,9 +196,9 @@ find docs/hardware/zh/logic_analyzer/<product> -type f -size +500k -printf '%s\t
- 相机样片(传感器对比、微光夜视、显微图)**画质本身就是内容,不要有损压缩**。
- 实测参考:11.7MB 的产品 PNG 转 JPEG 后 444KB(−96%);1.4MB 的 PulseView 截图调色板量化后 44KB(−97%)且文字依旧锐利。
### 动图:不要直接提交 GIF
### 动图:3 秒内用 WebP,5 秒以上用 MP4
先用同样的「照片 / 合成」二分法,再选模式。需要 `sudo apt install webp`(提供 `gif2webp`、`cwebp`)。
**任何情况下都不要提交 GIF。** 格式按时长选,编码模式再按「照片 / 合成」二分法选。需要 `sudo apt install webp`(提供 `gif2webp`、`cwebp`)。
```bash
# 合成图形 / 终端录屏 —— 无损(WebP 无损模式自带调色板,全面强于 GIF)
@@ -213,16 +220,65 @@ ffmpeg -i in.gif -vf "scale=iw*2/3:-1:flags=neighbor,split[a][b];\
**缩放尺度**:桌面录屏按 **2/3** 缩(直接砍到 640 会糊到看不清文字);实物拍摄长边超过 **512** 就缩到 512。缩完务必按原尺寸看一眼文字还认不认得出。
**长录播考虑 MP4。** 超过十几秒、画幅又大的录屏,H.264 的帧间预测碾压 WebP——实测一个 2147KB 的 GIF,WebP 最优 829KB,MP4 只要 87KB。代价是 markdown 要写成 HTML,且 `muted` 和 `playsinline` 不能省,否则 iOS 不自动播放;MP4 也不支持透明通道。
**超过 5 秒就转 MP4。** 画幅大、时间长的录屏,H.264 的帧间预测碾压 WebP——实测一个 2147KB 的 GIF,WebP 最优 829KB,MP4 只要 87KB。代价是 markdown 要写成 HTML,且 `muted` 和 `playsinline` 不能省,否则 iOS 不自动播放;MP4 也不支持透明通道。
```html
<video src="./assets/demo.mp4" autoplay loop muted playsinline></video>
```
已经是 MP4 的不用动——现有 21 个 MP4 共 34MB,码率都合理,重编码收益极小。
### MP4:按「等效 1080p 码率」衡量,不要只看文件大小
文件大小会被时长和分辨率掩盖,真正该看的是单位面积码率:
```
等效1080p码率 = 实际码率 × (1920×1080) ÷ (宽×高)
```
目标 **1 Mbps**;录屏类大范围不动的可降到 **0.5 Mbps**。按这个口径换算出目标码率再编码:
```bash
# 目标 = 1000k × 面积比;录屏类用 500
ffmpeg -i in.mp4 -vf "scale=trunc(iw/2)*2:trunc(ih/2)*2" \
-c:v libx264 -b:v ${T}k -maxrate $((T*3/2))k -bufsize $((T*2))k \
-pix_fmt yuv420p -an -movflags +faststart out.mp4
```
实测:一个 338×450、6.4 秒的小动图,折合 1080p 竟高达 **39.6 Mbps**(文件 2.2MB 看着不大,但单位面积码率离谱),按 1Mbps 重编后 57KB,−98%。反过来,一个 7.7MB 的 156 秒录屏折合才 1098k,已经很省,压它只会糊。
**先看帧率再调码率。** 120fps 的演示录屏降到 30fps 直接省 3/4,画面观感没区别——这比动码率划算得多。
**画质即内容的样片不要动**:传感器对比、微光夜视、显微图,压了等于毁掉它存在的意义。
**动图/示意图如果是 html 渲染出来的**,去改源 html 的输出尺寸,不要硬压已经生成的大图。
### 不要重复存放同一张图
**没有明确中英差异的图片 / 动图 / 视频,只放一份**,默认放中文目录下,英文页用相对路径回引:
```markdown
![Front view](../../../zh/logic_analyzer/slogic32u3/assets/MISC/view-front.jpg)
```
反复复制除了撑大仓库没有任何好处。判断依据很简单:**图里有中文文字才需要双份**(那种本来就该出 `_en` 版本,见 §4),纯实拍、截图、原理图、线稿一律共用。
清理历史重复时,判别「同一份素材」要同时满足两条:
1. **文件名完全相同** —— 文件名不同说明是两个产品碰巧用了同一张图(`cleam.png` 与 `clean_core_board.png`),不是刻意复制
2. **路径里不含同一产品族的两个不同型号** —— `lpi3a/lpi4a`、`tang-nano/tang-nano-1k`、`tang-primer-20k/25k`、`spmod_eink/spmod_rfid` 这些必须保持独立
第 2 条尤其重要:合并跨产品的同图会制造耦合,以后更新一个产品的图,另一个产品的文档会悄悄跟着变。为省几十 MB 把两条独立产品线绑在一起不划算。
### 批量处理素材时的纪律
一次改几百个文件时,下面每一条都是真摔过的坑:
- **先用基线证明自己没搞坏。** 改之前在干净检出(`git worktree add /tmp/base HEAD`)上跑一遍同样的检查器,改完再跑,对比两份清单。只看"数字变少了"会骗人——曾经断链从 230 降到 234,正是基线对比才暴露出我新引入了 5 处。
- **以构建产物为准,不是源码路径。** 判断一张图线上到底能不能取到,要去 `out/` 里按 `<img src>` 解析,而不是只看 markdown 里的相对路径。
- **读写文件必须保留原始行尾。** 很多老文档是 CRLF,Python 默认模式读写会把整个文件转成 LF,改动量从 42 行虚增到 1200 多行,git blame 从此没法看。一律 `open(p, encoding='utf-8', newline='')`。
- **字符串替换要带定界符。** `/assets/x.jpg` 是 `../../assets/x.jpg` 的子串,直接 `str.replace` 会把本来正常的引用改坏。替换时连 `(...)` 或 `src="..."` 一起匹配。
- **通用文件名不要自动匹配。** `1.jpg`、`11.png` 这种即使全仓库唯一也可能只是撞车——实测有一例被匹配到毫不相关的文档。纯数字或短于 4 字符的文件名一律留给人工。
- **删图片引用要删整个标记**,`![]()` 和 `<img>` 两种写法都要处理;表格里只清空单元格、保留表格结构;删完检查有没有留下空的 `<center class="half"></center>` 之类空壳。
### 命名与归类
有意义的英文短名 + 连字符,**不要 `a1.jpg` / `IMG_2034.jpg` / `1.png`**:
@@ -327,8 +383,13 @@ grep -o '[一-龥]\{2,\}' out/en/index.html | sort -u | head
- [ ] `comm -3` 中英文件名对齐无差异
- [ ] 浏览器实际点一遍:侧边栏每个二级页、短链、页内锚点、所有图片都正常
- [ ] 英文页顶部没有 `This page not translated yet` 横幅;英文页没有中文漏出
- [ ] 新加图片全部 <500KB、命名有意义、放对了 assets 子目录
- [ ] 新加素材符合 §6 体积上限(静态图 ≤500KB、SVG ≤1MB、动图 ≤1MB、视频 ≤2MB)
- [ ] 没有提交任何 GIF;5 秒以上的动图已转 MP4 并按等效 1080p 码率编码
- [ ] 超过 4MB 的视频走 B 站 / YouTube 内嵌,没有进仓库
- [ ] 没有中英差异的图只存了一份(中文目录下),英文页相对路径回引
- [ ] 图片命名有意义、放对了 assets 子目录
- [ ] 含文字的图有 `_en` 版本
- [ ] `python3 tools/check_image_links.py` 退出码为 0(没有新增断链)
- [ ] 每页有"下一步"出口,操作步骤有可验证结果
- [ ] 跨页参数一致(grep 过)
- [ ] frontmatter 的 `update` 写了这次的实际改动
@@ -351,6 +412,10 @@ grep -o '[一-龥]\{2,\}' out/en/index.html | sort -u | head
| 访问目录路径以为 404 | `readme.md` 会构建成该目录的 `index.html` | 直接访问目录路径即可,不是 bug |
| CI 显示构建完成但线上还是 404 | `build_doc_upload` 在对象存储上传步失败(RequestTimeout,teedoc-upload 无重试) | 去 Actions 重跑失败的 job |
| `pkill` 把自己的命令也杀了 | pattern 匹配到了自身命令行 | 用 `pkill -f 'teedoc.*serve'` 之类不自匹配的写法 |
| 批量改完 diff 有上千行,远超预期 | 老文档是 CRLF,默认模式读写转成了 LF | 读写一律 `open(p, newline='')` |
| 替换路径后把原本正常的引用也改坏 | 短路径是长路径的子串 | 替换时连 `(...)` / `src="..."` 定界符一起匹配 |
| 图片名字搜得到,就以为链接没问题 | 目录名或层级写错,文件在别处 | 以 `out/` 构建产物为准,或跑 `tools/check_image_links.py` |
| 自动修断链时匹配到了无关的图 | `1.jpg` 这类通用文件名撞车 | 纯数字或短于 4 字符的文件名不自动匹配 |
---