附录 C 探针清单
每个探针回答一个「Krita 无头下到底行不行」的问题,结论进正文。全部在 probes/,跑法见附录 A。
| 探针 | 问题 | 结论 | 章 |
|---|---|---|---|
probe_stroke_budget.py | 8K 上能落多少笔?换色换笔径要不要 pump? | paintLine 450–850/s 与 size 无关;不 pump 换色生效(24/24),带 pump 71/s | 19, 27 |
probe_throughput_tree.py | 真实图层树上为什么慢、为什么越画越慢? | 树只贵 7%;path() 比逐段 paintLine 快 2.3 倍;每次调用 233 KB 撤销栈,setBatchmode 无效 | 19 |
probe_taper.py | 36 个 preset 哪些收尖、哪些边干净? | mypaint 引擎 aliased ≈ 0,b) Basic-* 88–95%;Pencil 1 Sketch 收尖 0.28 但 W=3.25 最软 | 21 |
probe_markshape.py | 一笔是圆的还是方的? | Bristles-5 Flat 长宽比 2.52 是平头;mypaint 画不出 1px 点 | 21 |
probe_glaze.py | setPaintingOpacity 量纲?叠加曲线?笔径系数? | 收 0..1,255 饱和;叠加符合 1−(1−a)^N;系数 Airbrush 0.93 / Bristles-5 0.44 / Pencil 1 Sketch 0.20 | 17, 21 |
probe_fill.py | 8K 上填一块平滑边的色块,哪条路行? | 只有矢量层(0.083);select_mask 0.331;paintPolygon 二值 0.498 | 27 |
probe_clipvector.py | 笔画层能不能 clip 到矢量层? | 能,且分数 alpha 原样传递(③ = ① = 0.0828) | 13 |
probe_vecstack.py | group 能不能 clip 到矢量层?15 个矢量层多久? | 能,裁整组合成(7,147,891 = 剪影);12.3s;.kra 13.8 MB | 13 |
probe_vector.py | 矢量层在 8K 上靠不靠谱? | 5/5:进 composite、贝塞尔渲染、坐标 1:1 零偏移、.kra 往返、跨 7700px | 28 |
probe_clipping.py | inherit alpha 到底生不生效? | 在 group 内生效,裁到累积 alpha,passthrough 失效,必须看 alpha | 13 |
probe_layer_order.py | addChildNode(child, None) 放哪? | 顶部;childNodes() 底→顶 | 28 |
probe_bigcanvas.py | 8192×12288 能不能跑? | 建档 2.3s、整幅读 3.7s、峰值 RSS 4.9 GB、.kra 存/开正常 | 26 |
probe_hardlight.py | 中灰 hard_light 塑造成不成立? | 中灰叠上分毫不动,浅灰提亮深灰压暗,保色相 | B(画师流程) |
probe_filtermask.py | 带选区的 filter 行不行? | apply 过渡带 7.2px(=地板),FilterMask(Selection) 59.9px 且非破坏;过渡带 ≈ 1.5×feather;Node 重载不限制范围 | 29, 30 |
probe_colorize.py | ColorizeMask 无头能不能出 flats? | 能:三区面积 0.98,12.3s,RSS +1.1GB。但边是二值(0.4981)。必须先 initializeKeyStrokeColors | 30 |
probe_preset_xml.py | 能不能程序化造笔刷、系数表能不能作废? | toXML/fromXML 可用且不写盘;改 diameter 对 auto brush 生效、对预定义笔尖无效;系数消不掉;mypaint 往返有损 ×31 | 21, 30 |
probe_scratchpad.py | 离屏画布能不能绕开撤销栈? | 不能——没有落笔 API。但它是拿 gradient / pattern 光栅的唯一路,搬回文档无损 | 19, 30 |
probe_delivery.py | .kra 还能多带什么? | SelectionMask / FileLayer / CloneLayer 三样往返不丢;Palette 存不进;图层样式喂不进 | 16, 30, 31 |
probe_shape_edit.py | 矢量层建完还能不能改? | 能:setZIndex / setTransformation / createGroupShape / setAntialiased(0.2624 vs 0.0891)全生效。单位是 pt。Node 变换 + TransformMask 也成立 | 28, 30 |
probe_detail_energy.py | 平涂 vs 密集笔触的细节能量? | 平涂 σ8 0.1%,420 笔塑造 2.9% | B(画师流程) |
写探针的规矩
- 一个探针一个问题,docstring 第一行就是那个问题
- 判据写在 docstring 里,包括「什么算生效」和锚点
- 读像素用
s.stable()/s.settle(),读一次就下结论会判反 - 探针的几何匹配实际用法(长曲线 vs 短线段)
- 在真实的结构里量(group 里、8K 上),单层探针会漏掉组合成的行为
- 打印判读提示:
[判读] ③ 明显小于 ④ = …,让不了解上下文的人也能读结论 - 判据不能比被测对象更粗:用二值分类器去量「边是不是抗锯齿的」,答案恒等于
「是二值的」——那量的是分类器自己(
probe_colorize栽过) - 判据也要有地板:先算出「理想台阶」在这个判据下读多少(
probe_filtermask是 7.2 px),不然分不清「没生效」和「生效了但很窄」 - 量位移不要用重心:框比对象小会截断,组的投影还会留残影。用对象自己的
boundingBox(),或者对着挪过的解析真值量偏差(probe_shape_edit栽过两次)