API Node
- Image
- BFL
- Luma
- Recraft
- Save SVG
- Recraft Style - Realistic Image
- Recraft Text to Vector
- Recraft Creative Upscale
- Recraft Image to Image
- Recraft Crisp Upscale
- Recraft Color RGB
- Recraft Text to Image
- Recraft Image Inpainting
- Recraft Vectorize Image
- Recraft Style - Digital Illustration
- Recraft Remove Background
- Recraft Style - Logo Raster
- Recraft Controls
- Recraft Replace Background
- Ideogram
- Stability AI
- OpenAI
- Video
Recraft Image Inpainting - ComfyUI 原生节点文档
Recraft Image Inpainting - ComfyUI 原生节点文档
使用Recraft API选择性地修改图像区域
Recraft Image Inpainting 节点允许你选择性地修改图像的特定区域,保持其余部分不变。通过提供图像、蒙版和文本提示词,可以精确地生成新内容填充指定区域。
参数说明
基本参数
参数 | 类型 | 默认值 | 说明 |
---|---|---|---|
image | 图像 | - | 需要修改的输入图像 |
mask | 蒙版 | - | 定义要修改区域的黑白蒙版 |
prompt | 字符串 | "" | 描述要在蒙版区域生成的内容 |
n | 整数 | 1 | 生成结果的数量(1-6) |
seed | 整数 | 0 | 随机种子值 |
可选参数
参数 | 类型 | 说明 |
---|---|---|
recraft_style | Recraft Style | 设置生成内容的风格 |
negative_prompt | 字符串 | 指定不希望在生成内容中出现的元素 |
recraft_controls | Recraft Controls | 附加控制参数(颜色等) |
输出
输出 | 类型 | 说明 |
---|---|---|
IMAGE | 图像 | 修改后的图像结果 |
源码参考
[节点源码 (更新于2025-05-03)]
class RecraftImageInpaintingNode:
"""
Modify image based on prompt and mask.
"""
RETURN_TYPES = (IO.IMAGE,)
DESCRIPTION = cleandoc(__doc__ or "") # Handle potential None value
FUNCTION = "api_call"
API_NODE = True
CATEGORY = "api node/image/Recraft"
@classmethod
def INPUT_TYPES(s):
return {
"required": {
"image": (IO.IMAGE, ),
"mask": (IO.MASK, ),
"prompt": (
IO.STRING,
{
"multiline": True,
"default": "",
"tooltip": "Prompt for the image generation.",
},
),
"n": (
IO.INT,
{
"default": 1,
"min": 1,
"max": 6,
"tooltip": "The number of images to generate.",
},
),
"seed": (
IO.INT,
{
"default": 0,
"min": 0,
"max": 0xFFFFFFFFFFFFFFFF,
"control_after_generate": True,
"tooltip": "Seed to determine if node should re-run; actual results are nondeterministic regardless of seed.",
},
),
},
"optional": {
"recraft_style": (RecraftIO.STYLEV3,),
"negative_prompt": (
IO.STRING,
{
"default": "",
"forceInput": True,
"tooltip": "An optional text description of undesired elements on an image.",
},
),
},
"hidden": {
"auth_token": "AUTH_TOKEN_COMFY_ORG",
},
}
def api_call(
self,
image: torch.Tensor,
mask: torch.Tensor,
prompt: str,
n: int,
seed,
auth_token=None,
recraft_style: RecraftStyle = None,
negative_prompt: str = None,
**kwargs,
):
default_style = RecraftStyle(RecraftStyleV3.realistic_image)
if recraft_style is None:
recraft_style = default_style
if not negative_prompt:
negative_prompt = None
request = RecraftImageGenerationRequest(
prompt=prompt,
negative_prompt=negative_prompt,
model=RecraftModel.recraftv3,
n=n,
style=recraft_style.style,
substyle=recraft_style.substyle,
style_id=recraft_style.style_id,
random_seed=seed,
)
# prepare mask tensor
_, H, W, _ = image.shape
mask = mask.unsqueeze(-1)
mask = mask.movedim(-1,1)
mask = common_upscale(mask, width=W, height=H, upscale_method="nearest-exact", crop="disabled")
mask = mask.movedim(1,-1)
mask = (mask > 0.5).float()
images = []
total = image.shape[0]
pbar = ProgressBar(total)
for i in range(total):
sub_bytes = handle_recraft_file_request(
image=image[i],
mask=mask[i:i+1],
path="/proxy/recraft/images/inpaint",
request=request,
auth_token=auth_token,
)
images.append(torch.cat([bytesio_to_image_tensor(x) for x in sub_bytes], dim=0))
pbar.update(1)
images_tensor = torch.cat(images, dim=0)
return (images_tensor, )