2BZ Paste Crops Back
Put the Re-rendered Crops Back So Nobody Can See the Box
- image
- crops
- bboxes
- image
What it's for
The second half of the detect → crop → re-render → paste loop. After 2BZ Crop Each BBox (list) has scattered your frame into per-object crops and a sampler chain has re-rendered each one, this node shrinks every processed crop back to the size of its box, blends it in with a feathered edge, and hands you one image. No coordinates typed, no manual compositing.
It is the step everyone underestimates. The re-render is a fresh diffusion pass with its own VAE round trip, so its tone, contrast and brightness do not match the surrounding pixels - paste it in flat and you get a visible rectangle. Which is exactly what the tone widget is for.
How it works
It's a list-input node: it takes the original image, the (possibly batched) processed crops and the box list, flattens every batched crop down to one crop per box, then for each box resizes the crop to the box rectangle, optionally tone-corrects it, and composites it through a linear ramp mask feather_px pixels wide on each side. Edges that touch the image border stay hard, because there's nothing on the other side to blend with.
The composite is a straight lerp over the mask, so partial feather values blend partially - that's the whole seam-hiding mechanism, and it's the same compositing logic the KB describes for mask blur in any detail pass: bbox crops leave rectangular patches, and mask padding is what makes them disappear.
Inputs and outputs that matter
Three wires, three widgets.
image- the original frame. Everything outside the boxes is passed through untouched.crops- the output of whatever you ran the crop list through (decoded sampler output, an upscaler, whatever).bboxes- wireused_bboxesfrom the crop node, not the detector's raw boxes. The crop node padded and clamped the boxes, so the raw ones are in the wrong place and slightly too small.
Then:
tone(defaultoriginal_lowpass) - the interesting one.original_lowpassrebuilds each crop ascrop − lowpass(crop) + lowpass(region): it throws away the crop's low-frequency tone, keeps the original region's, and keeps only the crop's fine detail. That's frequency separation, run per box, and it's why the default hides seams so well on a full-denoise re-render.match_statsmatches per-channel mean and spread to the box instead - a classic statistics transfer, but it leaves a faint boundary.offpastes as-is, and you'll see the box.feather_px(default 24) - the soft edge width in source pixels. If a seam is still visible, 48 is the author's own next step. 0 gives you a hard rectangle.resize_method(lanczos) - the filter used to shrink crops back down.
The single output is image - one frame, same size as the input. Straight into Save Image, or into another pass.
Install
Part of the toobusy pack; needs v0.5.3+ for the two BBox nodes.
cd ComfyUI/custom_nodes
git clone https://github.com/nicekriss/toobusy.git toobusy
Manager installs work, but the registry copy can lag the repo - if a node is missing after a clean install, reinstall via Install via Git URL or just clone. Restart afterwards. No models, no extra pip packages.
Where people get tripped up
Ordering is positional. Crops are zipped against boxes in sequence, so if anything in between reorders or drops items, box #3 gets the face that belonged to box #5. This is the failure to look for when the paste "worked" but the output is subtly wrong.
Fewer crops than boxes is silent. Extra boxes just stay as the original pixels - no error, no warning. If one region looks un-retouched, count your crops against count from the crop node.
The crop list has to survive the round trip intact. The node flattens batched images, so a batch works fine, but a chain that outputs a single merged image where you expected a list will only paste one box.
Denoise 1.0 and the off tone mode are a bad pair. A full re-render tends to come back brighter, so with tone off you get bright rectangles on a darker frame. This is the case original_lowpass exists for. The reverse trap is real too: original_lowpass deliberately discards the re-render's overall tone, so if your goal was a genuine colour or exposure change inside the box, use match_stats or off and fix the exposure yourself.
Overlapping boxes get composited twice. Detectors happily return nested or duplicate regions, and the second pass lands on top of the first, feathering over it again. De-duplicate upstream (or use max_items on the crop node) if your detector is chatty.
Inputs (6)
| Name | Type | Default | Description |
|---|---|---|---|
| image | IMAGE | — | |
| crops | IMAGE | — | |
| bboxes | BOUNDING_BOX | — | |
| feather_px | INT | 240–512 | Soft edge width in source pixels. Edges touching the image border stay hard. |
| resize_method | COMBO | lanczos | 4 options: lanczos, bicubic, area, bilinear |
| tone | COMBO | original_lowpass | original_lowpass: keep the original's low-frequency tone and add only the crop's detail (seamless, recommended for full re-renders). match_stats: match per-channel mean/spread to the box. off: paste as is. |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| image | IMAGE | — |