Burve Crop + Mask Apply
The node that stitches your Gemini edit back into the photo
- base_image
- new_image
- crop_region_pipe
- mask
- edited_image
- placed_image_white_bg
- masked_placed_image_white_bg
- status
Generating a replacement for one region of an image is the easy half. The second half - getting that replacement back into the original without wrecking everything around it - is where a workflow quietly dies. That's the whole job of Burve Crop + Mask Apply: take a base image, a replacement image, and the crop-and-mask data from Burve Crop + Mask Load, and blend only the masked pixels back onto the base. Everything you didn't paint stays pixel-identical.
You reach for it at the end of the crop-zoom-regenerate-composite loop, the same one the detailing community has been running for years: cut a region out, re-render it at a size a model can actually resolve, paste it back, blend the seam. Here the "re-render" is a Gemini image node and the mask is something you painted rather than a detector found for you, which makes it closer to a manual inpainting-style edit - except the generator is a closed API call instead of a local sampler. The two Burve nodes are the loader/editor on one side and this paste-back on the other.
How it works
It's deliberately conservative, and that's a good thing. All three image inputs must have batch size 1. The base_image has to match the source size recorded inside the crop_region_pipe (change the source image after building the pipe and it errors), and mask must be the same dimensions as the base. The new_image gets bilinear-resized to fit the crop rectangle. If its aspect ratio doesn't exactly match the crop's, the node auto-fits with a centered crop - but only when the estimated trim is at most 1.0%. Anything bigger raises a hard error, and flipping the advanced strict_aspect_ratio toggle makes any mismatch an error, no auto-fit. That behavior exists so the workflow never silently crops away a meaningful chunk of your replacement. Mask values outside the crop rectangle are ignored even if they're nonzero.
The outputs, in order of how often you'll actually look at them:
edited_image- the composite. Base image with only the masked pixels inside the crop replaced. This is the one you save.placed_image_white_bg- the resizednew_imagesitting in the crop rectangle on a white canvas. Your debugging friend: it shows exactly what got placed before the mask touched anything.masked_placed_image_white_bg- the same, but only where the mask covers.status- empty on a clean run, or a warning string when a near-match ratio was auto-fit, so you know the placement got a silent center-crop.
How to install it
Same pack as the whole Burve suite. In ComfyUI Manager, search ComfyUI_Burve_Tools (or "Burve") and install, then restart ComfyUI. Or by hand:
cd ComfyUI/custom_nodes
git clone https://github.com/Burve/ComfyUI_Burve_Tools.git
cd ComfyUI_Burve_Tools
pip install -r requirements.txt
No model files to download and - important - no API key needed for this node. It's pure image math; the Gemini key is only required by the generation nodes in the same pack. You do need ComfyUI 0.4.0+ because the pack leans on the newer DynamicCombo and video-input APIs.
Common issues
- "must have batch size 1" errors. If you wired in a batched image or a batch of masks, it refuses. Feed it single frames.
- Source-size mismatch after editing. Rebuilding the crop region on a different source image invalidates the old pipe. Re-run Burve Crop + Mask Load so the pipe matches the base you're pasting into.
- The aspect-ratio hard error on paste. The replacement's ratio is too far from the crop's. Either regenerate at the right ratio (that's what the
aspect_ratiooutput on the Load node is for) or accept the centered-crop auto-fit when the trim is small.
It's a niche tool from a small pack, so you won't find a stack of community praise or war stories for it - but the mechanism is simple enough that it mostly just works when you respect the single-frame rule and keep the source dimensions consistent.
Inputs (5)
| Name | Type | Default | Description |
|---|---|---|---|
| base_image | IMAGE | — | |
| new_image | IMAGE | — | |
| crop_region_pipe | CROP_REGION_PIPE | — | |
| mask | MASK | — | |
| strict_aspect_ratio | BOOLEAN | false | — |
Outputs (4)
| Name | Type | Description |
|---|---|---|
| edited_image | IMAGE | — |
| placed_image_white_bg | IMAGE | — |
| masked_placed_image_white_bg | IMAGE | — |
| status | STRING | — |