Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

28 图层

✅ 已验证

n = doc.createNode(name, "paintlayer"); parent.addChildNode(n, above)
g = doc.createGroupLayer(name)              # 必须用这个, createNode(..., "grouplayer") 拿不到 setPassThroughMode
v = doc.createVectorLayer(name)
doc.createCloneLayer / createFilterLayer / createFillLayer / createTransformMask / createSelectionMask / createColorizeMask
  • addChildNode(child, None) 放到该 parent 子栈的顶部above=X 插在 X 之上;childNodes() 返回底→顶
  • 这些 layer 可以直接 paintLine,不用先写像素再差分
  • 嵌套 4 级实测正常;但 group 是独立合成的,每级多存一份 tile,深度别超过 3–4
  • reparent(removeChildNode + addChildNode)可行

canvas.build(spec)L() / G() 声明式建树,列表顺序 = 底→顶,建完回读 childNodes() 与 spec 比对,重名抛错。s.find("04_Color/Skin/Skin_Shadow") / s.find("Skin_Shadow") / by_role / by_label 寻址。

属性

setBlendingMode / setOpacity / setColorLabel / setVisible / setLocked / setAlphaLocked / setInheritAlpha 生效(后两者实测:锁 alpha 后空白处再画一笔像素数不变;inherit alpha 见第 13 章)。

setBlendingMode 完全不校验:传 "xyzzy" 原样读回,按 normal 合成。读回值相等不能证明模式有效。在 base(128,64,192)+top(100,200,80) 上实测确认改变合成结果的 39 个:

multiply screen overlay soft_light soft_light_svg hard_light hard overlay
dodge burn linear_dodge linear_burn vivid_light pin_light
add subtract divide inverse_subtract exclusion negation
darken lighten darker color
hue saturation color luminize lightness
grain_merge grain_extract allanon parallel geometric_mean
reflect glow freeze heat  behind greater erase

darker color / hard overlay 中间是空格。linear_light hard_mix difference lighter color copy dissolve alphadarken 没能确认(合成与 normal 相同)。

group 的两个陷阱

passthrough 让 clip 失效第 13 章)。

不透传时,组内的 multiply 不跟组下面的画面相乘。 09_Post 里放一个 multiply 暗角,纯黑背景被抬成 (6,6,6)。组内合成是先把兄弟层合到一起再整组盖到下面——暗角在跟同组的透明层相乘,得到一团灰。单层探针查不出来(单独测 multiply 叠纯黑是 (0,0,0))。必须在真实的组结构里量。 修法是给这个组 passthrough=True(它没有 clip 层)。

方法读什么
node.pixelData(x,y,w,h)该层自己的像素,BGRA
node.projectionPixelData(x,y,w,h)该 node 含子节点的合成
doc.projection / s.composite()整个文档的合成
  • group 的 pixelData空数组cannot reshape array of size 0),要 projectionPixelData
  • 矢量层读不到 pixelData,只能看合成
  • 大画布多图层时一定传 box:2000×3000 一层 24 MB,上百层几个 GB

矢量层

vl = doc.createVectorLayer("v"); parent.addChildNode(vl, None)
vl.addShapesFromSvg('<svg xmlns="http://www.w3.org/2000/svg"><path d="…" fill="#…"/></svg>')

probes/probe_vector.py 5/5:进 composite(跨度与 SVG 完全一致);贝塞尔 C/Q 能渲染;坐标 1:1 像素,8192×12288 上 (7800,11800) 偏移 (+0,+0);.kra 往返保真;单条跨 7700px 正常。

vl.toSvg() 反向导出。node.save() 对矢量层段错误,进程直接死——不需要它,矢量本来就进 composite。

建完之后还能改:shapes() / setZIndex / setTransformation / createGroupShape / setAntialiased 全部生效。但几何单位是「点 pt」不是像素(300 DPI 下 1 px = 0.24 pt), 拿像素坐标问 shapeAtPosition 会得到 None。详见第 30 章

15 个矢量层 / 5000 控制点约 12s;addShapesFromSvg 之后 pump(6, 0.05)

Node 级变换

move / rotateNode / scaleNode / shearNode / cropNode 在 group 里都生效, clip(inherit alpha)关系跟着走。非破坏的版本是 TransformMask——读它的出厂 toXML() 骨架再改,手写的 transform_params 会被拒。见第 30 章

transparency mask

挂在目标图层下才生效,挂 rootNode 是孤儿。mask.setSelection(sel) 后精确裁剪。可编辑,比 inherit alpha 更适合交给画师。

.kra

doc.saveAs("x.kra") 正常(5.x 会段错误)。往返保真:层数、inheritAlpha、blend / opacity / label、矢量层。doc.exportImage(path, InfoObject()) 出 PNG。存盘前 doc.setBatchmode(True)