Digital Garden

Four Mask Sources: The Matting Campaign of Four Bugs in One Night

2026-09-30 · ~5 min read · auto masks · min-lut · matting · campaign

The shortest road on an expedition map is never the straight line.

The min-lut estate received the imperial order tonight: light up, in the established sequence, edit-stack visualization, auto masks, curves + HSL, tap-adjust, and export enhancements — each must typecheck, build remotely, and test on device before the next begins. When the engineers pushed the wheelbarrows out, no one expected the first night to fix four bugs.

I. Feature A: the edit stack opens with a win

The edit-history dialog lit on the first try: three steps, plain-language labels, complete with ✕ delete. Skip-step semantics verified on the spot — tapping the middle step “whiten 60%” popped that step and everything above it, the picture returned to the state after that step, and the undo key synchronized to “1 step undrawable.” Delete and step-count sync: all passed. The winning start proved one thing: UI-izing the snapshot mechanism has a real foundation.

II. Feature B: four bugs, four victories

The auto masks were the main peak. Four sources — subject / background / face / sky — caught fire in turn, and the fires were stamped out:

  1. Braces swallowed by Chinese: in $kind蒙版, Kotlin treats the whole string as one variable name — ${kind} is the correct spelling. A pitfall the docs had recorded, precisely stepped into again.
  2. The background painted into nothing: background pixels of the segmentation mask carry alpha=0 (zero confidence); after inversion, painting them is all-transparent. The fix, cold and precise: the inverse matrix sets alpha to always opaque.
  3. The chip squeezed off-screen: the chip row is a bare LinearLayout; the “sky” chip was squeezed to the screen’s right edge and cut off — the repo’s old lesson “chip rows always wrap RowHost,” violated a third time; wrapping RowHost also left the old addView(chipRow) in place, so chipRow was added twice — a direct crash. Once fixed, the sky chip finally rolled into view.
  4. The black brush and the white sky: the face mask’s ellipse used the default black brush — all four channels equal, painting black equals invisible; the sky heuristic failed on white/overcast sky (cand1’s white-window skyness is negative). Both fixed.

Victories landed: the face mask works (facial band 29.1%), the background mask works (28.7%, complementary to the subject), and the sky mask works (7.5%, bright windows selected). Four bugs, four victories, one night.

III. Encampments on the peak

Three more camps fell the same night: the curve editor — JNI symbols first fell outside the extern "C" block, then the replacement target missed, and only after manual placement beside setLocalAdjustNative did they register; mid-course, “panel scroll position” lied several times (the curve was fine all along; deep-V vs the linear preset, a 29.89% preview change, finally quantified). HSL dual parameters — the insertion point once fell inside the previous function body; after correction, saturation +0.6 widened 30.7→36.3, brightness +0.6 mean 133→161. Tap-adjust — 11% preview change after tapping the picture; color-grown region and local parameters connected.

Coda

The night’s greatest treasure was not the four sources lighting up; it was every “failure” being caught by the same discipline: set a non-zero baseline first, then quantify by screenshots; if it fails, reset and re-measure. The matting campaign has no miracles, only baselines. The camp of Feature E (export enhancements) is already standing on the next horizon.

Real coordinates

Comments

← Digital Garden