Character + Clothing Virtual Try on Studio Photoshoot
Upload an image of your character and a flat lay image of your clothing items. Generate 4 fashion editorial photographs of your character in the outfit. Select which image to upscale and add back details.
概要
This workflow builds a fast, reference-guided virtual try‑on pipeline for characters. You provide two images via LoadImage: a clear character image (face and body framing) and a flat‑lay of the clothing. A prompt entered with PrimitiveStringMultiline describes pose, studio lighting, background, and styling cues. OpenAIGPTImageNodeV2 then generates a batch of four fashion‑editorial variations and arranges them into a 2×2 contact sheet for quick review. PreviewImage shows the grid, and ImageCompare can be used to examine differences side‑by‑side.
Under the hood, the same references (character and clothing) drive both the initial batch and the upscale path to preserve facial identity and outfit details. A utility node (663da6e9-8b62-4291-a9d6-e4b8fd672197) in this graph is wired to handle the 2×2 grid output and crop it back into four 1K (approx. 1024×1024) tiles. You select one tile with ImageFromBatch by setting batch_index (0–3, starting at top‑left) and feed it into the Upscale Selected Image group. The upscale pass uses OpenAIGPTImageNodeV2 again at 2048×2048 while reusing your original references for consistency, then writes results with SaveImage.
MarkdownNote and Note nodes in the canvas provide inline reminders and tips.
入力するもの
- ワークフローを読み込み中
ComfyUI で実行できます。 このワークフローはこのページでは実行できません。すべてが読み込まれた状態でComfy Cloudで開くか、ご自身のComfyUI用にダウンロードしてください。
Cloudで試す例を試す
ワークフローの内部
ノードグラフの読み取り専用プレビューです。ノードを編集するには、Comfy Cloudで開くかダウンロードしてください。
Loading the graph
Open full-size workflow preview- 作成者
- Rob
カスタムノードが必要です
- ワークフローを読み込み中
コードからこのワークフローを使用する
可能な場合はワークフローグラフと入力から生成されます。それ以外の場合は保存された例が表示されます。料金が発生する場合があるため、コードを実行する前に認証情報とエンドポイントを確認してください。
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({
"1": {
"class_type": "LoadImage",
"inputs": {
"image": "UPLOADED_image_FILENAME"
},
"_meta": {
"title": "Load Subject Image"
}
},
"5": {
"class_type": "PrimitiveStringMultiline",
"inputs": {
"value": "A 2x2 (2 rows, 2 cols) grid of high fashion photoshoot images of the model wearing the outfit from image 2, each grid image should show the a full body shot of the subject in slightly different poses. Ensure that all outfit clothes/accessories are present in each grid image.\n\nThe background setting is a studio environment with a white studio background. Ensure that each grid image has the same lighting conditions. \n\nDO NOT generate the grid with any visible borders or gutters.\n\nThe image is shot on fuji velvia film on a 55mm prime lens, the light is concentrated on the subject."
},
"_meta": {
"title": "Prompt"
}
},
"8": {
"class_type": "SaveImage",
"inputs": {
"filename_prefix": "ComfyUI-image_stitched",
"images": [
"149",
0
]
},
"_meta": {
"title": "Save Stitched Image"
}
},
"12": {
"class_type": "SaveImage",
"inputs": {
"filename_prefix": "ComfyUI-image_1",
"images": [
"146:57",
0
]
},
"_meta": {
"title": "Save Image"
}
},
"13": {
"class_type": "SaveImage",
"inputs": {
"filename_prefix": "ComfyUI-image_2",
"images": [
"146:143",
0
]
},
"_meta": {
"title": "Save Image"
}
},
"14": {
"class_type": "SaveImage",
"inputs": {
"filename_prefix": "ComfyUI-image_3",
"images": [
"146:140",
0
]
},
"_meta": {
"title": "Save Image"
}
},
"15": {
"class_type": "SaveImage",
"inputs": {
"filename_prefix": "ComfyUI-image_4",
"images": [
"146:144",
0
]
},
"_meta": {
"title": "Save Image"
}
},
"23": {
"class_type": "ImageFromBatch",
"inputs": {
"batch_index": 0,
"image": [
"146:137",
0
],
"length": 1
},
"_meta": {
"title": "Select Image to Upscale"
}
},
"26": {
"class_type": "SaveImage",
"inputs": {
"filename_prefix": "ComfyUI-image_upscaled",
"images": [
"150",
0
]
},
"_meta": {
"title": "Save Upscaled Image"
}
},
"27": {
"class_type": "PreviewImage",
"inputs": {
"images": [
"23",
0
]
},
"_meta": {
"title": "Preview Selected Image"
}
},
"35": {
"class_type": "LoadImage",
"inputs": {
"image": "UPLOADED_image_2_FILENAME"
},
"_meta": {
"title": "Load Outfit Image"
}
},
"149": {
"class_type": "OpenAIGPTImageNodeV2",
"inputs": {
"model": "gpt-image-2",
"model.background": "auto",
"model.custom_height": 1024,
"model.custom_width": 1024,
"model.images.image_1": [
"1",
0
],
"model.images.image_2": [
"35",
0
],
"model.quality": "low",
"model.size": "2048x2048",
"n": 1,
"prompt": [
"5",
0
],
"seed": 111
},
"_meta": {
"title": "OpenAI GPT Image 2.5"
}
},
"150": {
"class_type": "OpenAIGPTImageNodeV2",
"inputs": {
"model": "gpt-image-2",
"model.background": "auto",
"model.custom_height": 1024,
"model.custom_width": 1024,
"model.images.image_1": [
"23",
0
],
"model.images.image_2": [
"1",
0
],
"model.images.image_3": [
"35",
0
],
"model.quality": "high",
"model.size": "2048x2048",
"n": 1,
"prompt": "Generate a high resolution image. Upscale image 1 while maintaining pose, background and composition, add subtle details. Use the face from image 2 to add back facial consistency and ensure the outfit details match the clothes and accessories from image 3.",
"seed": 222
},
"_meta": {
"title": "OpenAI GPT Image 2.5"
}
},
"154": {
"class_type": "ImageCompare",
"inputs": {
"compare_view": None,
"image_a": [
"23",
0
],
"image_b": [
"150",
0
]
},
"_meta": {
"title": "Compare Before/After Upscale Images"
}
},
"146:137": {
"class_type": "BatchImagesNode",
"inputs": {
"images.image0": [
"146:57",
0
],
"images.image1": [
"146:143",
0
],
"images.image2": [
"146:140",
0
],
"images.image3": [
"146:144",
0
]
},
"_meta": {
"title": "Batch Images"
}
},
"146:138": {
"class_type": "ComfyMathExpression",
"inputs": {
"expression": "max(1, a - b)",
"values.a": [
"146:55",
0
],
"values.b": [
"146:54",
1
]
},
"_meta": {
"title": "Math Expression (Right Width)"
}
},
"146:139": {
"class_type": "ComfyMathExpression",
"inputs": {
"expression": "max(1, a - b)",
"values.a": [
"146:55",
1
],
"values.b": [
"146:59",
1
]
},
"_meta": {
"title": "Math Expression (Bottom Height)"
}
},
"146:140": {
"class_type": "ImageCropV2",
"inputs": {
"crop_region": [
"146:141",
0
],
"image": [
"149",
0
]
},
"_meta": {
"title": "Crop Image"
}
},
"146:141": {
"class_type": "PrimitiveBoundingBox",
"inputs": {
"height": [
"146:139",
1
],
"width": [
"146:54",
1
],
"x": 0,
"y": [
"146:59",
1
]
},
"_meta": {
"title": "Bounding Box"
}
},
"146:142": {
"class_type": "PrimitiveBoundingBox",
"inputs": {
"height": [
"146:59",
1
],
"width": [
"146:138",
1
],
"x": [
"146:54",
1
],
"y": 0
},
"_meta": {
"title": "Bounding Box"
}
},
"146:143": {
"class_type": "ImageCropV2",
"inputs": {
"crop_region": [
"146:142",
0
],
"image": [
"149",
0
]
},
"_meta": {
"title": "Crop Image"
}
},
"146:144": {
"class_type": "ImageCropV2",
"inputs": {
"crop_region": [
"146:145",
0
],
"image": [
"149",
0
]
},
"_meta": {
"title": "Crop Image"
}
},
"146:145": {
"class_type": "PrimitiveBoundingBox",
"inputs": {
"height": [
"146:139",
1
],
"width": [
"146:138",
1
],
"x": [
"146:54",
1
],
"y": [
"146:59",
1
]
},
"_meta": {
"title": "Bounding Box"
}
},
"146:54": {
"class_type": "ComfyMathExpression",
"inputs": {
"expression": "max(1, int(a/b))",
"values.a": [
"146:55",
0
],
"values.b": [
"146:56",
0
]
},
"_meta": {
"title": "Math Expression"
}
},
"146:55": {
"class_type": "GetImageSize",
"inputs": {
"image": [
"149",
0
]
},
"_meta": {
"title": "Get Image Size"
}
},
"146:56": {
"class_type": "PrimitiveInt",
"inputs": {
"value": 2
},
"_meta": {
"title": "Int"
}
},
"146:57": {
"class_type": "ImageCropV2",
"inputs": {
"crop_region": [
"146:58",
0
],
"image": [
"149",
0
]
},
"_meta": {
"title": "Crop Image"
}
},
"146:58": {
"class_type": "PrimitiveBoundingBox",
"inputs": {
"height": [
"146:59",
1
],
"width": [
"146:54",
1
],
"x": 0,
"y": 0
},
"_meta": {
"title": "Bounding Box"
}
},
"146:59": {
"class_type": "ComfyMathExpression",
"inputs": {
"expression": "max(1, int(a/b))",
"values.a": [
"146:55",
1
],
"values.b": [
"146:56",
0
]
},
"_meta": {
"title": "Math Expression"
}
}
})
# Replace each example.com URL with a public URL of your file.
workflow.set_input("1", "image", client.assets.from_url("https://example.com/replace-with-a-url/image"))
workflow.set_input("35", "image", client.assets.from_url("https://example.com/replace-with-a-url/image_2"))
# run() also passes api_key to the partner nodes in this workflow.
job = client.run(workflow, api_key=api_key)よくある質問
Both stages use the same character and flat-lay clothing images as references in OpenAIGPTImageNodeV2. The upscale pass reuses those references, so identity and garment details are reinforced rather than regenerated from scratch.
For the character: a clear, well-lit image with the face unobstructed and minimal background clutter. For the garment: a flat-lay on a plain background with the full front of the item visible, not folded, and without heavy occlusions or busy patterns in the backdrop.
Use the ImageFromBatch node and set batch_index to the tile you want (0=top-left, 1=top-right, 2=bottom-left, 3=bottom-right). The author note reminds that indexing starts at 0.
Yes. Edit the PrimitiveStringMultiline prompt to specify pose direction (e.g., three-quarter, walking stride), focal length or framing (full body, mid-shot), lighting (softbox, rim light), and background (seamless, colored paper). Re-run the 2×2 Grid Generation group to preview new variations.