MaskBuilder
The mask prep node that keeps your inpaint from looking painted
- base_mask
- pixel_lock_mask
- hard_keep
- soft_keep
- full_edit
Every inpainting workflow dies at the same place: the edge between the region you regenerated and the region you didn't. Feed a sampler one binary mask and it treats that boundary as a cliff, so you get seams, bleeding, and the telltale "painted-on" look. MaskBuilder exists to stop that before sampling ever starts.
It doesn't generate anything. It takes an ordinary ComfyUI MASK - the kind you'd paint by hand or get out of any segmentation node - and converts it into the pack's custom PIXEL_LOCK_MASK, which is a three-zone map:
- hard_keep - pixels that must be preserved exactly
- soft_keep - a boundary band that may drift slightly
- full_edit - pixels free to change
That three-way split is the whole idea behind ComfyUI-Pixel-Locker. Instead of a binary on/off, you get a feathered transition zone, and the other nodes in the pack (PixelLockSampler, PixelLockComposite, PixelLockDecodeComposite) know exactly how much each zone gets to move.
The inputs that actually matter
Only five inputs, and you'll only fiddle with three of them.
- base_mask - your starting
MASK. Any mask works: painted, from a segmentation model, from an inpaint helper. - mask_mode - the trap.
preserve_maskmeans white = keep;edit_maskmeans white = edit. They produce opposite results, and if your mask was built with "this is what I want to change" in mind but you leave it on the default, you'll protect the wrong half of the image. Match it to how the mask was made. - boundary_px - the width of the soft band in pixels (default 8). Zero gives you a hard binary lock with no feathering, which is right for tiny precision edits and wrong for anything with a visible edge.
- boundary_mode - where the soft band sits:
centered(both sides of the edge),inward(only inside the protected region), oroutward(only outside). Centered is the sensible default; use inward when you want the outside edge to stay razor sharp. - threshold - anything above 0.5 (the default) counts as "on". Lower it if your source mask is soft and faint.
How it works
Mechanically it's boring, and that's a compliment. From the source: the mask is thresholded, optionally inverted for edit_mask, then eroded and dilated by boundary_px to carve out the three bands. The three outputs are guaranteed non-overlapping and exhaustive - every pixel lands in exactly one zone. The pixel_lock_mask output is what you wire into the sampler and composite nodes; the separate hard_keep, soft_keep, and full_edit MASK outputs are there so you can drop a PreviewImage on each and see exactly what you're about to protect.
Installing it
The whole pack installs as one folder. In ComfyUI Manager, search ComfyUI-Pixel-Locker and install; or from the terminal:
cd ComfyUI/custom_nodes
git clone https://github.com/Bogyie/ComfyUI-Pixel-Locker
Then restart ComfyUI. There's no requirements.txt, no model downloads, no PyTorch versions to babysit - the pack is pure Python on top of what ComfyUI already ships. That's rare. Enjoy it.
Where people get burned
The mask_mode inversion catches everyone once. After that it's the expectation thing: PIXEL_LOCK_MASK is a custom type only the other three nodes in this pack understand, so don't try to wire it into a generic mask node. And remember MaskBuilder is only the map - the actual preservation happens downstream, so it's always worth previewing the three output masks before you spend the sampler budget.
Inputs (5)
| Name | Type | Default | Description |
|---|---|---|---|
| base_mask | MASK | Mask that describes the preserved or edited region. | |
| boundary_px | INT | 80–512 | — |
| mask_mode | COMBO | preserve_mask | 2 options: preserve_mask, edit_mask |
| boundary_mode | COMBO | centered | 3 options: centered, inward, outward |
| threshold | FLOAT | 0.500–1 | — |
Outputs (4)
| Name | Type | Description |
|---|---|---|
| pixel_lock_mask | PIXEL_LOCK_MASK | — |
| hard_keep | MASK | — |
| soft_keep | MASK | — |
| full_edit | MASK | — |