24 回放
🧪 在做 · 代码 code/canvas.py 的 replay() · 命令 ./paint replay <作品>
能回放什么
canvas.replay(jsonl_path, session) 按日志重跑:
op | 回放 |
|---|---|
set_preset / set_color / brush | 重新设置 |
stroke / path / line / dab / ellipse / polygon | 精确重画——坐标和压感都在 |
set_pixels / ground / erase / filter | 跳过并计数——只记了 box 和哈希,没记像素 |
所以回放的前提是:写像素类的数据要另外重跑(本流程只有一次 ground(0,0,0),可以直接补)。
现在的 ./paint replay
只是统计,不重画。 它读 jsonl、按 op 计数、打印「真正的笔画 N 条 / 写像素 M 条」:
trace-origin 共 209004 条操作
按操作: {'set_pixels': 1, 'ground': 1, 'brush': 128333, 'stroke': 2664, 'path': 78005, ...}
其中真正的笔画 80669 条 (可精确回放); 写像素 2 条(只记 box/哈希, 要原始数据在场)
要真的回放,需要一个 job:建同样的树 → replay(jsonl, s) → 和原成品比。没写。
回放前必须修的两件事
- 图层定位。 第 22 章末尾那条:
"layer": "Marks"不唯一。replay()用session.find(e["layer"]),多个匹配会抛错。要么日志记全路径,要么回放时按顺序推断。 - 树的重建。 回放 job 得先建出同一棵树(307 节点、74 个矢量层)。
plan.json有全部曲线,所以可以从它重建;但日志本身不含树结构。
为什么值得做
回放是这本书判据的终极形式:如果一份 jsonl 能在一个空文档上重建出成品,那这张画就是「一笔笔画出来的」,没有任何辩解余地。 现在只做到了「数写像素次数 ≤ 2」(第 25 章),是必要条件,不是充分条件。