From d9671b30980c84b2a00ae7faece576eec6d51d3e Mon Sep 17 00:00:00 2001 From: Ethanfel Date: Sun, 21 Jun 2026 15:13:56 +0200 Subject: [PATCH] docs: README for Image Pool (Grid) Co-Authored-By: Claude Opus 4.8 --- README.md | 108 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 108 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 0000000..32e8b18 --- /dev/null +++ b/README.md @@ -0,0 +1,108 @@ +# 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// +β”œβ”€β”€ 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/`: + +```bash +git clone /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: + +```bash +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.