kubakub load images from dir
A folder loader that runs your graph once per image and can resume where it stopped
- IMAGE
- MASK
- filename
- subfolder
- source_path
- total_count
- current_index
- image_batch
- mask_batch
- loaded_count
ComfyUI has a perfectly good folder loader in core (Load Image Batch), and most of the time that's the right answer. This one exists for batch jobs - the case where each image in a folder should run through the graph on its own, take its own seed, get its own filename, and be skippable if it's already been done. That last part is the reason it exists in a pack about facade fabrication: render 300 reference images to GLB overnight, get interrupted at image 214, and start again without redoing the first 213.
Inputs
directory is the folder. .jpg, .png, .webp and .bmp, sorted by name - natural sort, so frame_2 comes before frame_10 rather than after it. Leave it empty and you get a built-in sample folder of 12 frames of the sample facade, which is how the templates run without files.
image_load_cap is the one that confuses people. Default is 1, not 0. Zero means all of them; the default loads one image per run. That's deliberate - this node is built to be queued repeatedly, one image per pass, with a resume mechanism - but if you wire it in expecting a batch and get a single image, this is why.
start_index (0 = first) picks where to begin, counted after the name filter and skipping. load_always forces a reload on every Queue; with it off, the node only reloads when the settings or the folder's files change. include_subfolders (default on) and subfolder_prefix (default on, which prefixes the filename output with the subfolder name so hero.png and refs/hero.png don't collide) handle nested folders.
name_filter takes a substring, case-insensitive, with * and ? as wildcards - *_left_* is the usual shape. skip_existing_in is the resume switch: give it a folder of finished .glb files and any image that already has a matching .glb by name is skipped.
batch_fit decides what happens when the images aren't all the same size, for the image_batch output only: resize_to_first, pad_to_first, or error. The list outputs are unaffected - worth knowing, because it means you can have a ragged folder and still process it image by image.
Outputs, and the list-versus-batch thing
Ten of them, in two families. The list outputs - IMAGE, MASK, filename, subfolder, source_path, current_index - emit one entry per image, and in ComfyUI a list output means the downstream graph runs once per item. That's the batch-job behaviour: 300 images in, 300 separate runs through the sampler, each with its own filename available to a save node.
The batch outputs - image_batch, mask_batch - are everything as one tensor for nodes that want a stack. That's the input for a video or a walkthrough, with loaded_count telling you how many frames you actually got, total_count telling you how many there were after filtering and skipping, and mask_batch carrying transparency with 1 = transparent.
So the same node serves both idioms, and choosing wrong is the most common mistake here: list outputs into a 3D render node means it renders once per image (slowly), batch outputs into a per-image saver means you only get one file. If you want a folder of frames to behave as one batch for a node that also accepts a list, put core Rebatch Images in between.
Install
Part of the pack:
cd ComfyUI/custom_nodes && git clone https://github.com/kubakubkub/ComfyUI_KubaNodes
python -m pip install -r ComfyUI_KubaNodes/requirements.txt
Or ComfyUI Manager, search kubakub nodes. It's in the utils group, so if you've switched groups off in kubakub.ini and it's missing, check that first.
Notes from use
The reload behaviour is worth understanding properly because it's the difference between a fast batch and a slow one. With load_always off, the node participates in ComfyUI's normal caching; the pack implements it through the usual IS_CHANGED mechanism, so an unchanged folder means the loader doesn't even re-scan. On a big folder over a network share that's the difference between minutes and seconds per run, which is exactly why you shouldn't leave load_always on "just in case".
The resume trick has one prerequisite: your output filenames have to match your input names. skip_existing_in is a name comparison against .glb files, not a database. If your save node writes 00042.glb and your images are facade_042.png, nothing will ever be skipped and you'll quietly re-render everything. Check that once by running a skip pass over a completed folder and watching how long it takes.
Inputs (9)
| Name | Type | Default | Description |
|---|---|---|---|
| directory | STRING | The folder to load .jpg, .png, .webp and .bmp images from, sorted by name (frame_2 before frame_10). Empty = a built-in sample folder: 12 frames of the sample facade. | |
| image_load_capopt | INT | 1 | How many images to load per run. 0 = all of them; the default 1 loads one image. |
| start_indexopt | INT | 00–18446744073709550000 | Which image to start at (0 = the first), counted after the name filter and skipping. |
| load_alwaysopt | BOOLEAN | false | Reload on every Queue. Off reloads only when the settings or the folder's files change. |
| include_subfoldersopt | BOOLEAN | true | Also load images from folders inside the folder. |
| subfolder_prefixopt | BOOLEAN | true | Put the subfolder name in front of the filename output (subfolder_name), so names from different folders do not clash. |
| name_filteropt | STRING | Only load files whose name contains this text (any case); * and ? work as wildcards. Empty = all files. | |
| skip_existing_inopt | STRING | A folder of finished .glb files: images that already have a .glb of the same name there are skipped. Empty = skip nothing. | |
| batch_fitopt | COMBO | resize_to_first | image_batch / mask_batch: how images of other sizes join the first one's size. The list outputs are unchanged. |
Outputs (10)
| Name | Type | Description |
|---|---|---|
| IMAGE | IMAGE | one image per list item |
| MASK | MASK | one mask per list item (1 = transparent) |
| filename | STRING | each image's name without extension (with the subfolder in front when subfolder_prefix is on) |
| subfolder | STRING | each image's subfolder inside the folder (empty for the folder itself) |
| source_path | STRING | each image's full file path |
| total_count | INT | how many images the folder has after the filter and skipping |
| current_index | INT | the index the loading started at |
| image_batch | IMAGE | all loaded images as one batch |
| mask_batch | MASK | all masks as one batch |
| loaded_count | INT | how many images this run loaded (the frames in image_batch) |