MIKKY Video Mask Editor 🎬
Paint masks on video frames, one at a time, inside the ComfyUI graph
- images
- optional_mask
- mask_batch
- image_batch
You've got a video clip and you need a mask on it - to keep a subject out of an inpaint, to roto an object for a composite, to build a per-frame condition for a video pipeline. Doing that frame-by-frame in ComfyUI used to mean exporting frames, painting in an external editor, re-importing, and trying to keep a batch aligned. MIKKY Video Mask Editor kills that loop: it puts a canvas right on the node that previews your whole batch, lets you scrub frames with A/D and paint on each one, then hands you a clean MASK batch that matches your IMAGE batch frame-for-frame. It's a small, single-purpose pack - this node is the whole pack - but it's exactly the kind of fiddly-interactive-thing ComfyUI is bad at natively.
How it works
The node is an output node that renders its own little editor widget in the graph. On the Python side it saves every input frame (and your optional_mask, if you feed one) as a webp preview to ComfyUI's temp folder and pushes them to the UI. You paint on a canvas at the image's original resolution - left click draws, right click erases, the scroll wheel changes brush size, A/← and D/→ step frames. When you're done, the JS serializes your strokes for each frame into a hidden string input, and the node re-runs, merging what you drew with the optional mask and applying any post-processing before outputting the batch.
The post-processing is OpenCV (cv2), and it's straightforward. fill_holes finds external contours and fills them. mode transforms your strokes: BBox snaps the painted region to its minimum bounding rectangle, Square makes it square (centered on the painted area) - handy when you're producing masks for model training or a node that wants a boxed region. blur_radius runs a Gaussian blur on the mask edge, which is the classic trick for feathering so an inpaint doesn't leave a hard seam.
The inputs that matter
Only a few deserve your attention:
images- your frame batch. Anything that outputsIMAGEworks; in practice that's a VHS Load Video → VAE Decode chain, or a frame-sequence generator.mode-Original(your raw strokes),BBox, orSquare.start_frame/end_frame- slice the batch. End is exclusive, and0means "through the last frame." Output only covers that range.optional_mask- a pre-existing mask (say, from a segmentation node) to union with your strokes.process_drawn_only- the newer toggle, and worth understanding. Off (default) merges your strokes withoptional_maskthen applies BBox/Square/blur to the whole merged thing, so the base mask gets reshaped too. On, only your hand-drawn part gets transformed and the base mask stays untouched.
Outputs are mask_batch (MASK) and image_batch (IMAGE), aligned frame-for-frame over the sliced range - wire the mask into an inpaint or conditioning and the images into whatever needs the frames.
Installing it
Easiest via ComfyUI Manager: search "MIKKY". Or:
cd ComfyUI/custom_nodes
git clone https://github.com/XYMikky12138/ComfyUI-MIKKY-Mask-Editor
then restart ComfyUI. The README also tells you to pip install -r requirements.txt - ignore that. The repo ships no requirements.txt at all, and the only Python dependency in the code (cv2) already ships with ComfyUI itself, so a plain clone-and-restart is the whole install. No models to download.
Gotchas
The README's clone URL is stale - it points at ComfyUI-MIKKY-Video-Mask-Editor, a repo that doesn't exist. Use the correct URL above (or Manager). Watch the end_frame off-by-one: it's exclusive, so to include frame 30 you set it to 31. And remember this is an interactive node: it reflects what's painted last run, so if you tweak a frame, you need the workflow to re-execute for the outputs to update - which the editor does for you, but it means bypassing the node kills your painted work. One honest caveat: the pack is small and the community footprint is basically nil, so if you hit a bug, the GitHub issues page is your best friend - not a Reddit thread, because there isn't one.
Inputs (9)
| Name | Type | Default | Description |
|---|---|---|---|
| images | IMAGE | — | |
| mode | COMBO | Original | 3 options: Original, BBox, Square |
| start_frame | INT | 0 | — |
| end_frame | INT | 0 | — |
| padding | INT | 00–500 | — |
| fill_holes | BOOLEAN | false | — |
| blur_radius | INT | 00–100 | — |
| process_drawn_only | BOOLEAN | false | — |
| optional_maskopt | MASK | — |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| mask_batch | MASK | — |
| image_batch | IMAGE | — |