Skin Enhancer + Upscaler
One click workflow to generate a character portrait, refine/add skin details, and upscale to 4k. All done in less than 60 seconds.
简介
The 'Skin Enhancer + Upscaler' workflow is designed to streamline the process of creating high-quality character portraits by integrating skin detail enhancement and image upscaling into a single, efficient workflow. Utilizing the Z-Image-Turbo and SDXL models, this workflow allows users to generate detailed portraits with refined skin textures and upscale the final image to 4K resolution in under a minute. Key nodes such as LoadImage and SaveImage facilitate the input and output processes, while custom nodes from comfyui-kjnodes and comfyui_essentials handle the intricate tasks of skin detail refinement and upscaling.
The workflow is particularly useful for artists and designers who need to quickly produce high-resolution images with enhanced facial features.
Technically, the workflow leverages nodes like fb45acca-28ee-4342-9487-e4e2369c9883 and eeeed90f-caa6-493b-8da1-03f72f13e685 to parse and enhance facial features based on user-defined prompts. Users can specify characteristics such as freckles, facial hair, or makeup preferences, which are then processed to refine the portrait's appearance. The ComfySwitchNode and ImageCompare nodes allow users to toggle between different image processing options, providing flexibility in the final output.
This workflow is ideal for those looking to enhance portrait images with minimal effort and maximum efficiency, making it a valuable tool for both professional and personal projects.
你需要提供
- 正在读取工作流
在 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({
"17": {
"class_type": "LoadImage",
"inputs": {
"image": "input_face-1.png"
},
"_meta": {
"title": "Load Image"
}
},
"282": {
"class_type": "SaveImage",
"inputs": {
"filename_prefix": "portrait-upscaled",
"images": [
"283:27",
0
]
},
"_meta": {
"title": "Save Image"
}
},
"286": {
"class_type": "SaveImage",
"inputs": {
"filename_prefix": "portrait-z-image-turbo",
"images": [
"285:8",
0
]
},
"_meta": {
"title": "Save Image"
}
},
"300": {
"class_type": "ComfySwitchNode",
"inputs": {
"on_false": [
"285:8",
0
],
"on_true": [
"17",
0
],
"switch": False
},
"_meta": {
"title": "Image Switch"
}
},
"302": {
"class_type": "ImageCompare",
"inputs": {
"compare_view": {
"__value__": [
"",
""
]
},
"image_a": [
"283:27",
0
],
"image_b": [
"300",
0
]
},
"_meta": {
"title": "Image Compare (Before/After)"
}
},
"283:21": {
"class_type": "GetImageSize",
"inputs": {
"image": [
"284:180",
0
]
},
"_meta": {
"title": "Get Image Size"
}
},
"283:22": {
"class_type": "SeedVR2LoadVAEModel",
"inputs": {
"cache_model": False,
"decode_tile_overlap": 128,
"decode_tile_size": 1024,
"decode_tiled": True,
"device": "cuda:0",
"encode_tile_overlap": 128,
"encode_tile_size": 1024,
"encode_tiled": True,
"model": "ema_vae_fp16.safetensors",
"offload_device": "none",
"tile_debug": "false"
},
"_meta": {
"title": "SeedVR2 (Down)Load VAE Model"
}
},
"283:25": {
"class_type": "SimpleMath+",
"inputs": {
"a": [
"283:43",
0
],
"b": [
"283:30",
0
],
"value": "a*b"
},
"_meta": {
"title": "Upscale to Shortest Edge (pixels)"
}
},
"283:27": {
"class_type": "SeedVR2VideoUpscaler",
"inputs": {
"batch_size": 1,
"color_correction": "lab",
"dit": [
"283:28",
0
],
"enable_debug": False,
"image": [
"284:180",
0
],
"input_noise_scale": 0,
"latent_noise_scale": 0,
"max_resolution": 0,
"offload_device": "cpu",
"prepend_frames": 0,
"resolution": [
"283:25",
0
],
"seed": 74825977,
"temporal_overlap": 0,
"uniform_batch_size": False,
"vae": [
"283:22",
0
]
},
"_meta": {
"title": "SeedVR2 Video Upscaler (v2.5.24)"
}
},
"283:28": {
"class_type": "SeedVR2LoadDiTModel",
"inputs": {
"attention_mode": "sdpa",
"blocks_to_swap": 0,
"cache_model": False,
"device": "cuda:0",
"model": "seedvr2_ema_7b_fp16.safetensors",
"offload_device": "cpu",
"swap_io_components": False
},
"_meta": {
"title": "SeedVR2 (Down)Load DiT Model"
}
},
"283:30": {
"class_type": "PrimitiveFloat",
"inputs": {
"value": 4
},
"_meta": {
"title": "Upscale Factor"
}
},
"283:40": {
"class_type": "ImpactCompare",
"inputs": {
"a": [
"283:21",
0
],
"b": [
"283:21",
1
],
"cmp": "a <= b"
},
"_meta": {
"title": "ImpactCompare"
}
},
"283:43": {
"class_type": "LayerUtility: If ",
"inputs": {
"if_condition": [
"283:40",
0
],
"when_FALSE": [
"283:21",
1
],
"when_TRUE": [
"283:21",
0
]
},
"_meta": {
"title": "IfElse"
}
},
"284:116": {
"class_type": "CheckpointLoaderSimple",
"inputs": {
"ckpt_name": "Juggernaut-XL_v9_RunDiffusionPhoto_v2.safetensors"
},
"_meta": {
"title": "Load Checkpoint"
}
},
"284:117": {
"class_type": "CLIPTextEncode",
"inputs": {
"clip": [
"284:116",
1
],
"text": "plastic, smooth, glossy, cartoon, anime, worst quality, low quality, illustration, 3d, 2d, painting, cartoons, sketch, anime"
},
"_meta": {
"title": "Negative Prompt"
}
},
"284:156": {
"class_type": "FaceParsingResultsParser(FaceParsing)",
"inputs": {
"background": False,
"cloth": False,
"ear_r": False,
"eye_g": False,
"hair": False,
"hat": False,
"l_brow": True,
"l_ear": False,
"l_eye": False,
"l_lip": True,
"mouth": False,
"neck": False,
"neck_l": False,
"nose": True,
"r_brow": True,
"r_ear": False,
"r_eye": False,
"result": [
"284:161",
1
],
"skin": True,
"u_lip": True
},
"_meta": {
"title": "FaceParsingResultsParser(FaceParsing)"
}
},
"284:157": {
"class_type": "FaceParsingModelLoader(FaceParsing)",
"inputs": {
"device": "cuda"
},
"_meta": {
"title": "FaceParsingModelLoader(FaceParsing)"
}
},
"284:159": {
"class_type": "BBoxDetectorLoader(FaceParsing)",
"inputs": {
"model_name": "bbox/face_yolov8m.pt"
},
"_meta": {
"title": "BBoxDetectorLoader(FaceParsing)"
}
},
"284:160": {
"class_type": "BBoxDetect(FaceParsing)",
"inputs": {
"bbox_detector": [
"284:159",
0
],
"by_ratio": False,
"dilation": 8,
"dilation_ratio": 0.2,
"image": [
"300",
0
],
"threshold": 0.3
},
"_meta": {
"title": "BBoxDetect(FaceParsing)"
}
},
"284:161": {
"class_type": "FaceParse(FaceParsing)",
"inputs": {
"image": [
"284:163",
0
],
"model": [
"284:157",
0
],
"processor": [
"284:165",
0
]
},
"_meta": {
"title": "FaceParse(FaceParsing)"
}
},
"284:162": {
"class_type": "BBoxListItemSelect(FaceParsing)",
"inputs": {
"bbox_list": [
"284:160",
0
],
"index": 0
},
"_meta": {
"title": "BBoxListItemSelect(FaceParsing)"
}
},
"284:163": {
"class_type": "ImageCropWithBBox(FaceParsing)",
"inputs": {
"bbox": [
"284:162",
0
],
"image": [
"300",
0
]
},
"_meta": {
"title": "ImageCropWithBBox(FaceParsing)"
}
},
"284:165": {
"class_type": "FaceParsingProcessorLoader(FaceParsing)",
"inputs": {},
"_meta": {
"title": "FaceParsingProcessorLoader(FaceParsing)"
}
},
"284:176": {
"class_type": "ImageCompositeMasked",
"inputs": {
"destination": [
"284:163",
0
],
"mask": [
"284:179",
0
],
"resize_source": False,
"source": [
"284:196",
0
],
"x": 0,
"y": 0
},
"_meta": {
"title": "Image Composite Masked"
}
},
"284:179": {
"class_type": "GrowMaskWithBlur",
"inputs": {
"blur_radius": 8,
"decay_factor": 1,
"expand": -4,
"fill_holes": False,
"flip_input": False,
"incremental_expandrate": 0,
"lerp_alpha": 1,
"mask": [
"284:156",
0
],
"tapered_corners": True
},
"_meta": {
"title": "Grow Mask With Blur"
}
},
"284:180": {
"class_type": "ImageInsertWithBBox(FaceParsing)",
"inputs": {
"bbox": [
"284:162",
0
],
"image": [
"284:176",
0
],
"image_src": [
"300",
0
]
},
"_meta": {
"title": "ImageInsertWithBBox(FaceParsing)"
}
},
"284:193": {
"class_type": "GetImageSize",
"inputs": {
"image": [
"284:163",
0
]
},
"_meta": {
"title": "Get Image Size"
}
},
"284:196": {
"class_type": "ImageResizeKJv2",
"inputs": {
"crop_position": "center",
"device": "cpu",
"divisible_by": 2,
"height": [
"284:193",
1
],
"image": [
"284:76",
0
],
"keep_proportion": "stretch",
"pad_color": "0, 0, 0",
"upscale_method": "lanczos",
"width": [
"284:193",
0
]
},
"_meta": {
"title": "Resize Image v2"
}
},
"284:227": {
"class_type": "LoraLoaderModelOnly",
"inputs": {
"lora_name": "sdxl-skin_realism_acne_skin_details_imperfections.safetensors",
"model": [
"284:116",
0
],
"strength_model": 0.6
},
"_meta": {
"title": "Load LoRA"
}
},
"284:72": {
"class_type": "UpscaleModelLoader",
"inputs": {
"model_name": "8xNMKDFaces160000G_v10.pt"
},
"_meta": {
"title": "Load Upscale Model"
}
},
"284:76": {
"class_type": "UltimateSDUpscale",
"inputs": {
"cfg": 4,
"denoise": 0.2,
"force_uniform_tiles": True,
"image": [
"284:163",
0
],
"mask_blur": 32,
"mode_type": "Linear",
"model": [
"284:227",
0
],
"negative": [
"284:117",
0
],
"positive": [
"284:78",
0
],
"sampler_name": "dpmpp_2m_sde",
"scheduler": "karras",
"seam_fix_denoise": 1,
"seam_fix_mask_blur": 8,
"seam_fix_mode": "None",
"seam_fix_padding": 16,
"seam_fix_width": 64,
"seed": 900811593556971,
"steps": 35,
"tile_height": 1024,
"tile_padding": 32,
"tile_width": 1024,
"tiled_decode": False,
"upscale_by": [
"284:98",
0
],
"upscale_model": [
"284:72",
0
],
"vae": [
"284:116",
2
]
},
"_meta": {
"title": "Ultimate SD Upscale"
}
},
"284:78": {
"class_type": "CLIPTextEncode",
"inputs": {
"clip": [
"284:116",
1
],
"text": "Close-up professional photograph of a woman, detailed face skin and visible skin pores, detailed natural skin and blemishes without-makeup, detailed skin texure, detailed lips, natural skin pores, subtle skin imperfections, visible skin pores, slightly cracked lips, skin discoloration, intricate detailed iris, perfect eyes, soft freckles"
},
"_meta": {
"title": "Positive Prompt"
}
},
"284:98": {
"class_type": "PrimitiveFloat",
"inputs": {
"value": 2
},
"_meta": {
"title": "Upscale By"
}
},
"285:11": {
"class_type": "ModelSamplingAuraFlow",
"inputs": {
"model": [
"285:287",
0
],
"sampling": "flow",
"shift": 3
},
"_meta": {
"title": "ModelSamplingAuraFlow"
}
},
"285:13": {
"class_type": "EmptySD3LatentImage",
"inputs": {
"batch_size": 1,
"height": 1152,
"width": 896
},
"_meta": {
"title": "EmptySD3LatentImage"
}
},
"285:287": {
"class_type": "LoraLoaderModelOnly",
"inputs": {
"lora_name": "zimage-grainscape_ultrareal.safetensors",
"model": [
"285:289",
0
],
"strength_model": 1
},
"_meta": {
"title": "Load LoRA"
}
},
"285:288": {
"class_type": "CLIPLoader",
"inputs": {
"clip_name": "qwen_3_4b.safetensors",
"device": "default",
"type": "lumina2"
},
"_meta": {
"title": "Load CLIP"
}
},
"285:289": {
"class_type": "UNETLoader",
"inputs": {
"unet_name": "z_image_turbo_bf16.safetensors",
"weight_dtype": "default"
},
"_meta": {
"title": "Load Diffusion Model"
}
},
"285:29": {
"class_type": "VAELoader",
"inputs": {
"vae_name": "ae.safetensors"
},
"_meta": {
"title": "Load VAE"
}
},
"285:290": {
"class_type": "CLIPTextEncode",
"inputs": {
"clip": [
"285:288",
0
],
"text": "A clean, high-key studio portrait features a central subject captured in a sharp headshot composition against a solid, vibrant cerulean blue backdrop. The lighting is soft and even, characteristic of a professional beauty dish or large softbox, which minimizes harsh shadows and creates a subtle, healthy glow across the skin. The focus is tack-sharp on the eyes, with a shallow depth of field that gently softens the texture of the hair as it recedes toward the shoulders.\n\nThe subject possesses a symmetrical, heart-shaped face with a neutral, poised expression and a direct gaze. Their hair is a bright, cool-toned platinum blonde, styled in a sleek, center-parted bob that falls just to the collarbone with slightly textured ends. Their complexion is smooth and radiant, complemented by a light application of makeup that emphasizes the natural arch of the well-defined, dark blonde eyebrows. The eyes are a warm hazel-brown, framed by dark, delicate lashes, while the lips are a soft, natural rose-pink with a slight satin finish.\n\nThe subject wears a crisp, minimalist white turtleneck sweater made of a fine-ribbed, lightweight knit fabric. The garment's clean lines and bright tone provide a high-contrast transition between the subject and the saturated blue background. The overall atmosphere is modern and clinical yet approachable, defined by the precision of the studio environment and the clarity of the facial features."
},
"_meta": {
"title": "CLIP Text Encode (Prompt)"
}
},
"285:3": {
"class_type": "KSampler",
"inputs": {
"cfg": 1,
"denoise": 1,
"latent_image": [
"285:13",
0
],
"model": [
"285:11",
0
],
"negative": [
"285:33",
0
],
"positive": [
"285:290",
0
],
"sampler_name": "res_multistep",
"scheduler": "simple",
"seed": 223832286985235,
"steps": 8
},
"_meta": {
"title": "KSampler"
}
},
"285:33": {
"class_type": "ConditioningZeroOut",
"inputs": {
"conditioning": [
"285:290",
0
]
},
"_meta": {
"title": "Conditioning Zero Out"
}
},
"285:8": {
"class_type": "VAEDecode",
"inputs": {
"samples": [
"285:3",
0
],
"vae": [
"285:29",
0
]
},
"_meta": {
"title": "VAE Decode"
}
}
})
# run() also passes api_key to the partner nodes in this workflow.
job = client.run(workflow, api_key=api_key)常见问答
Portraits with clear facial features are ideal, as the workflow is optimized for enhancing and upscaling facial details.
Yes, as long as the character has facial features that can be enhanced, the workflow can be applied effectively.
Higher denoise values result in more significant changes to the face, allowing for more dramatic enhancements.
Try adjusting the feature toggles and denoise settings, or refine your input prompt to better match your desired outcome.