Nodes/Mask External Edit/Mask External Edit
ComfyUI Node

Mask External Edit

GPT Image fixes straight from the ComfyUI canvas

By wuhu290·Created 3 months ago·Updated 3 months ago· 0
Mask External Edit
  • image
  • mask
  • image
  • debug_crop
  • edited_crop
  • used_mask
  • status
provideropenai
taskgeneral_fix
promptFix only the masked area. Preserve the original character, pose, style, lighting, and background.
api_endpoint
api_key_envMASK_EXTERNAL_EDIT_API_KEY
padding160
mask_grow12
feather24
crop_max_size1024
threshold16
timeout_seconds120
blend_modecolor_match
api_key
openai_modelgpt-image-2
mask_modeauto
on_errorraise
openwond_resolution1K
openwond_max_side768

Every local fix runs the same loop: crop the broken region, re-render it, paste it back with a feathered seam. Mask External Edit runs that loop for you and then hands the middle step to a cloud image-editing API - OpenAI's GPT Image, OpenWond, or any HTTP endpoint you point it at - instead of burning a diffusion pass on your GPU. You paint a mask, it crops with context padding, ships the crop off, and blends the edited result back into the original so well the seam usually vanishes. If you've ever wanted GPT Image's masked edits inside a ComfyUI workflow, this is the least painful way to get them.

The name isn't lying: this is an API-wrapper node, not a local model. GPT Image has no open weights you can download, so calling the cloud is the only door - or you have the workflow but no spare VRAM. It's the same honest trade every API node makes: each call costs money, and your crop - not your whole image, just the crop and mask - leaves your machine. It's the right tool when you can't run the model locally, not a default to build every workflow on.

How it works

Read the source and the loop is clean. The node takes your image and painted mask, autocontrasts the mask, and figures out the painted region with mask_mode. The auto default is worth knowing: ComfyUI MaskEditor/clipspace masks often store painted areas as darker alpha over an opaque image, so the node inverts when the background dominates. If the edit comes out backwards, flip white_edits / black_edits.

Then it grows the mask (mask_grow), finds the painted bbox above threshold, pads it with padding pixels of context, crops, and scales down to crop_max_size (default 1024) so you're not sending a 4K patch to a metered API. The provider call happens - OpenAI gets the crop plus an RGBA mask where transparent = edit area; OpenWond gets two reference images (crop + a black/white mask where white = edit); custom_http gets a multipart/form-data POST to whatever URL you set in api_endpoint, with image, mask, prompt, and task fields. Finally it pastes back: the edited crop is resized to the crop bbox, the mask gaussian-blurred by feather, and color_match (the default blend) matches each channel's mean/std to the original region so the lighting doesn't scream.

The inputs that actually matter

For a first run you really set these:

  • image + mask - the source and the area you want edited.
  • provider - openai (default), openwond_draw, custom_http, or debug_echo.
  • task + prompt - general_fix, fix_hands, enhance_face, or change_expression, plus your instruction. The node folds the task into the prompt sent to the API.
  • api_key / api_key_env - paste a key, or set MASK_EXTERNAL_EDIT_API_KEY as an env var and leave the field empty. Prefer the env var: keys baked into node fields end up in exported workflows and screenshots.
  • padding / mask_grow / feather - your seam quality knobs. The README's starting points: hands like 160–256 padding / 8–20 grow / 20–48 feather; a face can get away with less.

The rest has sane defaults. openai_model defaults to gpt-image-2, timeout_seconds to 120, on_error to raise.

What comes out

Five outputs: image (the final pasted result), debug_crop and edited_crop (what went out and what came back), used_mask (the paste mask used), and status (a string that tells you what happened or why it failed). Wire image where your sampler output would go; keep status on a text preview while debugging.

Install

There's no model to fetch here - requirements.txt is just requests and Pillow:

cd ComfyUI/custom_nodes
git clone https://github.com/wuhu290/ComfyUI-Mask-External-Edit.git
cd ComfyUI-Mask-External-Edit
pip install -r requirements.txt

Restart ComfyUI and search "Mask External Edit" on the canvas. It's new enough that ComfyUI Manager may not list it yet - use Manager → Install via Git URL and paste the repo URL.

Where people get burned

  • GPT Image masks are prompt-guided, not pixel-perfect - OpenAI is upfront that the edited region may not follow your mask precisely. The node checks for this: if the API returns an unchanged crop, it raises rather than quietly pretending to have fixed your hand.
  • Inverted edits with MaskEditor/clipspace masks - switch mask_mode off auto as described above.
  • OpenWond returning 413 (request too large) - drop openwond_max_side from 768 to 512.
  • Silent failure - if you set on_error: return_original, a failed call hands you the original image and only a string in status says why. Keep raise while testing, or you'll swear the node is broken.
  • Free rehearsal: run provider: debug_echo first. It paints the detected mask area hot pink on the crop with zero API calls, so you can verify crop, mask polarity, and paste logic before spending a cent.
CategoryMask External Edit/Enhance

Inputs (20)

NameTypeDefaultDescription
imageIMAGE
maskMASK
providerCOMBOopenai4 options: openai, openwond_draw, custom_http, debug_echo
taskCOMBOgeneral_fix4 options: general_fix, fix_hands, enhance_face, change_expression
promptSTRINGFix only the masked area. Preserve the original character, pose, style, lighting, and background.
api_endpointSTRING
api_key_envSTRINGMASK_EXTERNAL_EDIT_API_KEY
paddingINT1600–1024
mask_growINT120–256
featherINT240–256
crop_max_sizeINT1024256–4096
thresholdINT161–255
timeout_secondsINT12010–600
blend_modeCOMBOcolor_match2 options: normal, color_match
api_keySTRING
openai_modelSTRINGgpt-image-2
mask_modeCOMBOauto3 options: auto, white_edits, black_edits
on_errorCOMBOraise2 options: raise, return_original
openwond_resolutionCOMBO1K3 options: 1K, 2K, 4K
openwond_max_sideINT768256–2048

Outputs (5)

NameTypeDescription
imageIMAGE
debug_cropIMAGE
edited_cropIMAGE
used_maskMASK
statusSTRING