Save Image Dict To Zip
One file that is both a picture and a zip
- image_dict
- polyglot_img
- output_path
What it's for
This is the payoff node of the pack's Dict workflow: it takes a labelled set of images and writes them out as one portable artifact instead of a spray of ComfyUI_00031_.png files. Two shapes, chosen by one toggle - a .zip with the images and an index.json naming them, or a plain folder with the same contents.
And then there's the party trick. Wire something into polyglot_img and you get a single .png that is a perfectly normal image and a valid zip archive containing the whole bundle. ComfyUI's own convention - the workflow lives inside the PNG - taken one step further: now the images live in there too.
How it works
The image dict is written key by key, in insertion order. Each key becomes a filename (spaces to underscores, anything outside letters, digits and -_.() stripped, .png appended, collisions suffixed _0001), and index.json records the original key for every file so the bundle stays labelled. If both json_filename and json_txt are filled in, that text is written as an extra JSON - handy for captions or generation settings.
The polyglot works because PNG and ZIP read from opposite ends of a file. A PNG decoder reads forward from byte zero and stops at the IEND chunk, ignoring whatever is appended after it. A ZIP reader scans backward from the end of file for its end-of-central-directory record, and the standard's "prepended data" correction handles the fact that the recorded offsets assume the archive starts at byte zero. It's the same mechanism that makes self-extracting .exe+zip files work, and it's implemented by Python's zipfile, 7-Zip, WinRAR and most unzip builds. So a tool doesn't need to know where the PNG ends:
unzip my_bundle.png -d extracted/
# or, in Python:
python -c "import zipfile; zipfile.ZipFile('my_bundle.png').extractall('out')"
One honest caveat on the naming: compress_to_zip is really package, not compress - the archive is written with default ZIP_STORED, no deflate. PNGs are already deflated, so you lose very little, but don't expect the file size to drop.
Inputs and outputs
image_dict and filename_prefix are required (filename_prefix defaults to imagedict). Then compress_to_zip (on = "Compress to Zip", off = "Export as Folder"), json_filename (default metadata.json), json_txt (multiline), and polyglot_img.
The single output, output_path, is a STRING holding where it wrote. The node is an output node, so it always runs - that's how it gets saved at all.
Skip the polyglot_img wiring unless you want the combo file; with it unwired you get a clean .zip.
Installing it
Part of ComfyUI-TinyBee, category 🐝TinyBee/Dicts. Standard library only, nothing to download, no build step.
cd ComfyUI/custom_nodes
git clone https://github.com/TinyBeeman/ComfyUI-TinyBee
Or search ComfyUI-TinyBee in Manager, install, restart.
Where people get burned
It overwrites. Unlike Save Image, this node doesn't append a counter - same filename_prefix, same filename, every run. Wire a counter, date or run name into the prefix if you want a history. Keep the prefix a plain name, too: the ComfyUI helper it uses already resolves any folder part of the prefix, so adding a path can end up doubled and the zip write has no directory to land in.
The metadata file only appears if you fill in json_txt. Both it and json_filename have to be non-empty; leaving the text box blank means no metadata.json, despite the default filename sitting right there looking like an invitation.
Only the first frame of each image is saved. Feed a 4-image batch into a key and you get exactly one PNG for that key, not four. The dict is a named set, not a batch container.
An empty or unwired dict writes nothing and returns an empty string - no error, no file. If your bundle came out missing, check the Add to Image Dict chain first: an unwired image input there removes a key rather than adding one.
Inputs (6)
| Name | Type | Default | Description |
|---|---|---|---|
| image_dict | ImageDict | — | |
| filename_prefix | STRING | imagedict | — |
| compress_to_zipopt | BOOLEAN | true | — |
| json_filenameopt | STRING | metadata.json | — |
| json_txtopt | STRING | — | |
| polyglot_imgopt | IMAGE | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| output_path | STRING | — |