//! AI Model Face & Hair Detail Fix Template //! //! This template performs detailed face and hair enhancement for AI model photos. //! It uses segmentation masks and local inpainting to improve facial features and hair quality. //! //! Features: //! - Automatic face and hair segmentation //! - Two-stage local inpainting (hair first, then face) //! - Configurable denoising strength //! - High-quality detail enhancement use std::collections::HashMap; use serde_json::json; use crate::types::{ WorkflowTemplateData, TemplateMetadata, ParameterSchema, ParameterType, ComfyUIWorkflow }; /// AI Model Face & Hair Detail Fix Template pub static AI_MODEL_FACE_HAIR_FIX_TEMPLATE: once_cell::sync::Lazy = once_cell::sync::Lazy::new(|| { create_ai_model_face_hair_fix_template() }); fn create_ai_model_face_hair_fix_template() -> WorkflowTemplateData { let metadata = TemplateMetadata { id: "ai-model-face-hair-fix".to_string(), name: "AI Model Face & Hair Detail Fix".to_string(), description: Some("Professional face and hair detail enhancement for AI model photos using segmentation and local inpainting".to_string()), category: Some("enhancement".to_string()), tags: Some(vec![ "face-enhancement".to_string(), "hair-enhancement".to_string(), "portrait".to_string(), "ai-model".to_string(), "detail-fix".to_string(), "inpainting".to_string(), ]), version: Some("1.0.0".to_string()), author: Some("ComfyUI SDK".to_string()), created_at: None, updated_at: None, }; let mut parameters = HashMap::new(); parameters.insert("input_image".to_string(), ParameterSchema { param_type: ParameterType::String, required: Some(true), default: Some(json!("20250806-190606.jpg")), description: Some("Input image filename to enhance".to_string()), r#enum: None, min: None, max: None, step: None, pattern: None, items: None, properties: None, accept: None, max_size: None, width: None, height: None, duration: None, node_mapping: None, }); parameters.insert("face_prompt".to_string(), ParameterSchema { param_type: ParameterType::String, required: Some(true), default: Some(json!("A girl, slim figure, oval face, beauty, Pink and greasy lips,")), description: Some("Positive prompt for face enhancement".to_string()), r#enum: None, min: None, max: None, step: None, pattern: None, items: None, properties: None, accept: None, max_size: None, width: None, height: None, duration: None, node_mapping: None, }); parameters.insert("face_denoise".to_string(), ParameterSchema { param_type: ParameterType::String, required: Some(true), default: Some(json!("0.30")), description: Some("Denoising strength for face enhancement".to_string()), r#enum: None, min: None, max: None, step: None, pattern: None, items: None, properties: None, accept: None, max_size: None, width: None, height: None, duration: None, node_mapping: None, }); let workflow = create_workflow_from_json(); WorkflowTemplateData { metadata, workflow, parameters, } } fn create_workflow_from_json() -> ComfyUIWorkflow { let workflow_json = r#" { "6": { "inputs": { "模糊强度": 3, "mask": ["53", 1] }, "class_type": "EG_ZZ_MHHT", "_meta": { "title": "2🐕遮罩边缘滑条快速模糊" } }, "8": { "inputs": { "ckpt_name": "juggernaut_reborn_sd1,5.safetensors" }, "class_type": "CheckpointLoaderSimple", "_meta": { "title": "Checkpoint加载器(简易)" } }, "9": { "inputs": { "text": "Smooth long hair,Hair details, quality hair,Smooth hair", "clip": ["8", 1] }, "class_type": "CLIPTextEncode", "_meta": { "title": "CLIP文本编码" } }, "10": { "inputs": { "text": "Frizzy hair, dry hair, split ends,bad quality, poor quality, doll, disfigured, jpg, toy, bad anatomy, missing limbs, missing fingers, 3d, cgi", "clip": ["8", 1] }, "class_type": "CLIPTextEncode", "_meta": { "title": "CLIP文本编码" } }, "13": { "inputs": { "text": ["59", 0], "clip": ["8", 1] }, "class_type": "CLIPTextEncode", "_meta": { "title": "CLIP文本编码" } }, "14": { "inputs": { "text": "(NSFW:1.2),(worst quality:1.2),(low quality:1.2),(normal quality:1.2),low resolution,watermark,", "clip": ["8", 1] }, "class_type": "CLIPTextEncode", "_meta": { "title": "CLIP文本编码" } }, "22": { "inputs": { "detail_method": "VITMatte(local)", "detail_erode": 44, "detail_dilate": 6, "black_point": 0.030000000000000006, "white_point": 0.99, "process_detail": true, "device": "cuda", "max_megapixels": 2, "image": ["30", 0], "segformer_pipeline": ["28", 0] }, "class_type": "LayerMask: SegformerUltraV2", "_meta": { "title": "LayerMask: Segformer Ultra V2" } }, "25": { "inputs": { "seed": 646617836820462, "steps": 30, "cfg": 4.5200000000000005, "sampler_name": "dpmpp_2s_ancestral", "scheduler": "karras", "denoise": 0.4, "重绘模式": "原图", "遮罩延展": 10, "仅局部重绘": true, "局部重绘大小": 768, "重绘区域扩展": 50, "遮罩羽化": 5, "TEXT": "2🐕出品,必出精品", "model": ["8", 0], "image": ["30", 0], "vae": ["8", 2], "mask": ["47", 0], "positive": ["9", 0], "negative": ["10", 0] }, "class_type": "EG_CYQ_JB", "_meta": { "title": "2🐕局部重绘采样器" } }, "26": { "inputs": { "seed": 969968724502727, "steps": 30, "cfg": 4.5200000000000005, "sampler_name": "dpmpp_2s_ancestral", "scheduler": "karras", "denoise": ["71", 0], "重绘模式": "原图", "遮罩延展": 10, "仅局部重绘": true, "局部重绘大小": 768, "重绘区域扩展": 50, "遮罩羽化": 5, "TEXT": "2🐕出品,必出精品", "model": ["8", 0], "image": ["25", 1], "vae": ["8", 2], "mask": ["6", 0], "positive": ["13", 0], "negative": ["14", 0] }, "class_type": "EG_CYQ_JB", "_meta": { "title": "2🐕局部重绘采样器" } }, "28": { "inputs": { "model": "segformer_b3_clothes", "face": false, "hair": true, "hat": false, "sunglass": false, "left_arm": false, "right_arm": false, "left_leg": false, "right_leg": false, "left_shoe": false, "right_shoe": false, "upper_clothes": false, "skirt": false, "pants": false, "dress": false, "belt": false, "bag": false, "scarf": false }, "class_type": "LayerMask: SegformerClothesPipelineLoader", "_meta": { "title": "LayerMask: Segformer Clothes Pipeline" } }, "30": { "inputs": { "image": "{{input_image}}" }, "class_type": "LoadImage", "_meta": { "title": "加载图像" } }, "44": { "inputs": { "masks": ["22", 1] }, "class_type": "Mask Fill Holes", "_meta": { "title": "Mask Fill Holes" } }, "47": { "inputs": { "expand": 5, "incremental_expandrate": 5, "tapered_corners": true, "flip_input": false, "blur_radius": 9.4, "lerp_alpha": 0.9900000000000002, "decay_factor": 1, "fill_holes": false, "mask": ["44", 0] }, "class_type": "GrowMaskWithBlur", "_meta": { "title": "Grow Mask With Blur" } }, "52": { "inputs": { "model": "segformer_b3_clothes", "face": true, "hair": false, "hat": false, "sunglass": true, "left_arm": false, "right_arm": false, "left_leg": false, "right_leg": false, "left_shoe": false, "right_shoe": false, "upper_clothes": false, "skirt": false, "pants": false, "dress": false, "belt": false, "bag": false, "scarf": false }, "class_type": "LayerMask: SegformerClothesPipelineLoader", "_meta": { "title": "LayerMask: Segformer Clothes Pipeline" } }, "53": { "inputs": { "detail_method": "VITMatte(local)", "detail_erode": 6, "detail_dilate": 4, "black_point": 0.01, "white_point": 0.99, "process_detail": false, "device": "cuda", "max_megapixels": 2, "image": ["30", 0], "segformer_pipeline": ["52", 0] }, "class_type": "LayerMask: SegformerUltraV2", "_meta": { "title": "LayerMask: Segformer Ultra V2" } }, "58": { "inputs": { "filename_prefix": "ComfyUI", "images": ["26", 1] }, "class_type": "SaveImage", "_meta": { "title": "保存图像" } }, "59": { "inputs": { "String": "{{face_prompt}}" }, "class_type": "String", "_meta": { "title": "String" } }, "71": { "inputs": { "Number": "{{face_denoise}}" }, "class_type": "Float", "_meta": { "title": "Float" } } } "#; // 解析 JSON 字符串为 ComfyUIWorkflow serde_json::from_str(workflow_json) .expect("Failed to parse workflow JSON") }