Qwen 2.1 - Image to Image
Up to ten references, and a mask field that's just a URL
- image_urls
- image
- url
- all_urls_json
- task_id
- raw_json
- credits_consumed
- credits_left
Qwen's image-editing line is the workhorse of the open editing world - the KB's consistency material notes Qwen-Image-Edit dwarfing the older IP-Adapter/InstantID stack in usage - and this node is the hosted version of that idea: feed it reference images plus an instruction, get the edit back as an IMAGE. What makes it more than a one-in-one-out edit node is the input count. You can pass up to ten references, and the prompt refers to them by position: "the first image", "the second image".
That's the actual superpower. One image is a retouch. Two images is a transfer - "replace the backpack in the first image with the colour scheme from the second image, and leave everything else unchanged", which is the docs' own example and a good test of whether the model is listening.
How it works
It's a KIE Market job (qwen2-1/image-to-image). Your connected image_urls batch is PNG-encoded and uploaded to KIE's file host, the resulting URLs go into the request in batch order, and the node polls the task until it completes before decoding the result into a tensor. Which means: order is meaning. Reference 1 is the base, reference 2 is the thing you're pulling from, and swapping them gives you a different operation entirely.
enhance_prompt deserves a mention because it defaults on: the model rewrites your prompt into a fuller scene description before generating, and that genuinely improves the output. Turn it off when you want exact control over the wording - which is also what you get automatically in local-edit mode.
Inputs that matter
- image_urls - the reference batch, 1 to 10. JPEG, PNG or WebP, up to 30MB and 25MP each. The docs are blunt that more references means less detail per reference, so stay at four or fewer when fidelity matters.
- prompt - required, up to 5000 characters, any language. This is where position-references live. In local-edit mode, describe only what goes inside the white area of the mask.
- mask_url - the rough edge of this node. It's a plain
STRINGURL field, not anIMAGEsocket, so you can't just wire a mask out of a local mask node and have the pack upload it for you. It needs to be a fetchable URL of a black-and-white image where white is what changes. Another reason to keep the pack's other image inputs in mind: they upload for you, this one doesn't. - background -
opaqueortransparent. Transparent gives you a real alpha channel (PNG/WebP only, never JPEG) and works best if your prompt describes only the subject - mention a scene or a surface and you often get an opaque result back. - aspect_ratio -
autotakes the ratio of the first reference and snaps to the nearest supported one. Ignored in local-edit mode, where the reference dictates the frame. - resolution -
1Kor2Konly.2Kis four times the pixels and can take a couple of minutes with reference images. Asking for4Kgets the request rejected. - seed - the one field that makes iteration sane. Same seed, prompt and parameters reproduces the image within a service version.
- nsfw_checker, output_format, timeout_seconds, callback_url - leave at defaults, though note
nsfw_checkershipsfalsehere, so no extra filtering pass is applied.
Outputs: image, url, all_urls_json, task_id, raw_json, credits_consumed, credits_left.
Installing
cd ComfyUI/custom_nodes
git clone https://github.com/felipederosilva/ComfyUI-KIE-Nodes-Next
cd ComfyUI-KIE-Nodes-Next && pip install -r requirements.txt
# restart ComfyUI
Manager: search "KIE.ai Nodes Next". Dependencies are requests, Pillow, numpy, PyYAML - no weights, no GPU. Key goes in Settings → KIE.ai Nodes Next → Connection; validated before saving and kept out of the workflow.
Where it hurts
Mixing a mask with more than one reference image is rejected outright - local-edit mode is exactly one image plus one mask. Combining mask_url with background: transparent is also rejected. And if you connect a batch to a socket that expects a single image, the pack's preflight says so in plain English ("expects one image; received a batch of N") rather than letting the provider fail obscurely.
Finally: this is a paid call every time, and image inputs get uploaded before the request. If you're using this to iterate on a client's product shot, that's a conversation worth having with the client.
Inputs (12)
| Name | Type | Default | Description |
|---|---|---|---|
| image_urls | IMAGE | — | |
| prompt | STRING | Replace the backpack in the first image with the colour scheme from the second image, and leave everything else unchanged | The prompt describing the result you want. Required. Any language is supported, up to 5000 characters; if it is longer, the request is rejected. When `mask_url` is supplied, use it to describe what should be generated inside the white area of the mask. |
| aspect_ratioopt | COMBO | auto | Output aspect ratio. Defaults to `auto`, which takes the aspect ratio of the first reference image and snaps it to the nearest supported ratio. The actual pixel size also depends on `resolution`. Ignored in local-edit mode. |
| resolutionopt | COMBO | 1K | Output resolution tier. `1K` is the faster option; `2K` produces four times the pixels and takes considerably longer, up to about 3 minutes with reference images. Only `1K` and `2K` are accepted — with any other value, including `4K`, the request is rejected. |
| backgroundopt | COMBO | opaque | Background type. transparent outputs a PNG or WebP with a real alpha channel and cannot be used with JPEG. When using transparent, describe only the subject — prompts that mention a background, scene, surface, etc. may produce a non-transparent result. |
| output_formatopt | COMBO | png | Output image format. `png` (default) and `webp` both carry an alpha channel and can be used with `background: transparent`. `jpeg` has no alpha channel and cannot be combined with a transparent background. |
| enhance_promptopt | BOOLEAN | true | Rewrites the prompt into a fuller scene description before generating, which noticeably improves quality. Enabled by default (also when the parameter is omitted); pass false to turn it off. |
| seedopt | INT | 20260921-2147483648–2147483647 | The random seed. Omit it to generate with a random seed. Passing the same seed together with the same prompt and parameters reproduces the same image within the same service version. |
| mask_urlopt | STRING | https://example.com/room-mask.png | Inpainting mask that switches the request into local-edit mode. A black and white image where **white marks the area to change and black is kept unchanged**, with a few pixels of feathering along the boundary. It must be used with exactly one entry in `image_urls`, otherwise the request is rejected. The mask should have the same aspect ratio as that reference image; a mask of a different size is scaled to it. In local-edit mode the output ratio follows the reference image, so `aspect_ratio` and `enhance_prompt` are ignored. It cannot be combined with `background: transparent`; such a request is rejected. |
| nsfw_checkeropt | BOOLEAN | false | Defaults to false. When false, no additional content filtering is applied and results are returned directly by the model. |
| timeout_secondsopt | INT | 120030–7200 | — |
| callback_urlopt | STRING | Optional KIE callback URL. Leave empty for normal ComfyUI use. |
Outputs (7)
| Name | Type | Description |
|---|---|---|
| image | IMAGE | — |
| url | STRING | — |
| all_urls_json | STRING | — |
| task_id | STRING | — |
| raw_json | STRING | — |
| credits_consumed | FLOAT | — |
| credits_left | FLOAT | — |