Nodes/comfyui-character-swap/Character Swap (Nano Banana Pro)
ComfyUI Node

Character Swap (Nano Banana Pro)

Put Your Character Into a Real Photo Without Rebuilding the Shot

By haristahir1·Created a day ago·Updated a day ago· 0
Character Swap (Nano Banana Pro)
  • shot_reference
  • character
  • wardrobe
  • IMAGE
  • final_prompt
  • diagnostics
backendVertex AI (gcloud or service account)
modelgemini-3-pro-image-preview
seed42
aspect_ratioauto (match reference)
resolution2K
shot_notes
remove_subjectthe person currently in the shot reference
character_notes
wardrobe_notes
blocking_notes
do_not
api_key
timeout300

You have a photo where everything is right except the person. The framing, the lens, the light, the grade, the pose - you'd keep all of it. You just want your character standing there instead.

Same-subject swaps are the hard version of that, and exactly where local instruction editors fall over: hand one two different women and nothing says which is the keeper. This node's contribution is the shape of the request that fixes it.

Two things up front: it's not local, so every image is a Google call on your own billing, and the pack is new and small with no track record yet. Read the source before your first run, like any API node that holds a key.

How it works

The request isn't one prompt followed by a pile of images. It alternates a text label and then the images that label describes - SHOT REFERENCE, CHARACTER, WARDROBE - so the model never infers roles from position. The shot-reference label is explicit that the face is the one thing you must not take from it; the character label says reproduce this identity exactly.

Second half of the trick: the request always states who to remove. remove_subject defaults to "the person currently in the shot reference", and without that line the original person survives - the model was told what to add, not what to delete. Be specific ("the blonde woman on the left").

A priority directive goes in last, where these models pay most attention: face and identity first, then your blocking and wardrobe notes, then the framing, lighting, colour, set and pose of the reference. Pose is always stated, never inferred. If blocking_notes is empty and a shot reference is connected, the node tells the model to match the reference pose - empty means keep, not guess.

aspect_ratio: auto reads the reference's shape and picks the nearest supported ratio - a 1920×802 scope frame still comes back scope-shaped. Forcing 16:9 on a wide reference re-blocks the whole composition, the usual reason a swap looks subtly wrong.

The inputs that matter

Connect shot_reference (the photo to copy), character (a clean portrait) and optionally wardrobe. That's the minimum; across those three the node caps you at 14 images, matching Google's own reference limit.

Then three text boxes do most of the work: remove_subject (who to delete), blocking_notes (empty keeps the pose; fill it, frame-relative, to change it - "she leans frame left"), and do_not. On this node do_not is empty by default, whatever the README's table says - paste the blockers yourself: no text, no watermark, no extra people, no duplicated or cloned person, no collage, no grid, no split frame, no border.

backend defaults to Vertex AI, model to gemini-3-pro-image-preview (Nano Banana Pro) and resolution to 2K - 1K/2K/4K is your cost dial, and Pro is the one that does 4K natively. seed tops out at int32 rather than ComfyUI's usual 2^64, because that's what Google's field accepts.

Three outputs: IMAGE (wire it to SaveImage or PreviewImage - not an output node), final_prompt (the readable transcript of what actually got sent) and diagnostics. Read the latter: Google happily returns HTTP 200 while quietly substituting someone else's face, so finishReason, safety flags and requested-vs-used aspect separate a bad prompt from a refusal. On a real public figure it will have steered, and no prompt works around that.

Install

Manager: search the pack title. Manual:

cd ComfyUI/custom_nodes
git clone https://github.com/haristahir1/comfyui-character-swap

There's no requirements.txt - requests/torch/numpy/Pillow are already in ComfyUI. AI Studio needs nothing else; Vertex needs google-auth, declared in pyproject.toml.

Setup

Vertex, which the pack recommends - Google excludes Gemini API on AI Studio from the $300 Cloud trial, so AI Studio credit won't pay for it:

gcloud auth login
gcloud auth application-default login   # both. the second is the one Python reads
gcloud services enable aiplatform.googleapis.com --project=YOUR_PROJECT_ID

Then copy config.json.example to config.json and set vertex.project_id. AI Studio instead: put the key in config.json or GEMINI_API_KEY, never the api_key widget - widget values get saved into every workflow you export and the error reports people paste into Discord. Search anything you share for AIza first.

Where it goes wrong

429 prepayment credits depleted means the AI Studio balance is zero - top up or move to Vertex. 403 SERVICE_DISABLED means you skipped the gcloud services enable line. Vertex mode needs credentials almost always means you ran gcloud auth login and stopped there; the application-default login is the one that matters. A 404 on a Vertex model is usually the region - set "location": "us-central1" instead of "global". If a 4K Pro run ever times out, raise timeout (300s default, up to 1800).

Use one clear portrait as the character; a contact sheet returns several people.

CategoryCharacter Swap

Inputs (16)

NameTypeDefaultDescription
backendCOMBOVertex AI (gcloud or service account)2 options: AI Studio (api key), Vertex AI (gcloud or service account)
modelCOMBOgemini-3-pro-image-preview3 options: gemini-3-pro-image-preview, gemini-2.5-flash-image, gemini-2.0-flash-preview-image-generation
seedINT420–2147483647
aspect_ratioCOMBOauto (match reference)11 options: auto (match reference), 1:1, 2:3, 3:2, 3:4, 4:3, +5
resolutionCOMBO2K3 options: 1K, 2K, 4K
shot_referenceoptIMAGE
characteroptIMAGE
wardrobeoptIMAGE
shot_notesoptSTRING
remove_subjectoptSTRINGthe person currently in the shot reference
character_notesoptSTRING
wardrobe_notesoptSTRING
blocking_notesoptSTRING
do_notoptSTRING
api_keyoptSTRING
timeoutoptINT30030–1800

Outputs (3)

NameTypeDescription
IMAGEIMAGE
final_promptSTRING
diagnosticsSTRING