全部在 code/。裸 python 的不需要 Krita,可以在外面迭代;Krita 作业要走 run_job.sh。
| 文件 | 运行在 | 做什么 | 章 |
trace_prepare.py | 裸 python | 读画:分割 → α → 色阶 → 矢量化 → 规划笔画,产出 plan.json + strokes.jsonl | 4–7, 17–20 |
job_trace.py | Krita | 落笔:建 307 节点的树,逐笔画,存盘,数写像素 | 12, 19 |
gauge.py | 裸 python | 判据尺 | 31 |
| 文件 | 入口 | 做什么 |
segment.py | load / regions / tiers / pick_flat / inpaint / deaa / residual / pseudocolor | 边界屏障分割、KMeans 分档、以及旧路线的残差分解(保留) |
contour.py | alpha_from_image / level_field / trace / to_svg / rasterize | 解 α、矢量化、自检 |
cel.py | levels / vectorize / clean_mask / pick_k | 嵌套色阶 |
upsample.py | _sdf / coverage / upsample_image | SDF;旧路线的升采样(coverage 在 contour 自检里当对照) |
lineart.py | depth_field / thin / trace_paths / rdp / _catmull / to_svg | 暗脊线稿、RDP、Catmull-Rom |
| 文件 | 入口 | 做什么 |
strokes.py | Sim / wash / soft / hatch / strand / detail / contour_lines / lines | 六种笔的规划器 + 1x 模拟画布 |
| 文件 | 入口 | 做什么 |
canvas.py | Session / L / G / pump / replay | 建树、寻址、落笔、换装、像素读写、选区、filter、存盘、作画日志 |
measure.py | metrics / edge_ratio / report | 边缘质量 |
enrich.py | rim_band / orientation / trace_strand | 轮廓光、方向场、发束(旧路线的加料,保留) |
job_selfcheck.py | — | 31 项自检 |
job_landscape.py | — | 参考作业:风景 |
| 文件 | 入口 | 做什么 |
workflow.py | Pyramid / scale_energy / local_contrast | 金字塔(笔刷尺度递减)、中灰 hard_light、归一化坐标 |
layout.py | art_tree | David Revoy 式图层骨架 |
job_portrait.py | — | 参考作业:按金字塔流程画人像(示范流程,造型很糙) |
这条线是「从零画」而不是「临摹」,本书主线没用它,但 canvas / measure 共用。它的两条实测规矩:塑造用中灰 + hard_light 单层(中灰叠上去分毫不动,浅灰提亮深灰压暗且保色相);金字塔是笔刷尺度递减不是画布尺寸递增(画布放大会让细节能量逐级递减)。
| 文件 | 做什么 |
setup_fedora.sh | 生成 harness(独立 HOME + autopaint 扩展 + run_job.sh),先 rm -f 再 cp |
setup.sh | 包一层,把画师流程的脚本也拷进去 |
../paint | 唯一入口 |
s = Session(w, h, "name", journal=True)
s.build(spec) / s.find(path) / s.use(path) / s.on(path) / s.by_role(r) / s.by_label(n) / s.tree()
s.set_preset(name, size, opacity, flow) / s.set_color(r,g,b) / s.brush(color, size, opacity, flow, preset)
s.stroke(pts, pressures, node) / s.path(pts, node) / s.line(pts, width, node) / s.dab(x,y,p,node)
s.ellipse(...) / s.polygon(...)
s.layer(name, blend, opacity, clip, label) / s.group(...)
s.pixels(node, box) / s.projection(node, box) / s.composite(box) / s.set_pixels(rgba, node, box) / s.ground(r,g,b)
s.select(x,y,w,h) / s.select_mask(mask, feather) / s.select_none() / s.erase(box, mask)
s.filter(name, params, node, box)
s.settle(node) / s.stable(fn) / s.flush()
s.stage(label) / s.final() / s.save_kra(path) / s.manifest()