Headshot Generator
Upload a selfie, pick an outfit with a backdrop and generate a professional quality headshot portrait of yourself.
简介
This Headshot Generator workflow lets you upload a selfie, choose an outfit and backdrop, and produce a polished, professional portrait. It wires together text controls and image conditioning so your face is preserved while the clothing and background are restyled. Your selfie is brought in with LoadImage and routed into a core generation node (ID: d4c06663-cb1a-4a41-a36b-f09c93e55e7e) that handles the actual synthesis. PreviewAny gives you quick visual checks, and SaveImage writes final results to disk.
Outfit and backdrop are managed with text nodes so you can work from presets or free‑type instructions. PrimitiveStringMultiline holds a small JSON block of presets; JsonExtractString pulls fields like outfit and backdrop from that JSON. ComfySwitchNode lets you toggle between preset-driven text and a custom prompt path. StringConcatenate assembles the final instruction text the generator sees (for example, a base headshot prompt plus your selected outfit and backdrop). A CustomCombo node encapsulates supporting pieces of the pipeline, so model loading and sampler details stay tidy while still exposing the key inputs you need for fast iteration.
你需要提供
- 正在读取工作流
在 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({
"132": {
"class_type": "LoadImage",
"inputs": {
"image": "30c332ffe0857813d284f963528c35e38b31234a681dfebe21db55c766f5cfa8.png"
},
"_meta": {
"title": "Load Image"
}
},
"197": {
"class_type": "SaveImage",
"inputs": {
"filename_prefix": "Qwen_Edit_2511",
"images": [
"196:175",
0
]
},
"_meta": {
"title": "Save Image"
}
},
"234": {
"class_type": "StringConcatenate",
"inputs": {
"delimiter": " ",
"string_a": "Keep the exact same facial identity as the original photo. Headshot portrait.",
"string_b": [
"258",
0
]
},
"_meta": {
"title": "Assemble Prompt"
}
},
"235": {
"class_type": "PreviewAny",
"inputs": {
"source": [
"234",
0
]
},
"_meta": {
"title": "Preview as Text"
}
},
"252": {
"class_type": "CustomCombo",
"inputs": {
"choice": "Black Suit and Tie"
},
"_meta": {
"title": "Outfit"
}
},
"253": {
"class_type": "JsonExtractString",
"inputs": {
"json_string": "{\n \"Black Suit and Tie\": \"The subject wears a black tailored suit, a crisp white dress shirt, and a black silk tie.\",\n \"Charcoal Suit and Tie\": \"The subject wears a charcoal gray tailored suit, a light blue dress shirt, and a burgundy silk tie.\",\n \"Navy Suit, No Tie\": \"The subject wears a navy blue tailored suit over a crisp white dress shirt, top button open, no tie.\",\n \"Navy Blazer, White Shirt\": \"The subject wears a navy blue blazer over a white open-collar shirt, smart business-casual.\",\n \"Black Tuxedo and Bow Tie\": \"The subject wears a black tuxedo with satin lapels, a white dress shirt, and a black bow tie.\",\n \"Black Turtleneck\": \"The subject wears a fitted black merino turtleneck, clean and modern.\",\n \"White Button-Up\": \"The subject wears a crisp white button-up shirt, top button open, neatly pressed.\",\n \"Light Blue Button-Up\": \"The subject wears a light blue oxford button-up shirt, crisp and approachable.\",\n \"Gray Crewneck Sweater\": \"The subject wears a heather-gray crewneck sweater over a white collared shirt.\",\n \"Cream Knit Sweater\": \"The subject wears a cream cable-knit sweater, warm and relaxed.\",\n \"Black Leather Jacket\": \"The subject wears a black leather jacket over a plain white t-shirt.\",\n \"Blue Denim Shirt\": \"The subject wears a mid-wash blue denim button-up shirt, relaxed and casual.\",\n \"Red Floral Shirt\": \"The subject wears a red tropical floral short-sleeve shirt, playful and confident.\",\n \"Camel Overcoat\": \"The subject wears a tailored camel overcoat over a black crewneck sweater.\",\n \"Brown Tweed Blazer\": \"The subject wears a brown tweed blazer with a cream shirt and a dark knit tie.\"\n}",
"key": [
"252",
0
]
},
"_meta": {
"title": "Outfit Prompt (JSON)"
}
},
"254": {
"class_type": "CustomCombo",
"inputs": {
"choice": "Studio Gray"
},
"_meta": {
"title": "Backdrop"
}
},
"255": {
"class_type": "JsonExtractString",
"inputs": {
"json_string": "{\n \"Studio Gray\": \"Set against a seamless mid-gray studio backdrop with polished three-point lighting and a soft rim light.\",\n \"Studio White\": \"Set against a seamless pure-white studio backdrop with bright, airy high-key lighting.\",\n \"Studio Black\": \"Set against a seamless deep-black studio backdrop with a dramatic soft key and subtle rim light.\",\n \"Studio Pink\": \"Set against a seamless pastel-pink studio backdrop with bright, even, flattering light.\",\n \"Studio Blue\": \"Set against a seamless soft steel-blue gradient studio backdrop with clean directional lighting.\",\n \"Studio Beige\": \"Set against a seamless warm beige studio backdrop with soft golden key light.\",\n \"Modern Office\": \"Set in a softly blurred modern office interior with bright natural window light and gentle bokeh.\",\n \"Conference Room\": \"Set in a softly blurred glass-walled conference room with cool professional daylight.\",\n \"Bookshelf Office\": \"Set in a softly blurred office with warm wooden bookshelves and gentle window light.\",\n \"Exposed Brick Loft\": \"Set in a softly blurred exposed red-brick loft with warm ambient tungsten light.\",\n \"Outdoor Golden Hour\": \"Set against a softly blurred leafy outdoor background in warm golden-hour sunlight with creamy bokeh.\",\n \"Overcast Street\": \"Set on a softly blurred city street under even overcast daylight with muted gray-blue tones.\",\n \"Garden Greenery\": \"Set against softly blurred lush green garden foliage in bright natural daylight.\",\n \"City Skyline\": \"Set before a softly blurred floor-to-ceiling window overlooking a city skyline in cool daylight.\",\n \"Rooftop Sunset\": \"Set on a softly blurred rooftop terrace at sunset with warm orange-and-violet sky tones.\"\n}",
"key": [
"254",
0
]
},
"_meta": {
"title": "Backdrop Prompt (JSON)"
}
},
"256": {
"class_type": "StringConcatenate",
"inputs": {
"delimiter": " ",
"string_a": [
"253",
0
],
"string_b": [
"255",
0
]
},
"_meta": {
"title": "Outfit + Backdrop"
}
},
"257": {
"class_type": "PrimitiveStringMultiline",
"inputs": {
"value": "The subject wears a black tailored suit with a white shirt. Set against a seamless dark teal studio backdrop with soft dramatic lighting."
},
"_meta": {
"title": "Custom Prompt Text"
}
},
"258": {
"class_type": "ComfySwitchNode",
"inputs": {
"on_false": [
"256",
0
],
"on_true": [
"257",
0
],
"switch": False
},
"_meta": {
"title": "Custom Prompt?"
}
},
"196:152": {
"class_type": "CFGNorm",
"inputs": {
"model": [
"196:155",
0
],
"pre_cfg": False,
"strength": 1
},
"_meta": {
"title": "CFGNorm"
}
},
"196:155": {
"class_type": "ModelSamplingAuraFlow",
"inputs": {
"model": [
"196:166",
0
],
"sampling": "flow",
"shift": 3.1
},
"_meta": {
"title": "ModelSamplingAuraFlow"
}
},
"196:156": {
"class_type": "VAELoader",
"inputs": {
"vae_name": "qwen_image_vae.safetensors"
},
"_meta": {
"title": "Load VAE"
}
},
"196:161": {
"class_type": "TextEncodeQwenImageEditPlus",
"inputs": {
"clip": [
"196:167",
0
],
"image1": [
"196:176",
0
],
"prompt": [
"235",
0
],
"vae": [
"196:156",
0
]
},
"_meta": {
"title": "TextEncodeQwenImageEditPlus (Positive)"
}
},
"196:162": {
"class_type": "LoraLoaderModelOnly",
"inputs": {
"lora_name": "Qwen-Image-Edit-2511-Lightning-4steps-V1.0-bf16.safetensors",
"model": [
"196:152",
0
],
"strength_model": 1
},
"_meta": {
"title": "Load LoRA"
}
},
"196:163": {
"class_type": "PrimitiveFloat",
"inputs": {
"value": 4
},
"_meta": {
"title": "CFG"
}
},
"196:164": {
"class_type": "PrimitiveFloat",
"inputs": {
"value": 1
},
"_meta": {
"title": "CFG"
}
},
"196:165": {
"class_type": "VAEEncode",
"inputs": {
"pixels": [
"196:176",
0
],
"vae": [
"196:156",
0
]
},
"_meta": {
"title": "VAE Encode"
}
},
"196:166": {
"class_type": "UNETLoader",
"inputs": {
"unet_name": "qwen_image_edit_2511_bf16.safetensors",
"weight_dtype": "default"
},
"_meta": {
"title": "Load Diffusion Model"
}
},
"196:167": {
"class_type": "CLIPLoader",
"inputs": {
"clip_name": "qwen_2.5_vl_7b_fp8_scaled.safetensors",
"device": "default",
"type": "qwen_image"
},
"_meta": {
"title": "Load CLIP"
}
},
"196:168": {
"class_type": "ComfySwitchNode",
"inputs": {
"on_false": [
"196:152",
0
],
"on_true": [
"196:162",
0
],
"switch": [
"196:171",
0
]
},
"_meta": {
"title": "Switch (Model)"
}
},
"196:169": {
"class_type": "PrimitiveInt",
"inputs": {
"value": 6
},
"_meta": {
"title": "Steps"
}
},
"196:170": {
"class_type": "PrimitiveInt",
"inputs": {
"value": 30
},
"_meta": {
"title": "Steps"
}
},
"196:171": {
"class_type": "PrimitiveBoolean",
"inputs": {
"value": True
},
"_meta": {
"title": "Enable 4steps LoRA?"
}
},
"196:172": {
"class_type": "ComfySwitchNode",
"inputs": {
"on_false": [
"196:163",
0
],
"on_true": [
"196:164",
0
],
"switch": [
"196:171",
0
]
},
"_meta": {
"title": "Switch (CFG)"
}
},
"196:173": {
"class_type": "ComfySwitchNode",
"inputs": {
"on_false": [
"196:170",
0
],
"on_true": [
"196:169",
0
],
"switch": [
"196:171",
0
]
},
"_meta": {
"title": "Switch (Steps)"
}
},
"196:174": {
"class_type": "KSampler",
"inputs": {
"cfg": [
"196:172",
0
],
"denoise": 1,
"latent_image": [
"196:244",
0
],
"model": [
"196:168",
0
],
"negative": [
"196:229",
0
],
"positive": [
"196:161",
0
],
"sampler_name": "euler",
"scheduler": "simple",
"seed": 111,
"steps": [
"196:173",
0
]
},
"_meta": {
"title": "KSampler"
}
},
"196:175": {
"class_type": "VAEDecode",
"inputs": {
"samples": [
"196:174",
0
],
"vae": [
"196:156",
0
]
},
"_meta": {
"title": "VAE Decode"
}
},
"196:176": {
"class_type": "FluxKontextImageScale",
"inputs": {
"image": [
"132",
0
]
},
"_meta": {
"title": "FluxKontextImageScale"
}
},
"196:229": {
"class_type": "TextEncodeQwenImageEditPlus",
"inputs": {
"clip": [
"196:167",
0
],
"image1": [
"196:176",
0
],
"prompt": "",
"vae": [
"196:156",
0
]
},
"_meta": {
"title": "Text Encode Qwen Image Edit Plus"
}
},
"196:244": {
"class_type": "EmptyLatentImage",
"inputs": {
"batch_size": 1,
"height": [
"196:245",
1
],
"width": [
"196:245",
0
]
},
"_meta": {
"title": "Empty Latent Image"
}
},
"196:245": {
"class_type": "ResolutionSelector",
"inputs": {
"aspect_ratio": "1:1 (Square)",
"megapixels": 1,
"multiple": 8
},
"_meta": {
"title": "Resolution Selector"
}
}
})
# run() also passes api_key to the partner nodes in this workflow.
job = client.run(workflow, api_key=api_key)常见问答
Open PrimitiveStringMultiline and edit the JSON. Include keys your JsonExtractString nodes expect (commonly "outfit" and "backdrop"). Example: {"outfit": "navy blazer, white shirt", "backdrop": "soft gray studio backdrop"}. Run the graph to apply.
Use a sharp, well-lit, front-facing selfie with your full face visible and minimal clutter. Crop so your head and shoulders dominate the frame. If your CustomCombo/core node exposes an image influence/strength control, increase it slightly to prioritize the selfie over stylization.
Yes. Toggle ComfySwitchNode to the custom prompt path and enter a clear, single-line or multiline description (e.g., “professional headshot, charcoal suit, light gray seamless backdrop”). The graph will route that text directly to the generator.
PreviewAny shows quick checks, while SaveImage writes the final render. If your CustomCombo or the core generator node exposes parameters (e.g., resolution, steps, guidance), adjust them there. If not exposed, open the CustomCombo to reveal internal settings.