Mask Edit — Transform/Draw/Points/BBox
One node for every mask-editing job — transform, draw, points, bboxes
- mask
- reference_image
- existing_mask
- mask
- positive_coords
- negative_coords
- bboxes
- neg_bboxes
- points_json
- bbox_json
- primary_bbox
Mask Edit (MEC) is the swiss-army knife of this pack: one node, five editing modes, and an eight-port output schema that stays the same no matter which mode you're in. It's a dispatcher - pick a mode and the corresponding widgets drive the engine. Transform a mask, draw a shape, place SAM points, or smooth a bounding-box track, all from the same node.
The reason it exists: the pack's README points out that legacy mask editing scattered the same job across half a dozen nodes. This one collapses them. If you're not sure which MEC editing node to use, start here.
The five modes
transform- the workhorse. Feeds on amaskinput and does per-axis morphing and shifting:expand_x/expand_y(dilate/erode, negative erodes),blur_x/blur_y(directional Gaussian),offset_x/offset_y(translate), plusfeather,threshold(binarize), andinvert. It's the quick "grow the mask 8 pixels" or "feather the edge" fix you'll reach for constantly.draw_shape- 12 shapes from a dropdown (circle, rectangle, ellipse, polygon, line, triangle, star, diamond, cross, rounded rectangle, heart, arrow) with named params: center, radius, size, rotation, thickness,value(fill intensity), and anoperationblend (set/add/subtract/max/min). There's abatch_sizefor making N frames of the shape - handy for a video wipe.draw_advanced- the power version: rawshape_params_jsonfor anything the named params don't cover.points_bbox- the interactive canvas mode. Theeditor_dataJSON carries your points and boxes from the JS widget (wire areference_imageand the canvas draws on it), and the node emits SAM-ready outputs.bbox_smooth- temporal smoothing for a sequence of[x,y,w,h]boxes, viabboxes_json,smoothing_radius,smoothing_method, andalpha. The fix for a jittery tracker.
Because it's pure CPU, it's instant - no GPU, no models.
Outputs that matter
The 8-port schema is fixed, which makes downstream wiring stable regardless of mode: mask, then SAM-facing data - positive_coords, negative_coords, points_json, bbox_json - plus bboxes, neg_bboxes, and primary_bbox. In points_bbox mode these feed straight into the pack's SAM nodes (or MaskOpsMEC) as point/box prompts. In other modes the ones that don't apply come back empty or zeroed, so don't panic at a [].
Install
cd ComfyUI/custom_nodes
git clone https://github.com/Code2Collapse/ComfyUI-CustomNodePacks.git
or ComfyUI Manager → search "CustomNodePacks", restart, confirm [MEC] Loaded ... in the console. No extra dependencies. One gotcha from the tooltips worth internalizing: transform requires a wired mask; if you switch to it without one, nothing comes out the mask port. And remember presets override sliders in the keying nodes - here the mode dropdown decides which widgets are honored at all.
Inputs (50)
| Name | Type | Default | Description |
|---|---|---|---|
| mode | COMBO | transform | transform: morph / blur / offset / feather / threshold (needs mask). draw_shape: pick a shape from a dropdown, set its params (12 shapes). draw_advanced: power-mode shape_params_json (raw JSON). points_bbox: interactive points + bbox canvas (SAM/SeC coords). bbox_smooth: temporally smooth a sequence of [x,y,w,h] boxes. |
| expand_x | INT | 0-512–512 | [transform] dilate/erode along X |
| expand_y | INT | 0-512–512 | [transform] dilate/erode along Y |
| blur_x | FLOAT | 0.00–128 | [transform] Gaussian sigma X |
| blur_y | FLOAT | 0.00–128 | [transform] Gaussian sigma Y |
| offset_x | INT | 0-4096–4096 | [transform] pixel shift X |
| offset_y | INT | 0-4096–4096 | [transform] pixel shift Y |
| feather | FLOAT | 0.00–128 | [transform/draw] feather radius |
| threshold | FLOAT | 0.500–1 | [transform] binarize threshold |
| invert | BOOLEAN | false | [transform] invert output |
| width | INT | 5121–16384 | [draw_*/points_bbox] canvas width |
| height | INT | 5121–16384 | [draw_*/points_bbox] canvas height |
| shape | COMBO | circle | [draw_shape] geometry |
| cx | FLOAT | 256.0-16384–16384 | — |
| cy | FLOAT | 256.0-16384–16384 | — |
| radius | FLOAT | 50.00–8192 | — |
| size_w | FLOAT | 200.00–16384 | — |
| size_h | FLOAT | 100.00–16384 | — |
| rx | FLOAT | 100.00–8192 | — |
| ry | FLOAT | 50.00–8192 | — |
| top_left_x | FLOAT | 100.0-16384–16384 | — |
| top_left_y | FLOAT | 100.0-16384–16384 | — |
| x2 | FLOAT | 400.0-16384–16384 | — |
| y2 | FLOAT | 400.0-16384–16384 | — |
| thickness | FLOAT | 5.00–500 | — |
| outer_r | FLOAT | 100.00–8192 | — |
| inner_r | FLOAT | 40.00–8192 | — |
| num_points | INT | 53–50 | — |
| corner_radius | FLOAT | 20.00–4096 | — |
| cross_size | FLOAT | 100.00–8192 | — |
| arrow_length | FLOAT | 200.00–16384 | — |
| head_length | FLOAT | 60.00–8192 | — |
| head_width | FLOAT | 80.00–8192 | — |
| points_json_shape | STRING | [[100,100],[400,100],[400,400],[100,400]] | [draw_shape] polygon vertices when shape=polygon |
| value | FLOAT | 1.000–1 | [draw_*] fill intensity |
| rotation | FLOAT | 0.0-360–360 | [draw_*] rotation deg |
| operation | COMBO | set | [draw_*] blend op |
| batch_size | INT | 11–256 | [draw_shape] number of frames |
| shape_params_json | STRING | {"cx": 256, "cy": 256, "radius": 50} | [draw_advanced] raw shape_params JSON (see MaskDrawFrame) |
| editor_data | STRING | {"points":[],"bboxes":[]} | [points_bbox] JSON from the interactive canvas |
| default_radius | FLOAT | 3.00.5–256 | [points_bbox] default brush radius |
| softness | FLOAT | 1.00–10 | [points_bbox] gaussian sigma multiplier |
| normalize | BOOLEAN | true | [points_bbox] clamp output to [0,1] |
| bboxes_json | STRING | [] | [bbox_smooth] JSON array of [x,y,w,h] per frame |
| smoothing_radius | INT | 31–30 | [bbox_smooth] window radius |
| smoothing_method | COMBO | median_then_exponential | [bbox_smooth] smoothing strategy |
| alpha | FLOAT | 0.300.05–1 | [bbox_smooth] exponential factor |
| maskopt | MASK | Source mask (transform requires this) | |
| reference_imageopt | IMAGE | Optional reference; canvas size matches it when supplied | |
| existing_maskopt | MASK | Existing mask to blend onto in draw modes |
Outputs (8)
| Name | Type | Description |
|---|---|---|
| mask | MASK | Rendered mask for the active mode (zero-mask in bbox_smooth mode). |
| positive_coords | STRING | Positive points JSON (points_bbox mode); '[]' otherwise. |
| negative_coords | STRING | Negative points JSON (points_bbox mode); '[]' otherwise. |
| bboxes | BBOX | Positive bbox list (points_bbox); single-element list in bbox_smooth. |
| neg_bboxes | BBOX | Negative bbox list (points_bbox mode). |
| points_json | STRING | All points JSON (points_bbox); '[]' otherwise. |
| bbox_json | STRING | All bbox JSON (points_bbox) or smoothed bboxes JSON (bbox_smooth). |
| primary_bbox | BBOX | Primary [x,y,w,h]: first positive bbox or smoothed first bbox. |