MediaPipe Eyes Mesh
Want a clean mask of just the eyes? This cloud MediaPipe node hands you one
- image
- image
The hardest part of fixing someone's eyes in a generated image isn't the fixing - it's telling the model where the eyes are. This node does that for you in one shot: feed it a face image and you get back a soft, ready-to-use mask of just the eye region, computed by MediaPipe on Runware's cloud. It's the classic "make a mask, then inpaint through it" workflow, minus the hours of lassoing.
What it actually does
This is an imageMasking node in the Runware pack, which means the heavy lifting happens server-side. Your image gets uploaded, MediaPipe's face-mesh landmarks find the eyes, and the node returns the mask as an image output (an IMAGE tensor, not the MASK type). It's a mask of the eye areas, with the face itself left untouched.
The output is the mask, not an edited photo. So the real workflow is: this node → mask → an inpainting model → done. In vanilla ComfyUI you'll usually run the mask through the core ImageToMask node (or feed it to a Runware inpaint node that takes IMAGE masks directly) and then use it to pin the inpaint to the eyes. The unmasked pixels stay bit-identical, which is exactly what masked inpainting still owns over whole-image edit models.
The settings that matter
Four of them, and they're all straightforward:
settings.confidence(default 0.5) - how sure MediaPipe has to be before a detection counts. If it keeps missing eyes, drop it; if it's grabbing random blobs, raise it.settings.maskBlur(default 5) - feathering on the mask edges. 5 is a good start for eye work; go lower if you want hard edges for a relight, higher if you're getting seams.settings.maskPadding(default 10) - pixels to extend the mask beyond the detected eyes. Positive grows it (safer for inpaint), negative shrinks it.settings.maxDetections(default 6) - how many faces to process when there's a crowd.
The ttl / ttl_value and outputFormat (JPG/PNG/WEBP) widgets are shared pack plumbing - you can ignore them. Everything runs in the cloud, so there's no local model to download.
Install
The whole pack installs at once, since these are all nodes in Runware/ComfyUI-Runware:
cd ComfyUI/custom_nodes
git clone https://github.com/Runware/ComfyUI-Runware
pip install -r ComfyUI-Runware/requirements.txt
Restart ComfyUI. Easier still: open ComfyUI Manager, search "Runware", install, restart. The dependencies are light (runware-sdk, pillow, soundfile) - no CUDA, no gigabytes of model files. You do need an API key: grab one from the Runware dashboard, then paste it in ComfyUI Settings → Runware API key, set the RUNWARE_API_KEY env var, or run runware auth login once.
Gotchas
Every run is a paid cloud inference, and the node's title bar shows the cost plus a NSFW flag after each run - worth glancing at if you're batch-running a folder of faces. And remember the output is a grayscale mask image; if a node downstream wants a MASK socket, convert first. That trips people up more than anything else.
Inputs (8)
| Name | Type | Default | Description |
|---|---|---|---|
| image | IMAGE | — | |
| settings.confidenceopt | FLOAT | 0.500–1 | Confidence threshold for detections. Only detections above this score are included. |
| settings.maskBluropt | INT | 50–100 | Blur radius for mask edges, creating smooth transitions. |
| settings.maskPaddingopt | INT | 100–200 | Pixel amount to extend (positive) or shrink (negative) the mask area. |
| settings.maxDetectionsopt | INT | 61–20 | Maximum number of detections. Prioritizes highest confidence scores if exceeded. |
| ttlopt | BOOLEAN | false | Enable to set ttl. Off uses the model's default. |
| ttl_valueopt | INT | 60 | Time-to-live (TTL) in seconds for generated content. Only applies when `outputType` is `URL`. |
| outputFormatopt | COMBO | JPG | File format for the generated image. |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| image | IMAGE | — |