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
- 你的文件
- 由代码根据链接上传
需要付费的 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.