Nodes/PhotoRoom Nodes by Discopixel/Transform Template onto Face Mask
ComfyUI Node

Transform Template onto Face Mask

The face-accessory transformer the pack left behind

By discopixel-studio·Created 3 years ago·Updated 2 years ago· 13
Transform Template onto Face Mask
  • face_mask
  • template_image
  • template_mask
  • IMAGE
  • MASK

TransformTemplateOntoFaceMask takes a template - glasses, a hat, a logo, a bandana - and a mask of a face, then warps the template to sit on that face. It scales it, rotates it, and slides it so the template's long axis lines up with the face's. It's pure geometry, no diffusion involved: think of it as an auto-aligned affine transform for compositing accessories onto portraits, the kind of thing you'd otherwise spend ten minutes nudging with a manual transform node.

The first thing you need to know

Here's the awkward part, and it's why this page exists. As of the current source on main, this node isn't registered. The class is there in comfyui_discopixel_nodes.py, but the @register_node decorator above it is commented out - same as the pack's OpenPoseToClothesMask. Install the current version of the pack and the only thing in your add-node menu under Discopixel is "Remove Background with Photoroom." This node shipped in older versions of the pack - the repo still carries the archived README and example workflow that used it - and the page survives because a bunch of workflows out there were built against those earlier releases. So if you landed here because a downloaded workflow is demanding this node, that workflow predates the current pack.

How it works

The math is the interesting part. Given your face mask (a white shape on black), the node finds the centroid of all the white pixels, then fits an ellipse to the blob: it computes the pixel covariance matrix and takes its eigenvectors, which give you the major and minor axis lengths and the face's rotation angle. From that it builds a single 2×3 affine matrix - translate to origin, scale to the face's ellipse, rotate to the major axis, translate back to the centroid - and applies it to the template with cv2.warpAffine. The author's own contract in the docstring says it plainly: it "assumes there is only one shape, and that the shape is comprised of white pixels over a black background."

Inputs and outputs

All three inputs are required, and there are no knobs to fiddle:

  • face_mask (MASK) - the region the template should land on. This drives everything, so the cleaner the blob, the better the fit.
  • template_image (IMAGE) - the accessory you're placing.
  • template_mask (MASK) - which pixels of the template count. Worth doing properly: give it a tight mask of just the object (the frames of the glasses, say), not a bounding box around the whole picture. The node inverts the mask internally so empty space around the template stays transparent.

Outputs are IMAGE and MASK: the warped template on a canvas sized to the face mask, plus a matching alpha mask. Wire both into a composite or blend node layered over the face and you're done.

Where it falls apart

The fit-an-ellipse approach is only as good as the assumption. It works well for near-frontal, oval faces. Side profiles, heavy angles, or any mask that isn't roughly elliptical will misalign, and nothing in the node will tell you - it just places the template where the math thinks the face is. There's also a fixed scale reference baked into the code (the ellipse is normalized against hardcoded 72×100 template proportions), so a template with a very different aspect ratio from what the author assumed will come out visibly distorted. And remember: one shape, white on black, or the centroid lands somewhere meaningless.

Installing it

The pack itself installs the normal way:

# ComfyUI Manager: search "PhotoRoom Nodes by Discopixel", or:
cd ComfyUI/custom_nodes
git clone https://github.com/discopixel-studio/comfyui-discopixel
pip3 install -r requirements.txt

Only dependency is opencv-python. But given the registration situation above, "install and go" doesn't apply to this particular node - if you need it, you're either on an old workflow that already has it, or you'd be re-enabling the class yourself. It's a genuinely neat little geometry node for face-accessory compositing; it just isn't the pack's present anymore.

CategoryDiscopixel

Inputs (3)

NameTypeDefaultDescription
face_maskMASK
template_imageIMAGE
template_maskMASK

Outputs (2)

NameTypeDescription
IMAGEIMAGE
MASKMASK