Nodes/Nodes for use with real-time applications of ComfyUI/Quick Shape Mask πŸ•’πŸ…‘πŸ…£πŸ…
ComfyUI Node

Quick Shape Mask πŸ•’πŸ…‘πŸ…£πŸ…

A Circle or Square Mask, Fast Enough to Generate Every Frame

By ryanontheinsideΒ·Created 2 years agoΒ·Updated about a year agoΒ· 82
Quick Shape Mask πŸ•’πŸ…‘πŸ…£πŸ…
    • MASK
    β—„shapecircleβ–Ί
    β—„width64β–Ί
    β—„height64β–Ί
    β—„x256β–Ί
    β—„y256β–Ί
    β—„canvas_width512β–Ί
    β—„canvas_height512β–Ί
    β—„batch_size1β–Ί

    A mask of a circle or square shouldn't need a 200ms Python journey, and in most packs it does anyway. Quick Shape Mask is the version built for the one constraint this pack cares about: it has to run every frame in a real-time loop. So instead of going through PIL's full drawing stack, it builds the mask with straight NumPy array operations - and it's genuinely fast, which is the whole point of its existence.

    You get two shapes: circle and square. width and height define the shape's size in pixels, x and y place its center on a canvas of canvas_width Γ— canvas_height, and batch_size duplicates the mask N times (so you can feed a batch without re-running the node). For the circle it computes a per-pixel distance check with np.ogrid - an axis-aligned ellipse, really, so width/height different from each other gives you an oval. For the square it's a simple slice fill. Either way you get a hard-edged MASK in the 0–1 range, one pixel wide borders and all.

    The real-time angle makes it more useful than it first looks. Because you can drive x, y, width, and height from the pack's control nodes - a Float Control sweeping the radius, motion mapping the position - you can animate a mask live without any image processing. It's also the fastest way to build an ROI: this pack's ROINode takes a mask to define a region of interest, and Quick Shape Mask hands you a clean one to feed it.

    The inputs that matter

    • shape - circle or square.
    • width / height - the shape's size in pixels (they're the ellipse axes for circles).
    • x / y - center position on the canvas, in pixels from the top-left.
    • canvas_width / canvas_height - output canvas size. These define the mask resolution.
    • batch_size - copies of the same mask; default 1.

    Output: one MASK (BHW format, so one channel).

    Install & gotchas

    In ryanontheinside/ComfyUI_RealtimeNodes - ComfyUI Manager (search "Control Nodes") or:

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

    Two things to keep straight. The shape's x/y is its center, not its corner - a 64px circle at 0,0 will be partially off-canvas, and the node just clips it. And the defaults are quirky: the shape defaults to 64Γ—64 but the canvas to 512Γ—512, centered at 256,256 - so the default is a small circle mid-canvas, which is usually not what you want on first drop. Set the size and position and you're good. Also remember the edges are razor hard; if your inpaint or composite wants softness, a blur after this node is your friend. For the cost of a couple of numpy ops per frame, it's the cheap way to put a shape anywhere, anytime.

    Categorymask

    Inputs (8)

    NameTypeDefaultDescription
    shapeCOMBOcircleThe shape of the mask to generate
    widthINT641–4096Width of the shape in pixels
    heightINT641–4096Height of the shape in pixels
    xINT2560–4096X position of the shape center (0 = left edge)
    yINT2560–4096Y position of the shape center (0 = top edge)
    canvas_widthINT5121–4096Width of the output mask
    canvas_heightINT5121–4096Height of the output mask
    batch_sizeINT11–64Number of identical masks to generate

    Outputs (1)

    NameTypeDescription
    MASKMASKβ€”