Mosaic By Mask
Pixelate exactly the part you want hidden, nothing else
- image
- mask
- image
- mask
Sometimes you don't want to redraw anything, you just want a face or a license plate to stop being recognizable before the image goes anywhere public. Classic mosaic - pixelate the region, keep the rest bit-for-bit identical. That's this node's whole job, and it does it with a mask instead of a rectangle you have to babysit.
It comes from the same small pack as Censor Bars By Mask; think of this one as the "blur with chunks" half of the pair. Where inpainting would regenerate the region (and with it, every nearby pixel it decides to touch), mosaic is deterministic and surgical - the unmasked area is untouched, which the inpainting crowd keeps rediscovering is a feature, not a limitation.
How it works
White mask areas are the target. The node downsamples the image by pixel_size using area averaging (so each block averages the pixels underneath, not just samples one), then scales back up with nearest-neighbor - that two-step is what gives you the chunky block look rather than a blurry mush. The result is blended with the original using the mask, and edge_blur applies a Gaussian feather to the mask boundary first, so the transition from sharp image to mosaic is soft instead of a hard line.
Two niceties worth knowing: invert_mask flips the region (mask the subject, mosaic everything else), and mask_batch_mode handles multi-frame work. merge_batch_to_one collapses several candidate masks into one region by pixel-wise max - handy when face detection hands you several boxes and you want them treated as a single hide-zone.
The inputs that matter
image+mask- feed both; larger white mask area = larger mosaic.pixel_size(16) - block size. Bigger = coarser = more hidden.edge_blur(0) - feather the boundary. Start at 3–6 if the seam looks harsh.invert_mask- mosaics everything except the white region.
Outputs are image (the result) and mask - and that second one is worth a look: it's the final mask actually used for compositing, after inversion and blur. Chain it downstream if you want whatever you hid to stay hidden in a later step.
Install
Part of ComfyUi_zaknak_nodes - search that in ComfyUI Manager, or:
cd ComfyUI/custom_nodes
git clone https://github.com/zaknak/ComfyUi_zaknak_nodes
Restart, done. No model downloads, and this node has zero Python dependencies beyond what ComfyUI already ships.
Where it fits
After VAE Decode, with a mask from Segment Anything (Impact Pack), a mask editor, or a blur/detection node. Real use cases: anonymizing faces or plates before posting, making a generation shareable under platform rules, or the classic anime-community move of "pixelate the explicit bit so the preview doesn't get flagged" - the inverse of the decensor workflows people trade recipes for.
Troubleshooting
pixel_size = 1is a no-op - there's nothing to average, so the image comes back unchanged. Don't panic, it's by design.- The mosaic area looks wider than your mask: strong
edge_blurfeathers the mask outward a bit. Dial it back or shrink the mask. - Mask resolution differs from the image: it's resized internally to match, so no manual alignment - but very low-res masks give chunky, imprecise boundaries.
- Batch errors: a multi-image mask must match the image batch size unless you use
merge_batch_to_one.
Inputs (6)
| Name | Type | Default | Description |
|---|---|---|---|
| image | IMAGE | — | |
| mask | MASK | — | |
| mask_batch_mode | COMBO | match_image_batch | 2 options: match_image_batch, merge_batch_to_one |
| invert_mask | BOOLEAN | false | — |
| pixel_size | INT | 161–256 | — |
| edge_blur | FLOAT | 0.00–64 | — |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| image | IMAGE | — |
| mask | MASK | — |