Nodes/ComfyUI-MoonNodes/πŸŒ— Moon Mask Maker GUI
ComfyUI Node

πŸŒ— Moon Mask Maker GUI

Paint your regional masks, not your coordinates

By m0rtus59Β·Created 3 months agoΒ·Updated 9 days agoΒ· 8
πŸŒ— Moon Mask Maker GUI
    • masks
    • composite
    • width
    • height
    β—„mask_names[]β–Ί

    If the Simple mask maker is the "type a number grid" approach to regional prompting, MoonMaskMakerGUI is the "actually draw the shapes" approach. It opens a real painting canvas right inside the node, where you draw your regions by hand, stack them in layers, and get a color-coded preview on the node itself. It's the version you reach for when your layout is a person standing in front of a background - not a rectangle you can type.

    Opening and using the painter

    Right-click the node and choose "Open Painting GUI...". A dialog pops up with a canvas and a layer system.

    • Left click + drag draws the current mask.
    • Right click + drag erases it.
    • Arrow up / down switches layers; pressing down on the last layer creates a new one.

    Non-active layers render semi-transparent, so you can line your new region up against the ones already painted. That's the feature that makes multi-region work tolerable - you can see exactly where the character ends before you paint the background layer.

    There's an Allow Overlap toggle, and it matters. When it's off, saving the layout subtracts each new layer from the layers beneath it, while keeping your original shapes intact and editable in the GUI. That's the "non-destructive exclusion" the README advertises: you get clean, non-overlapping masks for the sampler without destroying your source artwork. When it's on, layers can bleed into each other - which regional-prompting implementations generally handle badly, so keep it off unless you know you want overlap.

    How the masks get out

    Painting happens in the browser, but the masks have to reach the Python side. The node posts the layers to a custom server route (/moon/save_masks) that writes each layer to ComfyUI's input directory as a moon_mask_<node_id>_<index>_<timestamp>.png file, then the node loads them back as mask tensors and aligns them all to a common size.

    You don't see any of that - what you see is one input and one output:

    • mask_names (STRING, default "[]") - a JSON string the GUI fills with the saved mask filenames and the embedded preview. You normally never touch this by hand; it's the node's memory.
    • MASK output (a list) - one mask per layer, wired straight into the regional patcher or multi-pass sampler's mask_list.

    Install and the security note

    Standard pack install:

    cd ComfyUI/custom_nodes
    git clone https://github.com/m0rtus59/ComfyUI-MoonNodes.git
    cd ComfyUI-MoonNodes && pip install -r requirements.txt
    

    Restart ComfyUI and refresh the browser tab - the painter is JavaScript, so a stale frontend means a missing right-click menu. This is also the one MoonNodes node that opens a custom web endpoint, and since the ComfyUI ecosystem's worst moments have come from custom nodes shipping malicious routes (see the ComfyUI_LLMVISION incident), it's worth knowing the author bothered to document the sandboxing here: the node ID is sanitized against path traversal, images are re-encoded by Pillow rather than trusted from the browser, and everything lands in ComfyUI's designated input directory.

    Where it bites

    Because masks are files, they're tied to the node's ID. Delete the node and the files go with its identity; recreating it orphans the old PNGs. The node cleans up its own old masks on each save, so leftover files aren't a big deal - but if you want to keep a layout, save the workflow, because that JSON (with embedded preview) is the durable copy.

    CategoryMoonNodes

    Inputs (1)

    NameTypeDefaultDescription
    mask_namesSTRING[]β€”

    Outputs (4)

    NameTypeDescription
    masksMASKβ€”
    compositeIMAGEβ€”
    widthINTβ€”
    heightINTβ€”