Nodes/comfyui-fvmtools/Batch Save Multi
ComfyUI Node

Batch Save Multi

One source picture, eight destinations, and a delete that means delete

By ping1979ping·Created 7 months ago·Updated about 10 hours ago· 3
Batch Save Multi
  • image_1
  • gate_1
  • image_2
  • gate_2
  • image_3
  • gate_3
  • image_4
  • gate_4
  • image_5
  • gate_5
  • image_6
  • gate_6
  • image_7
  • gate_7
  • image_8
  • gate_8
  • saved_paths
  • matched
  • matched_count
  • report
◄slots2►
◄routeall_matches►
◄base_dir►
◄fallback_dirunsorted►
◄originalkeep►
◄original_whenalways►
◄original_dirdone►
◄formatkeep►
◄quality95►
◄mask_min_area0.001►
◄overwritefalse►
◄source_path►
◄subdir_1refined►
◄subdir_2slot_2►
◄subdir_3slot_3►
◄subdir_4slot_4►
◄subdir_5slot_5►
◄subdir_6slot_6►
◄subdir_7slot_7►
◄subdir_8slot_8►

Batch Save Image writes one picture into one folder. Batch Save Multi writes up to eight - each with its own condition and its own destination, all derived from a single source file. If your night's sorting job is "refined versions into refined/, full-body shots into full/, close-ups into close/, everything the anatomy check hated into broken/", this is the node that does it in one pass instead of four save nodes with four routers.

How the slots work

slots decides how many slots are shown (1–8). Each slot has three things:

  • image_N - the picture to save. Leave it unconnected and the slot copies the original file byte for byte, untouched. That's how you file the source alongside the variants you just generated without re-encoding it.
  • gate_N - the condition. It accepts a BOOLEAN, an integer count (fires above 0), or a MASK, which fires when at least mask_min_area of the pixels are set (default 0.001, i.e. 0.1% of the frame - the right kind of number for a SAM3 aux mask on a small garment print). No gate wired means the slot always writes.
  • subdir_N - the target folder, relative to base_dir, or to the source picture's own folder when base_dir is empty. Absolute paths work too. Defaults read refined, slot_2, slot_3… so rename them.

route decides what happens when more than one gate fires: all_matches writes to every slot that fired, first_match only to the first. Combined with gate ordering that's a cheap priority system.

The original, and the fallback

  • fallback_dir (default unsorted) gets a copy of the original when gates are wired but none of them fired. Empty it and the node does nothing in that case instead.
  • original decides the fate of the source file after the slots are written: keep, move, copy into original_dir (default done), or delete. The delete is permanent - no recycle bin, no undo.
  • original_when is the safety catch worth knowing: on_match only handles the original when at least one gate fired, so pictures nothing has an opinion about stay exactly where they are. On a folder where most images won't match anything, that's the difference between a tidy run and a wipe.

The pack's own documentation adds one more reassurance about ordering: the original is handled last, and skipped entirely if a slot failed to write. An error in the middle never costs you the only copy.

Outputs and install

saved_paths (one path per line), matched (which slots fired, as text), matched_count, and report for the log or a sidecar. It's an output node, so it always executes.

cd ComfyUI/custom_nodes
git clone https://github.com/ping1979ping/comfyui-FVMtools

Restart, or install through ComfyUI Manager by searching comfyui-fvmtools. No extra dependencies for this node; source_path from Batch Load Image is needed for unconnected slots, for the original handling, and as the base for relative folders.

Where it bites

The image_N behaviour is genuinely surprising to read the first time: an unconnected image input is not "skip this slot", it's "copy the original". If you wanted a slot disabled, leave the gate unconnected and the image connected - or just don't wire the slot's folder into anything you care about.

delete plus original_when = always plus a folder that is also your archive is a combination that will eventually hurt. Test the routing on a copy of ten images first.

And mask_min_area is measured over the whole image, not over the subject. A mask that fires confidently on a small label inside a 4K frame can sit under 0.1% and be treated as a miss. Drop it to 0.0001 for small-region gates, or feed the gate a boolean verdict from a detector instead of the raw mask.

CategoryFVM Tools/Batch

Inputs (36)

NameTypeDefaultDescription
slotsINT21–8How many slots are in use.
routeCOMBOall_matchesall_matches: every slot whose gate fires gets the picture. first_match: only the first gated slot that fires. Slots without a gate always write.
base_dirSTRINGWhere relative folders live. Empty = the folder the source picture came from.
fallback_dirSTRINGunsortedGets a copy of the original when gates are wired but none fired. Empty = do nothing.
originalCOMBOkeepWhat happens to the source file once every slot is written. keep: stays. move/copy: into original_dir. delete: removed for good (no recycle bin).
original_whenCOMBOalwaysalways: handle the original on every run. on_match: only when at least one gate fired — pictures without a hit stay where they are.
original_dirSTRINGdoneTarget for original = move/copy.
formatCOMBOkeepEncoding for slots with an image input. keep: the source file's extension, PNG if unknown.
qualityINT951–100JPEG/WebP quality.
mask_min_areaFLOAT0.0010–1Share of set pixels a MASK gate needs to fire. 0.001 = 0.1 % of the picture.
overwriteBOOLEANfalseOff: a colliding name gets _001, _002, …
source_pathoptSTRINGThe loader's source_path. Needed for slots without an image, for the original handling and as the base of relative folders.
image_1optIMAGESlot 1: picture to save. Unconnected = copy the original file untouched.
gate_1opt*Slot 1: condition. BOOLEAN, a count (> 0), or a MASK (fires above mask_min_area). Unconnected = always write.
subdir_1optSTRINGrefinedSlot 1: target folder. Relative to base_dir (or the source folder), or an absolute path.
image_2optIMAGESlot 2: picture to save. Unconnected = copy the original file untouched.
gate_2opt*Slot 2: condition. BOOLEAN, a count (> 0), or a MASK (fires above mask_min_area). Unconnected = always write.
subdir_2optSTRINGslot_2Slot 2: target folder. Relative to base_dir (or the source folder), or an absolute path.
image_3optIMAGESlot 3: picture to save. Unconnected = copy the original file untouched.
gate_3opt*Slot 3: condition. BOOLEAN, a count (> 0), or a MASK (fires above mask_min_area). Unconnected = always write.
subdir_3optSTRINGslot_3Slot 3: target folder. Relative to base_dir (or the source folder), or an absolute path.
image_4optIMAGESlot 4: picture to save. Unconnected = copy the original file untouched.
gate_4opt*Slot 4: condition. BOOLEAN, a count (> 0), or a MASK (fires above mask_min_area). Unconnected = always write.
subdir_4optSTRINGslot_4Slot 4: target folder. Relative to base_dir (or the source folder), or an absolute path.
image_5optIMAGESlot 5: picture to save. Unconnected = copy the original file untouched.
gate_5opt*Slot 5: condition. BOOLEAN, a count (> 0), or a MASK (fires above mask_min_area). Unconnected = always write.
subdir_5optSTRINGslot_5Slot 5: target folder. Relative to base_dir (or the source folder), or an absolute path.
image_6optIMAGESlot 6: picture to save. Unconnected = copy the original file untouched.
gate_6opt*Slot 6: condition. BOOLEAN, a count (> 0), or a MASK (fires above mask_min_area). Unconnected = always write.
subdir_6optSTRINGslot_6Slot 6: target folder. Relative to base_dir (or the source folder), or an absolute path.
image_7optIMAGESlot 7: picture to save. Unconnected = copy the original file untouched.
gate_7opt*Slot 7: condition. BOOLEAN, a count (> 0), or a MASK (fires above mask_min_area). Unconnected = always write.
subdir_7optSTRINGslot_7Slot 7: target folder. Relative to base_dir (or the source folder), or an absolute path.
image_8optIMAGESlot 8: picture to save. Unconnected = copy the original file untouched.
gate_8opt*Slot 8: condition. BOOLEAN, a count (> 0), or a MASK (fires above mask_min_area). Unconnected = always write.
subdir_8optSTRINGslot_8Slot 8: target folder. Relative to base_dir (or the source folder), or an absolute path.

Outputs (4)

NameTypeDescription
saved_pathsSTRING—
matchedSTRING—
matched_countINT—
reportSTRING—