Nodes/ComfyUI-TinyBee/Save Image Dict To Zip
ComfyUI Node

Save Image Dict To Zip

One file that is both a picture and a zip

By TinyBeeman·Created about a year ago·Updated 16 days ago· 1
Save Image Dict To Zip
  • image_dict
  • polyglot_img
  • output_path
◄filename_prefiximagedict►
◄compress_to_ziptrue►
◄json_filenamemetadata.json►
◄json_txt►

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.

Category🐝TinyBee/Dicts

Inputs (6)

NameTypeDefaultDescription
image_dictImageDict—
filename_prefixSTRINGimagedict—
compress_to_zipoptBOOLEANtrue—
json_filenameoptSTRINGmetadata.json—
json_txtoptSTRING—
polyglot_imgoptIMAGE—

Outputs (1)

NameTypeDescription
output_pathSTRING—