Put your product in a new scene
Place a product into a new setting and match its lighting to the scene.
下载工作流在 Cloud 中试用 API 文档
查看工作流内部
源模板的只读预览。在 Cloud 中打开,即可查看节点并进行修改。
Loading the graph
Open full-size workflow preview- 作者
- Rob
从代码中调用该模型
以下请求使用与体验区相同的预设图和设置。每次提交都可能开始一次付费运行;如果提交结果未知,请勿自动重试。
1 获取 API 密钥 ↗
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_image1_FILENAME"
},
"_meta": {
"title": "Load Product Image"
}
},
"2": {
"class_type": "LoadImage",
"inputs": {
"image": "UPLOADED_image2_FILENAME"
},
"_meta": {
"title": "Load Background Image"
}
},
"12": {
"class_type": "PrimitiveStringMultiline",
"inputs": {
"value": "Task: Realistic Product Compositing with Material Preservation Goal: Insert the product from Input 2 into Input 1, ensuring placement is logical and lighting interacts accurately with the product's specific material properties.\n\nInput Image(s):\n\nInput 1 (Scene)\nInput 2 (Product): {product_description}\n\nManual Material Breakdown (Critical): To ensure correct light interaction, treat the product as having the following physical properties:\n\nPrimary Material: [e.g., Matte Plastic / Brushed Aluminum / Clear Glass]\n\nReflectivity: [e.g., Low (dull reflections) / High (mirror-like)]\n\nTexture: [e.g., Smooth / Grainy / Porous]\n\nReaction to Light: [e.g., \"Should absorb light with soft highlights, no sharp glares\"]\n\nSecondary Material (if any): [e.g., Gold Foil Label / Glossy Cap]\n\nReaction to Light: [e.g., \"Should catch sharp, bright specular highlights from the environment\"]\n\nProcess:\nScene Analysis: Identify the logical ground plane/surface in Input 1.\n\nPlacement: Scale Input 2 uniformly (maintain aspect ratio) and place it on the surface.\n\nMaterial-Based Relighting:\n\nDo not simply overlay the scene colors onto the product.\nInstead, map the environment light from Input 1 onto the contours of Input 2 based on the material definitions above.\n\nExample: If the material is Matte, only the edge lighting and general ambient tone should change; do not add sharp reflections.\n\nExample: If the material is Glossy, reflect the scene's details on the surface.\n\nShadows: Generate contact shadows that match the hardness/softness of shadows in the rest of the scene.\n\nTechnical Requirements:\nAlbedo Preservation: The intrinsic color of the product (e.g., \"Brand Red\") must not be washed out by the scene's lighting color.\n\nTexture Fidelity: Do not smooth out surface details (grain, bumps) during the blending process.\n\nScaling: No non-uniform stretching.\n\nOutput: A composite where the lighting confirms the materiality of the product (e.g., makes the plastic look like plastic, not metal)."
},
"_meta": {
"title": "Prompt Template"
}
},
"13": {
"class_type": "RegexReplace",
"inputs": {
"case_insensitive": True,
"count": 0,
"dotall": False,
"multiline": False,
"regex_pattern": "{product_description}",
"replace": [
"14",
0
],
"string": [
"12",
0
]
},
"_meta": {
"title": "Replace Text (Regex)"
}
},
"14": {
"class_type": "PrimitiveStringMultiline",
"inputs": {
"value": "A dispenser bottle filled with viscuous clear liquid, with a metallic top, \"C\" logo and a clear glass body"
},
"_meta": {
"title": "Describe the Product"
}
},
"22": {
"class_type": "ByteDanceSeedreamNode",
"inputs": {
"fail_on_partial": True,
"height": 2048,
"image": [
"15:15",
0
],
"max_images": 1,
"model": "seedream-4-5-251128",
"prompt": [
"13",
0
],
"seed": 406946789,
"sequential_image_generation": "disabled",
"size_preset": "2048x2048 (1:1)",
"watermark": False,
"width": 2048
},
"_meta": {
"title": "ByteDance Seedream 4.5 & 5.0"
}
},
"23": {
"class_type": "SaveImage",
"inputs": {
"filename_prefix": "ComfyUI",
"images": [
"22",
0
]
},
"_meta": {
"title": "Save Image"
}
},
"15:15": {
"class_type": "BatchImagesNode",
"inputs": {
"images.image0": [
"2",
0
],
"images.image1": [
"15:6",
0
]
},
"_meta": {
"title": "Batch Images"
}
},
"15:5": {
"class_type": "GetImageSize",
"inputs": {
"image": [
"2",
0
]
},
"_meta": {
"title": "Get Image Size"
}
},
"15:6": {
"class_type": "ResizeAndPadImage",
"inputs": {
"image": [
"1",
0
],
"interpolation": "area",
"padding_color": "white",
"target_height": [
"15:5",
1
],
"target_width": [
"15:5",
0
]
},
"_meta": {
"title": "Resize And Pad Image"
}
}
})
workflow.set_input("1", "image", client.assets.from_url("https://cdn.jsdelivr.net/gh/Comfy-Org/workflow_templates@90c71fb78b3726392d010ff62a8e79e92d7296ad/input/comfy_shampoo.png"))
workflow.set_input("2", "image", client.assets.from_url("https://cdn.jsdelivr.net/gh/Comfy-Org/workflow_templates@90c71fb78b3726392d010ff62a8e79e92d7296ad/input/flower_sea.png"))
# 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("23"):
output.to_file(output.name)