Save Info from Source
Name Your Output After the Photo You Loaded
- source_info
- filename
- output_dir
You batch a folder of a hundred family photos through a restoration graph. Every output needs to come back out with the right name, next to the file it came from, and not overwrite anything. Save Info from Source is how you do that without typing anything per image: it reads the loader's source bundle and hands you filename and output_dir as STRINGs.
It's the bridge between the pack's loader and whatever saver you're using. Two outputs, one input, no widgets.
What it reads
The input is a typed PORTRAIT_SOURCE_INFO_V2 object, produced by Load Image + Source Info - the pack's loader, which handles single-image and auto-advancing folder modes with EXIF orientation and explicit colour/alpha handling. That bundle carries the filename, the output directory, and the source width and height. This reader unpacks two of those into primitives; width and height stay inside the bundle and are unpacked elsewhere.
Two things about the outputs worth knowing before you wire them.
filename has no extension. It's the stem - scan2024 from scan2024.png. That's almost always what you want downstream (suffix it, then let the saver add .png), but it surprises people once. If you need two files out of one source, the pack's Filename: Append Suffix node is the companion: build _upscaled or _final, then hand the result to the saver.
output_dir comes from the loader's own output_dir setting, passed through essentially unchanged. If that widget was left blank, this output is blank too and the saver falls back to its own default. The loader does not create directories and does not write anything - it just carries the string forward.
Why separate the reader from the saver
Because the pack's config design is one typed bundle per stage plus small readers, and a saver that takes two plain strings can be any saver. You can name outputs with the pack's Simple Image Saver, or with a stock SaveImage, or with a third-party node that takes a filename_prefix - the reader doesn't care which. It also means the filename and the directory can be routed independently: send filename into a name-building chain, send output_dir straight to the saver.
Typical shape:
Load Image + Source Info.source_info
├──────────────→ Save Info from Source.source_info
│ filename → Filename: Append Suffix → Simple Image Saver
│ output_dir ─────────────────────────→ Simple Image Saver
└──────────────→ Intelligent AutoCrop → Smart Photo Prepare → …
Worth remembering when you're puzzling over a result later: if your saver writes PNG with workflow metadata enabled, the graph is embedded in the file, and dragging the image back into ComfyUI reconstructs it. Any re-encode - a JPEG conversion, a screenshot, an image host that recompresses - strips that block permanently. Keep the original save if the provenance matters.
Install
Ships with the pack. In ComfyUI Manager, search PortraitUtils and install, then restart the ComfyUI server - a browser refresh reloads the frontend but not the Python nodes, which is why people conclude the install failed.
cd ComfyUI/custom_nodes
git clone https://github.com/heyburns/PortraitUtils
/path/to/ComfyUI/venv/bin/python -m pip install -r PortraitUtils/requirements.txt
Use ComfyUI's own interpreter (python_embeded on Windows portable builds). Pack dependencies are numpy, Pillow, opencv-python-headless, and tifffile - install a single OpenCV wheel variant, since they all claim the cv2 namespace. It's filed under PortraitUtils/Config V2/Readers.
Gotchas
Feed this node the wrong bundle - an edit config, a preparation info, a raw string - and it raises a type error telling you to connect the matching PortraitUtils V2 config node, rather than silently returning empty strings. That's the pack's house style across every reader, and it makes miswiring obvious.
Second: the loader's two outputs are the image and this one bundle, so there is nothing to alias. In a batch run the bundle changes per queued execution, which is exactly the behaviour you want for naming - but it also means anything you cache downstream of the loader may hold the previous photo's name. If a filename looks one photo behind, force a fresh execution rather than chasing the saver.
Inputs (1)
| Name | Type | Default | Description |
|---|---|---|---|
| source_info | PORTRAIT_SOURCE_INFO_V2 | — |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| filename | STRING | — |
| output_dir | STRING | — |