Expand Image
Extend your image by filling in the surrounding scene.
ワークフローの内部
ソーステンプレートの読み取り専用プレビューです。Cloud で開くと、ノードを確認して変更できます。
Loading the graph
Open full-size workflow preview- 出力
- 画像
- 作成者
- Rob
コードからこのモデルを呼び出す
以下のリクエストでは、Playground と同じ準備済みグラフと設定を使用します。送信ごとに有料実行が開始される場合があります。結果が不明な送信を自動的に再試行しないでください。
What you need
- Runs on
- Comfy Cloud
- キー
- COMFY_API_KEY
- ファイル
- コードによって URL からアップロードされます
有料の Cloud プランとクレジットが必要です。
# Python 3.10+: pip install comfy-sdk==0.4.0
import os
from comfy_sdk import Comfy
api_key = os.environ.get("COMFY_API_KEY", "").strip()
if not api_key: raise RuntimeError("Set COMFY_API_KEY")
os.environ.setdefault("COMFY_BASE_URL", "https://cloud.comfy.org")
client = Comfy(api_key=api_key)
workflow = client.workflows.from_json({
"130": {
"class_type": "LoadImage",
"inputs": {
"image": "UPLOADED_image_FILENAME"
},
"_meta": {
"title": "Load Image"
}
},
"262": {
"class_type": "ImageCompare",
"inputs": {
"compare_view": {
"__value__": [
"",
""
]
},
"image_a": [
"302",
0
],
"image_b": [
"264",
0
]
},
"_meta": {
"title": "Compare Images"
}
},
"264": {
"class_type": "ImageResizeKJv2",
"inputs": {
"crop_position": "center",
"device": "cpu",
"divisible_by": 2,
"height": [
"265",
1
],
"image": [
"303",
0
],
"keep_proportion": "stretch",
"pad_color": "0, 0, 0",
"upscale_method": "lanczos",
"width": [
"265",
0
]
},
"_meta": {
"title": "Resize Image v2"
}
},
"265": {
"class_type": "GetImageSize",
"inputs": {
"image": [
"280:175",
0
]
},
"_meta": {
"title": "Get Image Size"
}
},
"276": {
"class_type": "ComfySwitchNode",
"inputs": {
"on_false": [
"291",
0
],
"on_true": [
"283",
0
],
"switch": False
},
"_meta": {
"title": "Automatic Outpaint Caption"
}
},
"277": {
"class_type": "PreviewAny",
"inputs": {
"source": [
"276",
0
]
},
"_meta": {
"title": "Caption Preview"
}
},
"278": {
"class_type": "StringConcatenate",
"inputs": {
"delimiter": "\n",
"string_a": "Outpaint/fill the solid green pixels with new image content that seamlessly continues the scene. DO NOT modify the original non-green pixels — they must remain exactly as they are. Do not copy/paste existing pixels into the green area. The new content must blend seamlessly in lighting, color, perspective, and detail. The green region should be replaced with:",
"string_b": [
"277",
0
]
},
"_meta": {
"title": "Assemble Outpaint Prompt"
}
},
"279": {
"class_type": "PreviewAny",
"inputs": {
"source": [
"298",
0
]
},
"_meta": {
"title": "Final Prompt"
}
},
"283": {
"class_type": "TextGenerateLTX2Prompt",
"inputs": {
"clip": [
"285",
0
],
"image": [
"303",
0
],
"max_length": 400,
"mtp": "auto",
"prompt": [
"297",
0
],
"sampling_mode": "on",
"sampling_mode.min_p": 0.05,
"sampling_mode.presence_penalty": 0,
"sampling_mode.repetition_penalty": 1.05,
"sampling_mode.seed": 123456789,
"sampling_mode.temperature": 0.7,
"sampling_mode.top_k": 64,
"sampling_mode.top_p": 0.95,
"thinking": False,
"use_default_template": True
},
"_meta": {
"title": "Generate Prompt"
}
},
"285": {
"class_type": "CLIPLoader",
"inputs": {
"clip_name": "qwen3.5_4b_bf16.safetensors",
"device": "default",
"type": "stable_diffusion"
},
"_meta": {
"title": "CLIP Loader"
}
},
"291": {
"class_type": "PrimitiveStringMultiline",
"inputs": {
"value": "Ochre adobe walls with peeling plaster continue on both sides, a shuttered window with a wrought-iron grille on the left, terracotta pots of red geraniums along the base of the wall on the right, and the cobbled street running on in bright morning sun."
},
"_meta": {
"title": "Manual Caption (describe the expanded region)"
}
},
"292": {
"class_type": "CustomCombo",
"inputs": {
"choice": "Centered"
},
"_meta": {
"title": "Image Position"
}
},
"293": {
"class_type": "JsonExtractString",
"inputs": {
"json_string": "{\"Image at Start (Left / Top)\": \"0\", \"Image at 1/3 (Rule of Thirds)\": \"33\", \"Centered\": \"50\", \"Image at 2/3 (Rule of Thirds)\": \"67\", \"Image at End (Right / Bottom)\": \"100\"}",
"key": [
"292",
0
]
},
"_meta": {
"title": "Position % (JSON)"
}
},
"294": {
"class_type": "JsonExtractString",
"inputs": {
"json_string": "{\"Image at Start (Left / Top)\": \"Placement: the original photograph sits flush at the LEFT edge of the final frame; all new content extends to the RIGHT of the visible scene.\", \"Image at 1/3 (Rule of Thirds)\": \"Placement: the original photograph sits left of center; a narrow band of new content extends to the LEFT and a wider area extends to the RIGHT.\", \"Centered\": \"Placement: the original photograph is centered; new content extends equally to the LEFT and to the RIGHT.\", \"Image at 2/3 (Rule of Thirds)\": \"Placement: the original photograph sits right of center; a wider area of new content extends to the LEFT and a narrow band extends to the RIGHT.\", \"Image at End (Right / Bottom)\": \"Placement: the original photograph sits flush at the RIGHT edge of the final frame; all new content extends to the LEFT of the visible scene.\"}",
"key": [
"292",
0
]
},
"_meta": {
"title": "Placement Phrase (Horizontal)"
}
},
"295": {
"class_type": "JsonExtractString",
"inputs": {
"json_string": "{\"Image at Start (Left / Top)\": \"Placement: the original photograph sits flush at the TOP edge of the final frame; all new content extends BELOW the visible scene.\", \"Image at 1/3 (Rule of Thirds)\": \"Placement: the original photograph sits above center; a narrow band of new content extends ABOVE and a wider area extends BELOW.\", \"Centered\": \"Placement: the original photograph is centered; new content extends equally ABOVE and BELOW.\", \"Image at 2/3 (Rule of Thirds)\": \"Placement: the original photograph sits below center; a wider area of new content extends ABOVE and a narrow band extends BELOW.\", \"Image at End (Right / Bottom)\": \"Placement: the original photograph sits flush at the BOTTOM edge of the final frame; all new content extends ABOVE the visible scene.\"}",
"key": [
"292",
0
]
},
"_meta": {
"title": "Placement Phrase (Vertical)"
}
},
"296": {
"class_type": "ComfySwitchNode",
"inputs": {
"on_false": [
"295",
0
],
"on_true": [
"294",
0
],
"switch": [
"224:255",
2
]
},
"_meta": {
"title": "Placement Phrase (axis auto-selected)"
}
},
"297": {
"class_type": "StringConcatenate",
"inputs": {
"delimiter": "\n\n",
"string_a": "You are writing a scene-continuation description for an image outpainting model. The flat solid green area in this image is a placeholder that will be replaced with new scenery extending the photograph. Study the visible non-green content — the space, surfaces, objects, materials, lighting, colors, and perspective — and describe in 2-4 sentences exactly what should appear in that area as a natural continuation of the scene.\n\nBe concrete and specific: name the surfaces that extend (floor, walls, ceiling, sky, ground) with their materials, patterns, and colors; any furniture or objects that would plausibly continue or appear; the light direction, temperature, and shadows; and the depth and perspective as the scene recedes.\n\nWrite ONLY the description of the new content itself, as if captioning a photograph of that area. Never mention \"green\", \"region\", \"placeholder\", \"pixels\", \"image\", or the editing process. Never use instructional phrasing like \"should contain\" or \"must match\". Start directly with the content — for example: \"A continuation of the terracotta tiled floor, its beige grout lines receding toward a plaster wall washed in warm lamplight...\"",
"string_b": [
"296",
0
]
},
"_meta": {
"title": "Caption Instruction + Placement"
}
},
"298": {
"class_type": "StringConcatenate",
"inputs": {
"delimiter": "\n",
"string_a": [
"278",
0
],
"string_b": [
"296",
0
]
},
"_meta": {
"title": "Final Prompt + Placement"
}
},
"299": {
"class_type": "ComfyNumberConvert",
"inputs": {
"value": [
"293",
0
]
},
"_meta": {
"title": "Convert Number (% -> INT)"
}
},
"302": {
"class_type": "SaveImageAdvanced",
"inputs": {
"filename_prefix": "Qwen-2511-outpaint",
"format": "png",
"format.bit_depth": "8-bit",
"format.input_color_space": "sRGB",
"images": [
"280:175",
0
]
},
"_meta": {
"title": "Save Image (Advanced)"
}
},
"303": {
"class_type": "SaveImageAdvanced",
"inputs": {
"filename_prefix": "Qwen-2511-outpaint_region",
"format": "png",
"format.bit_depth": "8-bit",
"format.input_color_space": "sRGB",
"images": [
"224:249",
0
]
},
"_meta": {
"title": "Save Image (Advanced)"
}
},
"224:191": {
"class_type": "FluxResolutionNode",
"inputs": {
"aspect_ratio": "16:9 (Panorama)",
"custom_aspect_ratio": "1:1",
"custom_ratio": False,
"divisible_by": "8",
"megapixel": "2.1"
},
"_meta": {
"title": "Flux Resolution Calc"
}
},
"224:240": {
"class_type": "PrimitiveInt",
"inputs": {
"value": [
"299",
1
]
},
"_meta": {
"title": "top_or_left_outpaint_pct"
}
},
"224:241": {
"class_type": "ImageResize+",
"inputs": {
"condition": "always",
"height": [
"224:191",
1
],
"image": [
"130",
0
],
"interpolation": "lanczos",
"method": "keep proportion",
"multiple_of": 0,
"width": [
"224:191",
0
]
},
"_meta": {
"title": "🔧 Image Resize"
}
},
"224:242": {
"class_type": "ComfyMathExpression",
"inputs": {
"expression": "floor((a - b) * (c / 100))",
"values.a": [
"224:191",
0
],
"values.b": [
"224:241",
1
],
"values.c": [
"224:240",
0
]
},
"_meta": {
"title": "pad_left"
}
},
"224:243": {
"class_type": "ComfyMathExpression",
"inputs": {
"expression": "(a - b) - floor((a - b) * (c / 100))",
"values.a": [
"224:191",
0
],
"values.b": [
"224:241",
1
],
"values.c": [
"224:240",
0
]
},
"_meta": {
"title": "pad_right"
}
},
"224:244": {
"class_type": "ComfyMathExpression",
"inputs": {
"expression": "floor((a - b) * (c / 100))",
"values.a": [
"224:191",
1
],
"values.b": [
"224:241",
2
],
"values.c": [
"224:240",
0
]
},
"_meta": {
"title": "pad_top"
}
},
"224:245": {
"class_type": "ComfyMathExpression",
"inputs": {
"expression": "(a - b) - floor((a - b) * (c / 100))",
"values.a": [
"224:191",
1
],
"values.b": [
"224:241",
2
],
"values.c": [
"224:240",
0
]
},
"_meta": {
"title": "pad_bottom"
}
},
"224:246": {
"class_type": "ImagePadForOutpaint",
"inputs": {
"bottom": [
"224:245",
1
],
"feathering": 0,
"image": [
"224:241",
0
],
"left": [
"224:242",
1
],
"right": [
"224:243",
1
],
"top": [
"224:244",
1
]
},
"_meta": {
"title": "Pad Image for Outpainting"
}
},
"224:247": {
"class_type": "GetImageSize",
"inputs": {
"image": [
"224:246",
0
]
},
"_meta": {
"title": "Get Image Size"
}
},
"224:248": {
"class_type": "EmptyImage",
"inputs": {
"batch_size": 1,
"color": 65280,
"height": [
"224:247",
1
],
"width": [
"224:247",
0
]
},
"_meta": {
"title": "Empty Image"
}
},
"224:249": {
"class_type": "ImageCompositeMasked",
"inputs": {
"destination": [
"224:246",
0
],
"mask": [
"224:246",
1
],
"resize_source": False,
"source": [
"224:248",
0
],
"x": 0,
"y": 0
},
"_meta": {
"title": "Image Composite Masked"
}
},
"224:255": {
"class_type": "ComfyMathExpression",
"inputs": {
"expression": "a - b",
"values.a": [
"224:191",
0
],
"values.b": [
"224:241",
1
]
},
"_meta": {
"title": "has_horizontal_slack"
}
},
"280:152": {
"class_type": "CFGNorm",
"inputs": {
"model": [
"280:155",
0
],
"pre_cfg": False,
"strength": 1
},
"_meta": {
"title": "CFGNorm"
}
},
"280:155": {
"class_type": "ModelSamplingAuraFlow",
"inputs": {
"model": [
"280:166",
0
],
"sampling": "flow",
"shift": 3.1
},
"_meta": {
"title": "ModelSamplingAuraFlow"
}
},
"280:156": {
"class_type": "VAELoader",
"inputs": {
"vae_name": "qwen_image_vae.safetensors"
},
"_meta": {
"title": "Load VAE"
}
},
"280:161": {
"class_type": "TextEncodeQwenImageEditPlus",
"inputs": {
"clip": [
"280:167",
0
],
"image1": [
"280:176",
0
],
"prompt": [
"279",
0
],
"vae": [
"280:156",
0
]
},
"_meta": {
"title": "TextEncodeQwenImageEditPlus (Positive)"
}
},
"280:162": {
"class_type": "LoraLoaderModelOnly",
"inputs": {
"lora_name": "Qwen-Image-Edit-2511-Lightning-4steps-V1.0-bf16.safetensors",
"model": [
"280:152",
0
],
"strength_model": 1
},
"_meta": {
"title": "Load LoRA"
}
},
"280:163": {
"class_type": "PrimitiveFloat",
"inputs": {
"value": 4
},
"_meta": {
"title": "CFG"
}
},
"280:164": {
"class_type": "PrimitiveFloat",
"inputs": {
"value": 1
},
"_meta": {
"title": "CFG"
}
},
"280:165": {
"class_type": "VAEEncode",
"inputs": {
"pixels": [
"280:176",
0
],
"vae": [
"280:156",
0
]
},
"_meta": {
"title": "VAE Encode"
}
},
"280:166": {
"class_type": "UNETLoader",
"inputs": {
"unet_name": "qwen_image_edit_2511_bf16.safetensors",
"weight_dtype": "default"
},
"_meta": {
"title": "Load Diffusion Model"
}
},
"280:167": {
"class_type": "CLIPLoader",
"inputs": {
"clip_name": "qwen_2.5_vl_7b_fp8_scaled.safetensors",
"device": "default",
"type": "qwen_image"
},
"_meta": {
"title": "Load CLIP"
}
},
"280:168": {
"class_type": "ComfySwitchNode",
"inputs": {
"on_false": [
"280:152",
0
],
"on_true": [
"280:162",
0
],
"switch": [
"280:171",
0
]
},
"_meta": {
"title": "Switch (Model)"
}
},
"280:169": {
"class_type": "PrimitiveInt",
"inputs": {
"value": 6
},
"_meta": {
"title": "Steps"
}
},
"280:170": {
"class_type": "PrimitiveInt",
"inputs": {
"value": 30
},
"_meta": {
"title": "Steps"
}
},
"280:171": {
"class_type": "PrimitiveBoolean",
"inputs": {
"value": True
},
"_meta": {
"title": "Enable 4steps LoRA?"
}
},
"280:172": {
"class_type": "ComfySwitchNode",
"inputs": {
"on_false": [
"280:163",
0
],
"on_true": [
"280:164",
0
],
"switch": [
"280:171",
0
]
},
"_meta": {
"title": "Switch (CFG)"
}
},
"280:173": {
"class_type": "ComfySwitchNode",
"inputs": {
"on_false": [
"280:170",
0
],
"on_true": [
"280:169",
0
],
"switch": [
"280:171",
0
]
},
"_meta": {
"title": "Switch (Steps)"
}
},
"280:174": {
"class_type": "KSampler",
"inputs": {
"cfg": [
"280:172",
0
],
"denoise": 1,
"latent_image": [
"280:165",
0
],
"model": [
"280:168",
0
],
"negative": [
"280:229",
0
],
"positive": [
"280:161",
0
],
"sampler_name": "euler",
"scheduler": "simple",
"seed": 927215755554477,
"steps": [
"280:173",
0
]
},
"_meta": {
"title": "KSampler"
}
},
"280:175": {
"class_type": "VAEDecode",
"inputs": {
"samples": [
"280:174",
0
],
"vae": [
"280:156",
0
]
},
"_meta": {
"title": "VAE Decode"
}
},
"280:176": {
"class_type": "FluxKontextImageScale",
"inputs": {
"image": [
"303",
0
]
},
"_meta": {
"title": "FluxKontextImageScale"
}
},
"280:229": {
"class_type": "TextEncodeQwenImageEditPlus",
"inputs": {
"clip": [
"280:167",
0
],
"image1": [
"280:176",
0
],
"prompt": "",
"vae": [
"280:156",
0
]
},
"_meta": {
"title": "Text Encode Qwen Image Edit Plus"
}
}
})
workflow.set_input("130", "image", client.assets.from_url("https://comfy.org/catalog-media/c6df7625-c30c-4730-9f25-7ef00ee1d5cd/3a3c3a6e-c9ff-4609-a07d-a6c065021249"))
# run() also passes api_key to the partner nodes in this workflow.
job = client.run(workflow, api_key=api_key)
for output in job.get_outputs("302"):
output.to_file(output.name)例を試す
このワークフローについて
Expand Image is a guided outpainting workflow that grows a single photo to any target aspect ratio without cropping or distorting the original pixels. It wraps your image in a flat green matte to reach the new canvas size, then uses Qwen Image Edit 2511 to replace only the green area with believable scene continuation. Core utility nodes—GetImageSize, ImageResizeKJv2, CustomCombo, and ComfyNumberConvert—calculate the new dimensions and margins so the source stays centered and untouched while the surrounding frame becomes the editable region.
To keep the new content on-style and on-topic, the workflow can automatically write a scene-continuation caption for the missing region using TextGenerateLTX2Prompt and a local VLM backend (configured by you), then JsonExtractString parses the result. A ComfySwitchNode lets you flip between that auto caption and a manual description you type in PrimitiveStringMultiline. The final instruction is assembled with StringConcatenate and, together with CLIPLoader (for text conditioning when required), guides Qwen Image Edit 2511 to synthesize lighting, materials, and perspective that match the visible photo.
PreviewAny and ImageCompare help you evaluate changes, and SaveImageAdvanced stores the outpainted result and metadata for reproducibility.
よくある質問
No. The workflow keeps your source image intact and adds a flat green border to reach the new canvas size. Only that green area is replaced during outpainting.
Set the ComfySwitchNode to Manual and type your continuation description in PrimitiveStringMultiline. You can still get excellent results by describing surfaces, lighting, perspective, and what should extend into the green area.
Be specific in the region description: mention horizon position, floor/wall continuation, materials (brick, marble, foliage), time of day, and color temperature. Keep the prompt grounded in what’s visible. Adjust the base style string and try moderate aspect changes before extreme ones.
GetImageSize + ImageResizeKJv2 (with CustomCombo and ComfyNumberConvert) compute the new canvas and green margins. TextGenerateLTX2Prompt (auto) or PrimitiveStringMultiline (manual) supplies the region description, selected via ComfySwitchNode and assembled with StringConcatenate. CLIPLoader provides text conditioning if required by the edit model.