Wan2.2 Animate: Automatic Character Replacement
Upload a video and a character image. Automatically replace the character in the video using the Wan2.2 Animate model.
查看工作流内部
源模板的只读预览。在 Cloud 中打开,即可查看节点并进行修改。
Loading the graph
Open full-size workflow preview- 输出
- 视频
- 作者
- Purz
从代码中调用该模型
以下请求使用与体验区相同的预设图和设置。每次提交都可能开始一次付费运行;如果提交结果未知,请勿自动重试。
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({
"10": {
"class_type": "LoadImage",
"inputs": {
"image": "UPLOADED_image_FILENAME"
},
"_meta": {
"title": "Reference Image"
}
},
"19": {
"class_type": "SaveVideo",
"inputs": {
"filename_prefix": "video/ComfyUI",
"format": "auto",
"format.codec": "auto",
"video": [
"344:232:15",
0
]
},
"_meta": {
"title": "Save Video"
}
},
"159": {
"class_type": "PrimitiveInt",
"inputs": {
"value": 1280
},
"_meta": {
"title": "Width"
}
},
"160": {
"class_type": "PrimitiveInt",
"inputs": {
"value": 720
},
"_meta": {
"title": "Height"
}
},
"301": {
"class_type": "VHS_LoadVideo",
"inputs": {
"custom_height": 0,
"custom_width": 0,
"force_rate": 0,
"format": "AnimateDiff",
"frame_load_cap": 0,
"select_every_nth": 1,
"skip_first_frames": 0,
"video": "UPLOADED_video_FILENAME"
},
"_meta": {
"title": "Input Video"
}
},
"314": {
"class_type": "VHS_VideoInfo",
"inputs": {
"video_info": [
"301",
3
]
},
"_meta": {
"title": "Video Info 🎥🅥🅗🅢"
}
},
"344:1": {
"class_type": "CLIPTextEncode",
"inputs": {
"clip": [
"344:2",
0
],
"text": "色调艳丽,过曝,静态,细节模糊不清,字幕,风格,作品,画作,画面,静止,整体发灰,最差质量,低质量,JPEG压缩残留,丑陋的,残缺的,多余的手指,画得不好的手部,画得不好的脸部,畸形的,毁容的,形态畸形的肢体,手指融合,静止不动的画面,杂乱的背景,三条腿,背景人很多,倒着走"
},
"_meta": {
"title": "CLIP Text Encode (Negative Prompt)"
}
},
"344:18": {
"class_type": "LoraLoaderModelOnly",
"inputs": {
"lora_name": "lightx2v_I2V_14B_480p_cfg_step_distill_rank64_bf16.safetensors",
"model": [
"344:20",
0
],
"strength_model": 1
},
"_meta": {
"title": "Load LoRA"
}
},
"344:2": {
"class_type": "CLIPLoader",
"inputs": {
"clip_name": "umt5_xxl_fp8_e4m3fn_scaled.safetensors",
"device": "default",
"type": "wan"
},
"_meta": {
"title": "Load CLIP"
}
},
"344:20": {
"class_type": "UNETLoader",
"inputs": {
"unet_name": "Wan2_2-Animate-14B_fp8_e4m3fn_scaled_KJ.safetensors",
"weight_dtype": "default"
},
"_meta": {
"title": "Load Diffusion Model"
}
},
"344:21": {
"class_type": "CLIPTextEncode",
"inputs": {
"clip": [
"344:2",
0
],
"text": "The post-apocalyptic elf warrior from the reference image dances alone in an empty night parking lot, taking over the dancer's exact moves. He bounces his shoulders, steps side to side in a relaxed groove, swings his arms low and wide, lifts a knee playfully and turns halfway on the spot before facing forward again. His tattered olive-green cloak flares and settles with each step, the alchemical vials on his belt sway and glint, and the cyan vents of the respirator around his neck glow softly. His blonde hair moves with the rhythm and his blue eyes stay on the camera. Warm amber streetlights light the cracked asphalt, parked white cars and autumn trees in the background, while distant red taillights glow through the dark. Smooth natural motion, consistent character, cinematic night photography."
},
"_meta": {
"title": "CLIP Text Encode (Positive Prompt)"
}
},
"344:232:15": {
"class_type": "CreateVideo",
"inputs": {
"bit_depth": "auto",
"codec": "none",
"color_space": "sRGB",
"fps": [
"314",
0
],
"images": [
"344:232:230",
0
]
},
"_meta": {
"title": "Create Video"
}
},
"344:232:230": {
"class_type": "ImageFromBatch",
"inputs": {
"batch_index": [
"344:232:62",
4
],
"image": [
"344:232:58",
0
],
"length": 4096
},
"_meta": {
"title": "Get Image from Batch"
}
},
"344:232:57": {
"class_type": "TrimVideoLatent",
"inputs": {
"samples": [
"344:232:63",
0
],
"trim_amount": [
"344:232:62",
3
]
},
"_meta": {
"title": "Trim Video Latent"
}
},
"344:232:58": {
"class_type": "VAEDecode",
"inputs": {
"samples": [
"344:232:57",
0
],
"vae": [
"344:3",
0
]
},
"_meta": {
"title": "VAE Decode"
}
},
"344:232:62": {
"class_type": "WanAnimateToVideo",
"inputs": {
"background_video": [
"344:332",
0
],
"batch_size": 1,
"character_mask": [
"344:325",
0
],
"clip_vision_output": [
"344:9",
0
],
"continue_motion_max_frames": 5,
"face_video": [
"344:334",
1
],
"height": [
"160",
0
],
"length": [
"301",
1
],
"negative": [
"344:1",
0
],
"pose_video": [
"344:335",
0
],
"positive": [
"344:21",
0
],
"reference_image": [
"344:342",
0
],
"vae": [
"344:3",
0
],
"video_frame_offset": 0,
"width": [
"159",
0
]
},
"_meta": {
"title": "WanAnimateToVideo"
}
},
"344:232:63": {
"class_type": "KSampler",
"inputs": {
"cfg": 1,
"denoise": 1,
"latent_image": [
"344:232:62",
2
],
"model": [
"344:60",
0
],
"negative": [
"344:232:62",
1
],
"positive": [
"344:232:62",
0
],
"sampler_name": "euler",
"scheduler": "simple",
"seed": [
"344:279",
0
],
"steps": 6
},
"_meta": {
"title": "KSampler"
}
},
"344:279": {
"class_type": "PrimitiveInt",
"inputs": {
"value": 281253459907758
},
"_meta": {
"title": "Seed"
}
},
"344:3": {
"class_type": "VAELoader",
"inputs": {
"vae_name": "wan_2.1_vae.safetensors"
},
"_meta": {
"title": "Load VAE"
}
},
"344:324": {
"class_type": "DownloadAndLoadSAM2Model",
"inputs": {
"device": "cuda",
"model": "sam2.1_hiera_base_plus.safetensors",
"precision": "fp16",
"segmentor": "video"
},
"_meta": {
"title": "(Down)Load SAM2Model"
}
},
"344:325": {
"class_type": "BlockifyMask",
"inputs": {
"block_size": 32,
"device": "cpu",
"masks": [
"344:327",
0
]
},
"_meta": {
"title": "Blockify Mask"
}
},
"344:326": {
"class_type": "Sam2Segmentation",
"inputs": {
"bboxes": [
"344:334",
3
],
"image": [
"344:338",
0
],
"individual_objects": False,
"keep_model_loaded": False,
"sam2_model": [
"344:324",
0
]
},
"_meta": {
"title": "Sam2Segmentation"
}
},
"344:327": {
"class_type": "GrowMaskWithBlur",
"inputs": {
"blur_radius": 0,
"decay_factor": 1,
"expand": 10,
"fill_holes": False,
"flip_input": False,
"incremental_expandrate": 0,
"lerp_alpha": 1,
"mask": [
"344:326",
0
],
"tapered_corners": True
},
"_meta": {
"title": "Grow Mask With Blur"
}
},
"344:328": {
"class_type": "OnnxDetectionModelLoader",
"inputs": {
"onnx_device": "CUDAExecutionProvider",
"vitpose_model": "vitpose-l-wholebody.onnx",
"yolo_model": "yolov10m.onnx"
},
"_meta": {
"title": "ONNX Detection Model Loader"
}
},
"344:329": {
"class_type": "SaveVideo",
"inputs": {
"filename_prefix": "video/ComfyUI",
"format": "auto",
"format.codec": "auto",
"video": [
"344:333",
0
]
},
"_meta": {
"title": "Save Video"
}
},
"344:330": {
"class_type": "SaveVideo",
"inputs": {
"filename_prefix": "video/ComfyUI",
"format": "auto",
"format.codec": "auto",
"video": [
"344:340",
0
]
},
"_meta": {
"title": "Save Video"
}
},
"344:331": {
"class_type": "SaveVideo",
"inputs": {
"filename_prefix": "video/ComfyUI",
"format": "auto",
"format.codec": "auto",
"video": [
"344:339",
0
]
},
"_meta": {
"title": "Save Video"
}
},
"344:332": {
"class_type": "DrawMaskOnImage",
"inputs": {
"color": "0, 0, 0",
"device": "cpu",
"image": [
"344:338",
0
],
"mask": [
"344:325",
0
]
},
"_meta": {
"title": "Draw Mask On Image"
}
},
"344:333": {
"class_type": "CreateVideo",
"inputs": {
"bit_depth": "auto",
"codec": "none",
"color_space": "sRGB",
"fps": [
"314",
0
],
"images": [
"344:334",
1
]
},
"_meta": {
"title": "Create Video"
}
},
"344:334": {
"class_type": "PoseAndFaceDetection",
"inputs": {
"face_padding": 0,
"height": [
"344:348",
1
],
"images": [
"344:338",
0
],
"model": [
"344:328",
0
],
"width": [
"344:348",
0
]
},
"_meta": {
"title": "Pose and Face Detection"
}
},
"344:335": {
"class_type": "DrawViTPose",
"inputs": {
"body_stick_width": -1,
"draw_head": True,
"hand_stick_width": -1,
"height": [
"344:348",
1
],
"pose_data": [
"344:334",
0
],
"retarget_padding": 16,
"width": [
"344:348",
0
]
},
"_meta": {
"title": "Draw ViT Pose"
}
},
"344:338": {
"class_type": "ImageScale",
"inputs": {
"crop": "center",
"height": [
"160",
0
],
"image": [
"301",
0
],
"upscale_method": "lanczos",
"width": [
"159",
0
]
},
"_meta": {
"title": "Resize Input Video"
}
},
"344:339": {
"class_type": "CreateVideo",
"inputs": {
"bit_depth": "auto",
"codec": "none",
"color_space": "sRGB",
"fps": [
"314",
0
],
"images": [
"344:332",
0
]
},
"_meta": {
"title": "Create Video"
}
},
"344:340": {
"class_type": "CreateVideo",
"inputs": {
"bit_depth": "auto",
"codec": "none",
"color_space": "sRGB",
"fps": [
"314",
0
],
"images": [
"344:335",
0
]
},
"_meta": {
"title": "Create Video"
}
},
"344:342": {
"class_type": "ImageScale",
"inputs": {
"crop": "center",
"height": [
"160",
0
],
"image": [
"10",
0
],
"upscale_method": "lanczos",
"width": [
"159",
0
]
},
"_meta": {
"title": "Resize Reference Image"
}
},
"344:348": {
"class_type": "GetImageSize",
"inputs": {
"image": [
"344:338",
0
]
},
"_meta": {
"title": "Get Image Size"
}
},
"344:4": {
"class_type": "CLIPVisionLoader",
"inputs": {
"clip_name": "clip_vision_h.safetensors"
},
"_meta": {
"title": "Load CLIP Vision"
}
},
"344:60": {
"class_type": "ModelSamplingSD3",
"inputs": {
"model": [
"344:99",
0
],
"shift": 8
},
"_meta": {
"title": "ModelSamplingSD3"
}
},
"344:9": {
"class_type": "CLIPVisionEncode",
"inputs": {
"clip_vision": [
"344:4",
0
],
"crop": "none",
"image": [
"344:342",
0
]
},
"_meta": {
"title": "CLIP Vision Encode"
}
},
"344:99": {
"class_type": "LoraLoaderModelOnly",
"inputs": {
"lora_name": "WanAnimate_relight_lora_fp16.safetensors",
"model": [
"344:18",
0
],
"strength_model": 1
},
"_meta": {
"title": "Load LoRA"
}
}
})
workflow.set_input("10", "image", client.assets.from_url("https://comfy.org/catalog-media/c15207cf-eea0-4265-afa1-1f184889d1bb/8837ea56-961e-45d2-9f12-9a1e6671d461"))
workflow.set_input("301", "video", client.assets.from_url("https://comfy.org/catalog-media/75887865-03c0-4c13-ac9d-3ba726ac9737/d7153c54-caab-422e-8ed5-dd3349ee5243"))
# 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("19"):
output.to_file(output.name)试试一个示例
关于此工作流
The 'Wan2.2 Animate: Automatic Character Replacement' workflow is designed to seamlessly replace a character in a video with a new character from an uploaded image. This is achieved using the Wan2.2 Animate model, which specializes in character animation and replacement. The workflow begins by loading your video and character image. It then processes these inputs through a series of nodes, including the ComfyUI-WanAnimatePreprocess for initial setup and the ComfyUI-segment-anything-2 for precise segmentation. This ensures that the character replacement is accurate and visually coherent.
Technically, the workflow leverages a combination of video processing nodes such as VHS_LoadVideo and VHS_VideoInfo to extract and manage video data. The b396d3e6-70cc-4a91-81db-6e0399a4edb6 node is crucial for handling complex data transformations required for character animation. By using these nodes in conjunction with the Wan2.2 Animate model, users can achieve high-quality character replacements that are both stable and realistic, especially when the reference image is a clear depiction of a human subject.
常见问答
Images of human subjects with clear faces and body outlines produce the most stable and convincing results.
While the workflow is optimized for human subjects, it may work with non-human characters, though results can vary.
The workflow supports standard video formats, but ensure your video is compatible with the VHS_LoadVideo node.
Processing time varies based on video length and complexity, but typically it completes within a few minutes for short clips.