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

29 选区、filter、擦除、变换

✅ 已验证

选区

from krita import Selection
sel = Selection()
sel.select(x, y, w, h, 255)                     # 矩形
sel.setPixelData(mask.tobytes(), 0, 0, w, h)    # 任意形状, numpy 造
sel.feather(15); sel.grow(20, 20); sel.shrink(...); sel.border(5, 5)
sel.invert(); sel.smooth(); sel.dilate(); sel.erode()
sel.add(o); sel.subtract(o); sel.intersect(o); sel.symmetricdifference(o)
doc.setSelection(sel)
  • 选区限制 paintLine:矩形 x∈[50,200) → 笔触落在 [50,199];圆形 + feather(15) → 向外羽化 15。全部精确。
  • 不限制 filter.apply():半幅选区下跑 gaussian blur,整幅都被处理。 但 createFilterMask / createFilterLayer 的 Selection 重载是受选区限制的, 而且带羽化、非破坏(第 30 章)。
  • 留不住分数覆盖率:喂 0..255 的抗锯齿 mask,画出来只从 aliased 100% 改善到 25.5%(边界带偏差 0.367 → 0.331,矢量层是 0.083)。要平滑的边别指望选区。
  • 8192×12288 上建一次约 1.1s(整幅 setPixelData 的成本)。
  • 取消选区只有一种写法doc.setSelection(None)setSelection(Selection())sel.clear() 是「全不选」,之后每一笔静默画出 0 px,不报错。症状是「笔刷突然全都不工作了」。
  • sel.selectAll() 需要 (node, value) 两个参数。

filter

f = Krita.instance().filter("gaussian blur")
c = f.configuration(); c.setProperty("horizRadius", 25.0); c.setProperty("vertRadius", 25.0)
f.setConfiguration(c)
f.apply(node, x, y, w, h)        # 成功也返回 None, 自己查像素

52 个:asc-cdl, autocontrast, blur, burn, colorbalance, colortoalpha, colortransfer, crosschannel, desaturate, dodge, edge detection, emboss(+5), fastcoloroverlay, gaussian blur, gaussianhighpass, gaussiannoisereducer, gradientmap, halftone, height to normal, hsvadjustment, indexcolors, invert, lens blur, levels, maximize, mean removal, minimize, motion blur, noise, normalize, oilpaint, palettize, perchannel, phongbumpmap, pixelize, posterize, propagatecolors, raindrops, randompick, resettransparent, roundcorners, sharpen, smalltiles, threshold, unsharp, wave, waveletnoisereducer。

范围只受 box 控制,刀切硬边——量模糊强度剖面的 0.9→0.1 过渡带是 7.2 px, 正好等于判据本身的地板(理想台阶经 9 宽平滑之后的读数)。

v5.1.0 更正:原来这里写着「要羽化的局部 filter 只能整幅跑一遍再用 numpy 按 mask 混回去」。那是 apply() 的结论。doc.createFilterMask(name, f, sel)Selectionsel.feather(40) 给出 59.9 px 的过渡带、feather(120) 给出 177.7 px,而且是非破坏的。 见第 30 章

擦除

只能清 alpha:s.erase(box=, mask=)。三种「用笔擦」全部无效(第 27 章)。

变换

Node 级(都改变 bounds):scaleNode(QPointF(cx,cy), w, h, "Bicubic")QPointF,传 QPoint 会 TypeError)、rotateNode(rad)shearNodecropNodemove

Document 级:scaleImage(w,h,xres,yres,strategy)rotateImageshearImagecropresizeImageflatten。策略 filterStrategies() → Bell, Bicubic, BSpline, Hermite, Mitchell, Bilinear, Lanczos3, NearestNeighbor。

scaleImagestrategy 不校验:传 "xyzzy" 尺寸照改,插值方式未知。之后 Session.w/h 不会自动同步,要回读 doc.width()

Node 级变换在 group 里对 clip 的实测、以及它们的非破坏版本 TransformMask, 见第 30 章

资源

Krita.instance().resources(类型):preset 144 / brush 84 / gradient 19 / pattern 112 / palette 13 / workspace 9。其它字符串返回空。createFillLayer(name, "gradient"|"pattern", InfoObject(), sel) 可铺成一层;"simplenoise" 段错误

Krita.instance().actions() 688 个,任何 GUI 菜单项都能 .trigger()——API 没覆盖的功能的后门,无返回值。

gradient 和 pattern 在 Node 上没有「铺一层」的 API,要拿它们的光栅结果只能走 Scratchpad.fillGradient / fillPattern第 30 章)。

其它

  • wrap aroundview.canvas().setWrapAroundMode(True) 实测影响绘制,越界的笔触卷回另一侧。
  • 动画:能读、能设时间轴参数、能导入序列帧,没有创建 keyframe 的 API
  • 通道顺序ManagedColor.setComponentsNode.setPixelData / pixelData 全是 BGRA,前者 0..1 浮点。canvas 对外一律 RGB。