Nodes/ComfyUI_Gemini/✏️ Gemini Draw Diff Mask
ComfyUI Node

✏️ Gemini Draw Diff Mask

Scribble on a photo, get an inpaint mask back

By aarnoatchi·Created 2 months ago·Updated 2 months ago· 0
✏️ Gemini Draw Diff Mask
  • clean_image
  • drawn_image
  • mask
  • strokes
  • preview
threshold0.10
fill_regiontrue
close_gaps3
min_area16
grow0
feather0

Gemini Draw Diff Mask turns a scribble into a mask. You give it a clean image and the same image with a shape drawn on it - a red circle, a highlight, an arrow, whatever color - and it compares the two, finds the drawn pixels, and returns them as a proper ComfyUI MASK. Draw a closed outline and it'll even fill the interior for you, which is a surprisingly elegant way to mark an inpaint region: paint a circle around the thing you want regenerated, and the mask is ready.

It's a local utility - no API, no key, runs instantly. The name says Gemini, but nothing about it touches Google; it's pure pixel diffing.

How it works

The mechanism is refreshingly honest: it subtracts the two images and thresholds the difference. A pixel counts as "drawn" when it's more than threshold away from the clean version (default 0.1 - lower is more sensitive, and the author's own note is to raise it if JPEG noise leaks through). Then it cleans the result up in a few passes.

  • fill_region (default on) - fills the area enclosed by the drawing, turning an outline into a solid region. Off gives you just the strokes.
  • close_gaps (default 3px) - bridges small breaks in a hand-drawn outline before filling, so an imperfect circle still fills as a circle. Only applies when fill_region is on.
  • min_area (default 16) - drops diff specks smaller than that many pixels: compression noise, stray dots.
  • grow - expands the final mask outward by N pixels, e.g. to swallow the drawn line itself once you've filled.
  • feather - softens the mask edge by N pixels with a Gaussian.

If you've ever hand-painted inpaint masks in an image editor and cursed the antialiased edges, this is the workflow-friendly version: draw, fill, grow a hair, feather, done.

The inputs that matter

The two required inputs are the whole deal: clean_image (the original, un-drawn photo) and drawn_image (the same picture with the mark on it). The one caveat buried in the tooltips is that they must be the same picture - the node is diffing pixels, so if you draw on a differently-resized or re-exported copy, the whole image diffs as "drawn." Same file, same dimensions.

Outputs are mask (the filled final mask - the one you wire into inpaint), strokes (just the raw strokes before filling, in case you want them separately), and preview (an IMAGE so you can eyeball what it detected without a separate preview node).

Install

Pack-wide install: ComfyUI Manager search "ComfyUI_Gemini", or clone and pip:

cd ComfyUI/custom_nodes
git clone https://github.com/aarnoatchi/ComfyUI_Gemini
pip install -r ComfyUI_Gemini/requirements.txt

It's one of the rare nodes in this pack that works even if scipy is missing - it has a pure-torch fallback for the fill/closing steps, just slower and cruder. Still, install the requirements as-is and you'll get the scipy path. Restart ComfyUI and it's under AI/Image Analysis/Google.

Common failure: your "drawn" region comes out huge because JPEG artifacts or a subtle brightness shift across the whole frame crossed the threshold - that's the threshold too low, so raise it and drop min_area cleanup in. And if you draw in a program that adds a white border or letterboxing, trim it off first - the node will happily interpret a changed border as a giant drawn stroke.

CategoryAI/Image Analysis/Google

Inputs (8)

NameTypeDefaultDescription
clean_imageIMAGEThe original, un-drawn image.
drawn_imageIMAGEThe same image with a shape/mark drawn on it. Must be the same picture.
thresholdoptFLOAT0.100–1How different a pixel must be to count as 'drawn'. Lower = more sensitive. Raise it if JPEG noise leaks through.
fill_regionoptBOOLEANtrueON: fill the area enclosed by the drawing (outline → solid). OFF: keep just the strokes.
close_gapsoptINT30–128Bridge small breaks in the outline (in px) before filling, so an imperfect circle still fills. Only used when fill_region is ON.
min_areaoptINT160–1000000Remove diff specks smaller than this many pixels (compression noise, stray dots).
growoptINT00–256Expand the final mask outward by N px (e.g. to cover the drawn line itself when filling).
featheroptINT00–256Soften the final mask edge by N px (Gaussian).

Outputs (3)

NameTypeDescription
maskMASK
strokesMASK
previewIMAGE