Load Images from ZIP
The zip you never have to unzip
- zip
- images
- names
- count
- skipped
Load Images from ZIP reads every picture inside a .zip and hands it to the graph as one image batch - no manual unzip, no folder full of loose PNGs, no file-by-file loaders. You drop a zip of reference frames, training crops, or a contact sheet's worth of images into ComfyUI's input folder, point this node at it, and everything downstream just sees a normal batch. If you've ever spent a workflow doing "extract zip → Load Image Batch → delete the mess", this is the step that disappears.
It ships in WAS Node Suite, the big MIT toolkit that's been in ComfyUI users' hands since the early days. The suite's v3 rewrite is huge (457 nodes), so odds are you already have it in your Add Node menu - this node sits under WAS Suite/Archive.
How it works
A zip holds files, but a ComfyUI batch holds one tensor - so every image has to reach the same size, and the node makes that explicit instead of silently mangling things. resize_mode decides how mixed sizes get there: fit and pad keeps the whole image and fills bars with pad_color; fill and crop fills the frame and cuts the overhang; stretch distorts; crop or pad never resamples and keeps original pixels. width/height are what every image comes out at (a multiple of 8 suits a sampler; 512 or 1024 matches most models).
There's a memory rule worth knowing: the node loads as many images as 32 megapixels holds - 128 at 512×512, 32 at 1024×1024 - and says in the log when an archive has more. That's why start and limit exist: page through a big archive a chunk at a time, and the log tells you the next page's index.
The file menu lists every zip in ComfyUI's input, output, and temp folders (each tagged with where it sits), and pattern filters what gets read - * takes everything, *.png only PNGs, frames/**/*.png everything under a folder, and a / anchors at the archive root. Optionally wire a ZIP from the suite's Open ZIP node into the zip socket and the menu is ignored entirely.
The outputs that matter
Three wires do the real work:
- images - the batch, all at
width×height, in sorted-name order. - names - the filename each image came from, in batch order (
frames/cat.png). Folders inside the archive are kept, so twocat.pngfiles stay apart. Read one out with Text List Get at the same index as the image. - count and skipped - how many made it in, and how many entries were rejected (non-images, symlinks, damaged, encrypted). Each rejection gets named in the log.
Wire names into a filename prefix on save and you can round-trip an archive through a graph with every output keeping its original name.
Installing it
ComfyUI Manager → search "WAS Node Suite v3", or:
cd ComfyUI/custom_nodes
git clone https://github.com/WASasquatch/was-node-suite-comfyui.git
Then restart. You need ComfyUI 0.14.0+ and Python 3.10+. The suite installs nothing by itself - no pip, no model downloads - and writes its config to <ComfyUI user dir>/was-node-suite/ on first start.
Where people get burned
The classic mistake is expecting a batch from images of very different sizes and then wondering why the resize seems to crop things. Pick fit and pad (or crop or pad with matching sources) and check pad_color. Second: default channels is RGB, so transparency is dropped - and a transparent pixel that got scaled comes out black. Choose RGBA if you're compositing, and keep in mind the batch counts against your VRAM the way any batch does; a 4K-per-image archive will not fit in one load, which is what the 32-megapixel cap and start/limit are protecting you from.
Inputs (12)
| Name | Type | Default | Description |
|---|---|---|---|
| file | COMBO | Which archive to read. The menu lists every .zip in ComfyUI's input, output and temp folders and in any folder added under paths.allow_read, each tagged with where it sits. Ignored while the zip socket is connected. | |
| pattern | STRING | * | Which entries to read; STRING. No '/' matches the file name at any depth; a '/' anchors at the archive root. Case is ignored, and non-images are always skipped. Eg: *, *.png, frames/**/*.png |
| resize_mode | COMBO | fit and pad | How mixed sizes reach width by height, since one batch holds one size. `fit and pad`: whole image, pad_color bars. `fill and crop`: fills the frame, ends cut. `stretch`: distorts. `crop or pad`: no resampling, original pixels kept. |
| width | INT | 5121–16384 | How wide every image in the batch comes out, in pixels. Every mode delivers exactly this width, so the batch is this wide whatever the archive held. A multiple of 8 suits a sampler; 512 or 1024 matches most models. |
| height | INT | 5121–16384 | How tall every image in the batch comes out, in pixels. Together with width this is also what decides how many images fit in one batch: the node loads as many as 32 megapixels holds, which is 128 at 512 by 512 and 32 at 1024 by 1024, and says in the log when there are more. |
| interpolation | COMBO | lanczos | Scaling filter. `lanczos` is sharpest and slowest; `bicubic` and `bilinear` are softer and quicker; `nearest` invents no colour, for pixel art and label maps. Ignored in `crop or pad`. |
| align | COMBO | middle center | Which part survives a crop, and which side takes the wider pad bar. `top center` suits portraits, where a centred crop takes the forehead off. Ignored in `stretch`. |
| pad_color | STRING | #000000 | Fill for space the image does not cover; STRING. Any Pillow colour: `#RRGGBB`, a name, or `#RRGGBBAA`. Empty is transparent, which only shows while channels is RGBA. Eg: white |
| channels | COMBO | RGB | Channels the batch carries. `RGB` is what samplers and upscalers expect; transparency is dropped, and a transparent pixel that was scaled comes out black. `RGBA` keeps alpha, for compositing and Image Select Channel. |
| start | INT | 00–1024 | Which matching image the batch starts at; INT, counting from 0 in sorted name order. Leave limit at 0 to read a large archive a page at a time: the log names the next page's index. |
| limit | INT | 00–1024 | How many images to load from start; INT. 0 loads as many as one batch holds at the chosen size. A number above that is reduced, and the log says so. |
| zipopt | ZIP | The archive to read, from Open ZIP. Connected, it is used and the menu is ignored, so the archive is opened and indexed once however many nodes read it. |
Outputs (4)
| Name | Type | Description |
|---|---|---|
| images | IMAGE | Every image that was read, as one batch, all at width by height and all with the same channel count. In the order the names sort, so two runs of the same archive produce the same batch. |
| names | ARRAY | The name each image came from, on one wire and in batch order, such as 'frames/cat.png'. The folders inside the archive are kept, so two files called cat.png in different folders stay apart. Read one out with Text List Get, using the same index as the image. |
| count | INT | How many images are in the batch, which is the length of the names list. Never 0: an archive that yields no image stops the prompt instead, because an image batch cannot be empty. |
| skipped | INT | How many entries did not reach the batch: not an image, an unsafe name, a symlink, encrypted, a repeated name, damaged, or holding something other than its extension says. The log names each one. Images left out by start or limit are not counted. |