ComfyUI Node

Face-Shaper

Draw the face you want, and let Qwen-Image-Edit make it real

By EricRorich·Created 8 months ago·Updated 6 months ago· 5
Face-Shaper
  • settings_list
  • IMAGE
  • LIST
canvas_width1024
canvas_height1024
transparent_backgroundfalse
line_thickness2.0
gender
fov_mm80
camera_distance1.00
camera_pos_x0.00
camera_pos_y0.00
head_size_x1.00
head_size_y1.00
jaw_size_x1.00
fore_head_size_x1.00
eye_left_size_x1.00
eye_left_size_y1.00
eye_left_pos_x0.00
eye_left_pos_y0.00
eye_left_rotation0.0
eye_right_size_x1.00
eye_right_size_y1.00
eye_right_pos_x0.00
eye_right_pos_y0.00
eye_right_rotation0.0
iris_left_size1.00
iris_left_pos_x0.000
iris_left_pos_y0.000
iris_right_size1.00
iris_right_pos_x0.000
iris_right_pos_y0.000
eyebrow_left_size_x1.00
eyebrow_left_size_y1.00
eyebrow_left_pos_x0.00
eyebrow_left_pos_y0.00
eyebrow_left_rotation0.0
eyebrow_right_size_x1.00
eyebrow_right_size_y1.00
eyebrow_right_pos_x0.00
eyebrow_right_pos_y0.00
eyebrow_right_rotation0.0
nose_pos_y0.00
nose_size_x1.00
nose_size_y1.00
nose_tip_pos_y0.000
lips_pos_y0.00
lip_size_x1.00
lip_upper_size_y1.00
lip_lower_size_y1.00

The name is a bit of a lie, in the best way. Face-Shaper never touches your photo - it draws a face. Black line art on a white (or transparent) canvas: head outline, jaw, forehead, eyes, irises, brows, nose, lips. What you get out is a structural guide image, meant to be dropped into an image-editing workflow as a conditioning reference for Qwen-Image-Edit-2511. You shape the line drawing, and the edit model shapes the actual face to match.

That's the whole reason this node exists. Prose prompts are terrible at precise geometry - "narrower jaw, wider-set eyes, fuller upper lip" is a coin flip even on a good day. A drawn mask isn't. It's the same trick behind the "crop-and-stitch" conditioning people bolt onto Qwen-Image-Edit because the model re-emits the whole frame and drifts if you leave structure to chance. Here you get a parametric sketch instead of hand-drawing it in an image editor. One README warning up front: it currently works only with Qwen-Image-Edit-2511, so don't expect Flux Kontext or the 2509 revision to obey it the same way.

How it works

Every feature starts life as coordinates parsed from the pack's bundled Face_Mask_female.svg, normalized to a 0–1 space. Each group (eyes, brows, nose, lips, head) gets its own scale/translate/rotate applied before pixel conversion, so scaling an eye doesn't stretch its neighbor. That relative space is then projected onto your canvas with x = (rx - 0.5) * canvas_width * camera_distance + canvas_width / 2 - and, nicely, there's a virtual camera here. camera_distance is global zoom, camera_pos_x/y pan, and fov_mm (neutral at 80) applies actual radial lens distortion: barrel below 80, pincushion above. It's a small touch, but edit models respond to lens geometry, so a little distortion can sell the shot. Drawing is plain Pillow polylines and circles, returned as a float32 0–1 tensor.

The reset button in the footer and the settings_list input are one feature split in two: the node's second output is a LIST of every current parameter, and feeding that list back into settings_list restores it - that's your preset system, with backward compatibility for older saved lists built in.

The inputs that matter

You'll actually touch a fraction of the ~45 widgets. Start with these:

  • canvas_width / canvas_height - 1024 default; output size, not the model's.
  • transparent_background - off gives RGB white, on gives RGBA with a transparent canvas. Only flip it on if your downstream node can handle an alpha channel.
  • line_thickness - 2.0 default; the stroke width. Anything below ~1 rounds to a 1px line.
  • gender - female or male, but read the fine print: male currently uses the female coordinate data (the README says so). Don't expect a distinct male anatomy yet.

Then the geometry sliders: head_size_x/y, jaw_size_x, fore_head_size_x for the skull shape; eye_left_* / eye_right_* (including independent eye_left_rotation / eye_right_rotation, great for expression); iris_*; eyebrow_*; nose_pos_y / nose_size_* / nose_tip_pos_y; and lip_size_x, lip_upper_size_y, lip_lower_size_y. Positions are fractions of the canvas (positive x = right, positive y = down), sizes are multipliers around 1.0.

Wiring it up

Outputs are IMAGE and LIST. The bundled Workflow_Face_Shaper_Qwen_Edit_2511.json shows the intended path: your source portrait, overlaid with the face-shaper image, fed into a Qwen Image Edit sampler node alongside the photo as a conditioning reference. The mask image and settings_list also make it easy to batch-compare face shapes - render one, dial the list, render the next.

Install

cd ComfyUI/custom_nodes/
git clone https://github.com/EricRorich/ComfyUI-face-shaper.git

Then restart ComfyUI - it lands under the face category as Face Shaper. ComfyUI Manager can also find it by searching "ComfyUI-face-shaper". There are no extra pip dependencies (torch, numpy, Pillow all ship with ComfyUI), and the node downloads no model files itself. The catch is upstream: to actually use it you'll need the Qwen-Image-Edit-2511 weights plus its VAE (qwen_image_vae.safetensors) and a Qwen Edit sampler pack - the workflow file names QwenImageIntegratedKSampler, which comes from a separate integration pack.

Gotchas

  • It's young. This is a WIP pack from early 2026 with essentially zero community track record yet. If something misbehaves, the GitHub issues page is your only real knowledge base.
  • The white/RGBA background is part of the guide. If it fights your composition, overlay it with transparency rather than blending it flat - the CR Overlay node in the bundled workflow is doing exactly that.
  • Don't fight fov_mm until you've seen what 80 looks like. Default first, fiddle later.
Categoryface

Inputs (48)

NameTypeDefaultDescription
canvas_widthINT1024256–2048
canvas_heightINT1024256–2048
transparent_backgroundBOOLEANfalse
line_thicknessFLOAT2.00.5–10
genderCOMBO2 options: female, male
fov_mmFLOAT8016–200
camera_distanceFLOAT1.000.5–2
camera_pos_xFLOAT0.00-0.5–0.5
camera_pos_yFLOAT0.00-0.5–0.5
head_size_xFLOAT1.000.5–2
head_size_yFLOAT1.000.5–2
jaw_size_xFLOAT1.000.5–2
fore_head_size_xFLOAT1.000.5–2
eye_left_size_xFLOAT1.000.5–3
eye_left_size_yFLOAT1.000.5–3
eye_left_pos_xFLOAT0.00-0.5–0.5
eye_left_pos_yFLOAT0.00-0.5–0.5
eye_left_rotationFLOAT0.0-45–45
eye_right_size_xFLOAT1.000.5–3
eye_right_size_yFLOAT1.000.5–3
eye_right_pos_xFLOAT0.00-0.5–0.5
eye_right_pos_yFLOAT0.00-0.5–0.5
eye_right_rotationFLOAT0.0-45–45
iris_left_sizeFLOAT1.000.5–3
iris_left_pos_xFLOAT0.000-0.25–0.25
iris_left_pos_yFLOAT0.000-0.25–0.25
iris_right_sizeFLOAT1.000.5–3
iris_right_pos_xFLOAT0.000-0.25–0.25
iris_right_pos_yFLOAT0.000-0.25–0.25
eyebrow_left_size_xFLOAT1.000.5–2
eyebrow_left_size_yFLOAT1.000.5–2
eyebrow_left_pos_xFLOAT0.00-0.5–0.5
eyebrow_left_pos_yFLOAT0.00-0.5–0.5
eyebrow_left_rotationFLOAT0.0-45–45
eyebrow_right_size_xFLOAT1.000.5–2
eyebrow_right_size_yFLOAT1.000.5–2
eyebrow_right_pos_xFLOAT0.00-0.5–0.5
eyebrow_right_pos_yFLOAT0.00-0.5–0.5
eyebrow_right_rotationFLOAT0.0-45–45
nose_pos_yFLOAT0.00-1–1
nose_size_xFLOAT1.000–2
nose_size_yFLOAT1.000–2
nose_tip_pos_yFLOAT0.000-0.2–0.2
lips_pos_yFLOAT0.00-0.5–0.5
lip_size_xFLOAT1.000–2
lip_upper_size_yFLOAT1.000.5–2
lip_lower_size_yFLOAT1.000.5–2
settings_listoptLIST

Outputs (2)

NameTypeDescription
IMAGEIMAGE
LISTLIST