Nano Banana - Face Swap (Mask Inpaint)
The face swap that paints the old face red before Gemini sees it
- target_image
- identity_1
- identity_2
- identity_3
- identity_4
- identity_5
- identity_6
- network
- image
- status
- mask
- debug_sheet
Nano Banana's celebrity/public-figure classifier fires on the original face, not just the identity you're aiming for. NanoBananaInpaintSwap is the pack's third pathway and its bluntest workaround: it detects the face, paints it solid red, and only then sends the image to Gemini - so the model literally never sees the face it would have refused to touch.
This is the node you reach for when the whole-image path dies on a refusal and the crop path dies too. Where Crop & Composite works around scene content, this one works around identity content. It's also the closest thing in the pack to classic masked inpainting: a specified region gets redrawn from a prompt while the rest of the frame stays bit-identical, because Gemini only ever sees the obscured crop.
How it works
The flow: FaceMesh landmarks build a face polygon, mask_dilate_px expands it outward, and the region is filled red. That obscured image plus your identity references go to Gemini with an edit instruction - the model redraws a face matching the refs into the red blob. Back on your side, the result is composited into the original frame with the same integration stack as the other swap nodes: LAB color match, grain match matched to cheek variance, sharpness match that only ever blurs (never sharpens), and a Laplacian or feathered composite.
The red-paint trick has a side benefit beyond evasion: because Gemini sees no original face to preserve, it has freedom to redraw bone structure, which is why the pack suggests raising mask_dilate_px when you want a more thorough head rework.
Inputs that matter
api_key/model- Gemini key (orGEMINI_API_KEYenv) and the model:gemini-3.1-flash-image-previewdefault,gemini-3-pro-image-previewfor higher quality,gemini-2.5-flash-imagefor the older model.target_image+identity_1..identity_6- the frame and up to six refs. Setgrid_modetoauto_sheetif you're feeding a composed sheet.scope-face,head, orhead+styling, same semantics as the rest of the pack.mask_dilate_px(default 25) - how far the red polygon puffs out. This is the knob for this node. Higher = more room for Gemini to redraw bone structure; too high and the red paint bleeds into hair.mask_feather_px(default 16) - softness of the composite edge. 16–32 is typical.detector,crop_size, plus the integrate stack (color_match,grain_match,sharpness_match,composite_method,lab_strength,grain_strength).match_directional_lightingstays off for cross-identity swaps.- The v0.2 extras are all here too:
dry_runfor a free prompt preview,timeout_ms,ref_cap_px,auto_relax_on_refused, and the optionalnetworkinput for a proxy route node.
Outputs
The standard four: image (result, red-tinted on refusal), status (OK/REFUSED:<category>/ERROR:<reason>), mask, and debug_sheet.
Install
Same pack, same steps:
cd ComfyUI/custom_nodes
git clone https://github.com/IxMxAMAR/ComfyUI-NanoBanana-FaceSwap
cd ComfyUI-NanoBanana-FaceSwap
pip install -r requirements.txt
Restart ComfyUI (or ComfyUI Manager → "NanoBanana FaceSwap"). You need a Gemini API key, and the mediapipe dependency for the detector cascade - the requirements install handles it.
Troubleshooting
- Oval "sticker" boundary around the face - the classic sign
mask_dilate_pxis too big and the red blob carved a visible shape. The pack's workflow notes suggest lowering it (toward 12 or below). - Double jawline / face not tracking the original head - the opposite: too little dilation, so Gemini didn't have room to redraw. Raise
mask_dilate_px. REFUSEDeven though the original face is hidden - the red blob is still a face-shaped region, and the classifier can guess. This is where the pack's Unbiased pathway or the obfuscator picks up.
Batch tip: with batch_axis, each frame or identity gets its own API call and its own retry - one refusal in a run doesn't stop the rest.
Inputs (32)
| Name | Type | Default | Description |
|---|---|---|---|
| api_key | STRING | — | |
| model | COMBO | gemini-3.1-flash-image-preview | 3 options: gemini-3.1-flash-image-preview, gemini-3-pro-image-preview, gemini-2.5-flash-image |
| target_image | IMAGE | — | |
| identity_1 | IMAGE | — | |
| scope | COMBO | face | 3 options: face, head, head+styling |
| grid_mode | COMBO | separate_refs | 2 options: separate_refs, auto_sheet |
| custom_hint | STRING | — | |
| safety_threshold | COMBO | BLOCK_NONE | 4 options: BLOCK_NONE, BLOCK_ONLY_HIGH, BLOCK_MEDIUM_AND_ABOVE, BLOCK_LOW_AND_ABOVE |
| seed | INT | 00–2147483647 | — |
| batch_axis | COMBO | target | 2 options: target, identity |
| detector | COMBO | auto | 4 options: auto, mediapipe, opencv_yunet, gemini_bbox |
| crop_size | INT | 1024256–2048 | — |
| mask_dilate_px | INT | 250–128 | Dilate the face polygon outward before painting red. Higher = more room for Gemini to redraw bone structure. 25 is the tested default. |
| mask_feather_px | INT | 160–128 | Gaussian feather radius on the final composite mask edge. |
| image_size | COMBO | 2K | 3 options: 1K, 2K, 4K |
| color_match | BOOLEAN | true | LAB color match with face-polygon stats. |
| grain_match | BOOLEAN | true | Synthetic noise matched to target's cheek variance. |
| sharpness_match | BOOLEAN | true | Blur Gemini's face if it's sharper than the body. |
| composite_method | COMBO | laplacian | 2 options: laplacian, feather |
| match_directional_lighting | BOOLEAN | false | Same-character mode only. Corrupts identity in cross-identity swaps. |
| lab_strength | FLOAT | 0.600–1 | — |
| grain_strength | FLOAT | 1.000–2 | — |
| identity_2opt | IMAGE | — | |
| identity_3opt | IMAGE | — | |
| identity_4opt | IMAGE | — | |
| identity_5opt | IMAGE | — | |
| identity_6opt | IMAGE | — | |
| dry_runopt | BOOLEAN | false | — |
| timeout_msopt | INT | 1800005000–600000 | — |
| ref_cap_pxopt | INT | 10240–4096 | — |
| auto_relax_on_refusedopt | BOOLEAN | false | — |
| networkopt | NB_NETWORK | Optional. Wire a NanoBanana - Network Route node here to route this swap's API call through that proxy (e.g. US egress). |
Outputs (4)
| Name | Type | Description |
|---|---|---|
| image | IMAGE | — |
| status | STRING | — |
| mask | MASK | — |
| debug_sheet | IMAGE | — |