Ethanfel 69968ebb20 fix: flex-wrap grid + free resize (drop width floor)
The DOM-widget width doesn't reliably track the node width in frontend
1.45, so force a fixed column count clipped the grid and the width floor
blocked resizing down. Use flex-wrap (cells wrap to fit, never clip),
drop the computeSize width floor (resize freely), and re-sync the widget
width + reflow on manual resize.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-21 16:19:00 +02:00
2026-06-21 15:12:53 +02:00
2026-06-21 15:12:53 +02:00
2026-06-21 15:13:56 +02:00

ComfyUI Datasete Gates

Custom nodes for curating image datasets in ComfyUI.

Image Pool (Grid)

A node that holds a curated pool of images — each with its own remembered mask and editable label — shown as an in-node thumbnail grid. One image is selectable as the node's output (image + mask + index + count + label), so you can switch which image flows downstream without rewiring.

![category: Datasete Gates]

What it does

  • In-node grid of the pooled images. Ingest by paste (Ctrl+V), drag-and-drop, or the Upload button.
  • Click a thumbnail to make it the active output. No rewiring needed to switch images.
  • Per-slot mask: click the 🖌 button to paint a mask in ComfyUI's MaskEditor. The mask is remembered per image and never redrawn when you switch between images.
  • Per-slot label: type a label under each thumbnail; it's saved with the pool and exposed on the label output.
  • Drag to reorder thumbnails; to delete.
  • The pool is stored on disk, so it survives a ComfyUI restart and travels with the workflow (via a per-node pool id).

Inputs

Input Type Description
index INT -1 (default) outputs the in-node selected image. 0+ forces that slot index (clamped to the pool size).
pool_id STRING Per-node pool identifier. Managed automatically by the UI (a UUID minted per node and hidden); you normally never touch it.

Outputs

Output Type Description
image IMAGE The selected image, [1, H, W, 3] float 0..1. A 1×1 black image when the pool is empty.
mask MASK The selected image's mask, [1, H, W] float 0..1. All zeros when the slot has no mask.
index INT The resolved slot index that was output.
count INT Number of images in the pool.
label STRING The selected slot's label.

Mask polarity

A mask is a grayscale PNG where white (1.0) = the painted region of interest (the area you painted in the MaskEditor — i.e. the area to inpaint). No mask file means an all-zeros MASK output. The MaskEditor stores the painted region in the image's alpha channel; the extension bakes that alpha into a grayscale mask on save so that white = painted.

Managed pool folder

Each pool lives under ComfyUI's input directory:

input/grid_pool/<pool_id>/
├── manifest.json        # {active, slots:[{image, mask, label, added}], next_seq}
├── img_0001.png         # an image
├── img_0001.mask.png    # its mask (sidecar; optional)
├── img_0002.png
└── ...
  • Images are named monotonically (img_0001.png, img_0002.png, …).
  • A mask is stored as a *.mask.png sidecar next to its image.
  • manifest.json is written atomically. If it's missing or corrupt, it is rebuilt from the files on disk.

Cloning nodes

Copy/paste of a node shares the source node's pool_id (both show the same pool). To give a clone its own independent pool, right-click it → “Detach pool (new id)”.

Install

Clone (or symlink) this repo into ComfyUI's custom_nodes/:

git clone <repo-url> /path/to/ComfyUI/custom_nodes/ComfyUI-Datasete-Gates
# or, for local development:
ln -sfn /media/p5/ComfyUI-Datasete-Gates /path/to/ComfyUI/custom_nodes/ComfyUI-Datasete-Gates

Restart ComfyUI. The node appears under the “Datasete Gates” category as “Image Pool (Grid)”.

Dependencies (torch, Pillow, numpy, aiohttp) are already provided by ComfyUI.

Development

The storage layer (gates/pool.py) is pure stdlib and fully unit-tested without ComfyUI. Run the tests with:

python -m pytest tests/ -v

Layout:

  • gates/pool.py — pure storage (manifest, add/remove/reorder/active/label/mask). Stdlib only.
  • gates/imaging.py — torch/PIL tensor loaders.
  • gates/node.py — the GridImagePool node.
  • gates/handlers.py / gates/routes.py — pure handlers + aiohttp routes (/grid_pool/*).
  • web/grid_image_pool.js — the in-node grid UI + MaskEditor integration.
S
Description
No description provided
Readme 362 KiB
Languages
Python 52.6%
JavaScript 47.4%