Save Image Original Name (JPG / PNG)
Upscaled 400 Files and Got ComfyUI_00001_.png Back?
- images
- saved_paths
You point a batch upscaler at a folder of 400 images. It works. Every output is named ComfyUI_00001_.png, ComfyUI_00002_.png, and so on - and nothing maps back to its source. If you're rebuilding a LoRA training set, comparing before/after pairs, or handing files back to whoever sent them, that's a real problem. Stock SaveImage can't fix it: its filename_prefix is a template you type, not a value read off each image coming down the pipe.
That's the whole pitch. Display name "Save Image Original Name (JPG / PNG)", class SaveOriginalJPG, category image/save, about 76 lines of Python. The author, aiwaifuhen-oss, is refreshingly upfront that it was built for one specific Civitai workflow - the RTX Batch Upscaler - "in collaboration with ChatGPT". Which is exactly what you want from a node this small: one job, done.
How it actually works
It takes the incoming IMAGE tensor, clamps it to 0–1, multiplies by 255, rounds, casts to uint8, and hands it to Pillow. For JPG it saves as JPEG at your quality with optimize=True hard-coded; for PNG it uses compress_level. That's it. Pillow and NumPy ship with ComfyUI - no model files, no keys, no API calls.
The naming logic is where most confusion comes from. It takes base_name, strips any extension, and writes <stem>.jpg or <stem>.png into the target folder. Exactly one image in the call gets you that exact name. Two or more and it appends _0001, _0002 from 1 - so "why did my names change" almost always means your images input was a batch.
One thing the README doesn't tell you: writing through Pillow directly means it never embeds ComfyUI's workflow chunk. Drag that PNG back onto the canvas and nothing reconstructs. As our metadata notes put it, that metadata is the project file - treat this as a delivery node, not your master - keep a SaveImage upstream if you care about reproducibility.
The inputs you'll actually touch
images- the tensor.RTXVideoSuperResolution.upscaled_images, aVAEDecode, whatever.base_name- the filename to reuse. Note the source: this is declaredforceInput, meaning there is no text box on the node. You must wire a STRING into it, which is the single biggest beginner wall here. More below.subfolder- relative path underComfyUI/output, defaultRTX_Upscaled, created if missing. Change that default unless you genuinely want the folder.format,quality(default 95),png_compress_level(default 6),on_existing(skip/overwrite/error).
The output is one thing: saved_paths, a STRING with the written paths joined by newlines. Skipped files show up as SKIPPED: <path>, which is handy wired into a text display when you're processing folders. The node also feeds saved images into ui.images, so you get an inline preview.
Installing it
ComfyUI Manager → Install Custom Nodes → search Save Original Image or ComfyUI-SaveOriginalImage → install → restart. The pack is Registry-published (PublisherId = aiwaifuhen-oss), so there's no URL to add.
Manual, if you prefer:
cd ComfyUI/custom_nodes
git clone https://github.com/aiwaifuhen-oss/ComfyUI-SaveOriginalImage
Restart ComfyUI. Nothing to download, nothing for models/. Version 1.1.1, MIT.
Feeding it a filename
Since base_name won't take typing, you need a STRING source. Two realistic options:
- FolderBatch Sync Queue's
base_nameoutput - the pairing this node was built for. It walks a folder and hands you the current filename alongside the image, which is what makes folder-in/folder-out work possible. - A core
PrimitiveStringnode for one-offs. TypeMorrigan_001, connect it, done. Extension optional -Morrigan_001.pngandMorrigan_001both produceMorrigan_001.jpg.
Where people get burned
"Invalid base_name." It rejects anything containing /, \, or : - filename, not path. Pulling names out of a directory walker? Take the stem first; Windows paths trip this constantly. Same guard on subfolder: absolute paths, .. and drive letters raise "Output folder must stay inside ComfyUI/output". That validation is why the node can't be tricked into writing outside output/.
on_existing=skip is sneaky. A skip still pushes the existing file to the preview, so you re-run with a changed upscale and the preview looks identical - you're looking at yesterday's file, not your new pixels. While iterating, set overwrite.
JPG eats transparency. Non-RGB images get converted to RGB by dropping alpha outright rather than compositing onto a background, so soft cutout edges can fringe. Use PNG if background removal is upstream.
Two save nodes, duplicate exports. A stock SaveImage still dangling off the same image gives you both - one in output/, one in your subfolder. The README flags it; the graph doesn't.
Is it worth installing
For a single image, no - SaveImage's filename_prefix templating (including %NodeName.widget% tokens) covers most of it. For folder batches, where the filename is the data - upscaling a training set, restoring old renders, running RTX Video Super Resolution over a directory - it's the missing piece. Just don't make it your only save node if you post your work with workflows attached.
Inputs (7)
| Name | Type | Default | Description |
|---|---|---|---|
| images | IMAGE | — | |
| base_name | STRING | — | |
| subfolder | STRING | RTX_Upscaled | — |
| quality | INT | 951–100 | — |
| on_existing | COMBO | skip | 3 options: skip, overwrite, error |
| format | COMBO | JPG | 2 options: JPG, PNG |
| png_compress_level | INT | 60–9 | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| saved_paths | STRING | — |