HDR Inpaint Crop
Fix one eye at 4K without regenerating the face
- image
- mask
- cropped_image
- cropped_mask
- stitcher_data
Crop-and-stitch went from a clever trick to the default way people inpaint in ComfyUI, and the reason is structural: if the unmasked pixels never pass through a VAE, they cannot be degraded by one. HDR Inpaint Crop is Radiance's take on the first half of that pattern, with the VFX-flavoured wrinkle that values pass through completely unclamped, so scene-linear and HDR data survive the round trip.
Reach for it when the thing you need to fix is small relative to the frame. A 64-pixel eye that gets its own 1024-pixel generation budget looks better than the same eye inside a whole-frame pass - that's the entire argument, and it holds at any setting.
How it works
The node builds one union bounding box from every frame's mask (pixels above 0.05 on any frame count as active), then expands it by context_padding as a multiple of that box, centred on it. One box for the whole batch, deliberately: the crop doesn't move over time, so a video pass doesn't jitter. An empty mask crops the full frame rather than erroring.
Then it rounds the crop width and height up to a multiple of force_multiple - 16 by default, which is what Wan and LTX latents want. That last step is the unglamorous bit that saves you from a "latent dimensions must be divisible by N" error twenty nodes later.
It returns three things: cropped_image, the matching cropped_mask, and stitcher_data - an opaque bundle you feed to Radiance HDR Stitch to put the result back. That stitch is not a naive paste; it uses ACEScg linear Laplacian pyramids and edge-aware Gaussian blending, and its output is explicitly not clamped above 1.0.
Inputs
Three that matter:
imageandmask. The mask's job is both "what to inpaint" and "where to crop", so a tight mask means a tight crop means less context for the model. If your inpaint comes back with a weird edge, this is usually why.context_padding(default 1.5) - 1.0 hugs the mask, 1.5 gives you 50% extra around it. Generous masks overlapping the surrounding area by 20–30% are the standard advice in the KB's inpainting material, and this is the knob that implements it.force_multiple(default 16). Leave it at 16 for Wan/LTX; set 1 only if something downstream is dimension-agnostic and you want a tight crop.
Install
Manager → search Radiance → Install → restart → refresh the browser. Manually:
cd ComfyUI/custom_nodes
git clone https://github.com/fxtd-studios/radiance.git
cd radiance
python -m pip install -r requirements.txt
Windows portable users must use python_embeded\python.exe. The pack's dependency list is long (OpenImageIO, OpenColorIO, OpenEXR, diffusers, accelerate) - this node needs almost none of it, but you install the pack as a whole.
Where people get burned
The multiple-of-16 promise has an exception and it's written in the tooltip: a crop that reaches the frame edge is capped to the frame size and may not be a multiple of your value. So an inpaint that has to touch the top border can hand you a non-conforming size. If you hit a latent-size error right after this node, that's the mechanism.
Second, the union box across frames cuts both ways. One stray dot in your mask in a single frame expands the crop for the entire clip - you regenerate a much bigger area than you intended. Clean the mask before it gets here.
And the honest one: this node doesn't inpaint anything. It's one half of the pattern. Without a matching Stitch - with the stitcher_data you got out of this node - you're left holding a crop and no way home.
Inputs (4)
| Name | Type | Default | Description |
|---|---|---|---|
| image | IMAGE | Plate or frame batch to crop. Values pass through unchanged, so HDR and scene-linear data are kept. | |
| mask | MASK | Region to inpaint. Pixels above 0.05 on any frame define one union box used for every frame, so the crop does not move over time. An empty mask crops the full frame. | |
| context_padding | FLOAT | 1.501–4 | Crop size as a multiple of the mask's bounding box, centred on it. 1.0 = tight to the mask, 1.5 = 50% larger for surrounding context. |
| force_multiple | INT | 161–256 | Round the crop width and height up to a multiple of this (16 suits Wan and LTX latents). 1 = no rounding. A crop that reaches the frame edge is limited to the frame size and may not be a multiple. |
Outputs (3)
| Name | Type | Description |
|---|---|---|
| cropped_image | IMAGE | — |
| cropped_mask | MASK | — |
| stitcher_data | STITCHER_DATA | — |