ComfyUI Cutom node: 💾 Save Image Extended for ComfyUI 2.51
7 min readSave Image Extended for ComfyUI: Customize the folder, sub-folders, and filenames of your images! Use the values of ANY node’s widget, by simply adding its badge number in the form id.widget_name. Save data about the generated job (sampler, prompts, models) as entries in a json
(text) file, in each folder. Oh btw… also saves your output as JXL AVIF WebP jpg jpeg j2k jp2 png gif tiff bmp … And yes the prompt is included ComfyUI can load them but a PR approval is needed to fix a bug on their side and @omfyanonymous fixed it!.
Reboot by me since 2024-05-05, original idea from @thedyze
How To Use Save Image Extended
You can use whatever separator you want, and add folder separators “/” anywhere you want!
Installation
Pretty simple with ComfyUI Manager:
Then look for and install Save Image Extended:
Requirements
There is a requirements.txt
that will take care of that, but just in case:
- python 10.6
- piexif
- imagecodecs
- pillow
- pillow-avif-plugin
- pillow-jxl-plugin
pip install piexif imagecodecs pillow pillow-avif-plugin pillow-jxl-plugin
For the native jxlpy
JPEG-XL it’s more complicated. You would need to install and compile the wheel jxlpy, and therefore, need a valid and functional MSVC installation, along with the libjxl library, likely along with the dev code. Impossible to do that on Windows. Instead, we rely on imagecodecs
which embeds libjxl 0.9.0.
Manual Download
1. Open a terminal inside the ‘custom_nodes’ folder located in your ComfyUI installation dir
2. Use the git clone
command to clone the repo, under ComfyUI\custom_nodes\
git clone https://github.com/audioscavenger/save-image-extended-comfyui
Parameters / Usage
Attribute | Description |
---|---|
filename_prefix |
String prefix added to files. |
filename_keys |
Comma separated string with sampler parameters to add to filename. E.g: sampler_name, scheduler, cfg, denoise Added to filename in written order. resolution also works. vae_name model_name (upscale model), ckpt_name (checkpoint) are others that should work. Here you can try any parameter name of any node. As long as the parameter has the same variable name defined in the prompt object they should work. The same applies to foldername_keys . |
foldername_prefix |
String prefix added to folders. |
foldername_keys |
Comma separated string with sampler parameters to add to foldername. Add more subfolders by prepending “./” to the key name. |
delimiter |
now a free field Delimiter = 1 character, can be anything your file system supports. Windows users should still use “/” for subfolders. |
save_job_data |
If enabled, saves information about each job as entries in a jobs.json text file, inside the generated folder. Mulitple options for saving prompt , basic data , sampler settings , loaded models . |
job_data_per_image |
When enabled, saves individual job data files for each image. |
job_custom_text |
Custom string to save along with the job data. Right click the node and convert to input to connect with another node. |
save_metadata |
Saves metadata into the image. |
counter_digits |
Number of digits used for the image counter. 3 = image_001.png. Will adjust the counter if files are deleted. Looks for the highest number in the folder, does not fill gaps. |
counter_position |
Image counter first or last in the filename. |
one_counter_per_folder |
Toggles the counter. Either one counter per folder, or resets when a parameter/prompt changes. |
image_preview |
Turns the image preview on and off. |
output_ext |
File extension: PNG by default, or WEBP (coming soon). |
Unknown key names in filename_keys
and foldername_keys
are treated as custom strings: if you enter wrongNumber.attribute
, you will get attribute
in your filename.
Node inputs
images
– The generated images.
Optional:
positive_text_opt
– Optional string input for when using custom nodes for positive prompt text.negative_text_opt
– Optional string input for when using custom nodes for negative prompt text.
Automatic folder names and date/time in names
Convert unix datetime formats right off the batch!
Samples you can use:
Unix datetime | Example | Comment |
---|---|---|
%F
|
2024-05-22 | |
%D |
05/22/24 | This effectively creates subfolders |
%F %H-%M-%S |
2024-05-22 09-13-58 | |
%Y/%V |
2024/21 | year subfolder / ISO week number subfolder |
Details and discussion on How Save Image Extended works
[JPEG XL is a heated debate on chromium forum](https://issues.chromium.org/issues/40168998#comment85) and if true indeed that Google is working on WebP2, jxl is unlikely to take off any day soon. Proponents arguably declare with no proof, that jxl is better and faster than the current best codec: AVIF. But again, without support from the industry, it’s going nowhere.Pillow cannot save Exif data in JPEG2000, or maybe I did not read the doc. Who the heck is using JPEG2000 in 2024 anyway?
Disclaimer: Does not check for illegal characters entered in file or folder names. May not be compatible with every other custom node, depending on changes in the prompt
object.
Tested and working with default samplers, Efficiency nodes, UltimateSDUpscale, ComfyRoll, composer, NegiTools, and 45 other nodes.
Quality and compression settings: default is 90, 100 will activate **lossless** for AVIF and WEBP only.
Ext | Compression | Maker | Size | Compression |
---|---|---|---|---|
png | max 9 | PIL | 413111 | 0% |
j2k | n/a | PIL | 395028 | 4% |
jxl | lossless | PIL | 301310 | 27% |
jxl | 90 | PIL | 179210 | 57% |
jpeg | 90 | PIL | 88554 | 79% |
avif | 90 | Imagick | 67272 | 84% |
webp | 90 | Imagick | 64416 | 84% |
webp | 90 | PIL | 64356 | 84% |
avif | 60 | PIL | 47353 | 89% |
avif | 60 | Imagick | 33691 | 92% |
About loading prompt from WebP AVIF JPEG JXL: atm ComfyUI can only load PNG and WebP
For AVIF and JPEG, you will have to wait for the team to update their product.
The prompt is included under the **EXIF** tag UserComment
(IFD0 / 0x010f and 0x010e) as defined here. WAS Node Suite also use those tags. They must be next to each other in order to Comfy to be able to load them with drag and drop.
Data | EXIF | Name | String looks like |
---|---|---|---|
prompt | 0x010f | Make | Prompt: {“5” … } |
workflow | 0x010e | ImageDescription | Workflow: {“5” … } |
You can retrieve the prompt manually with exiftool, here are some example commands:
exiftool -Parameters -Prompt -Workflow file.png
exiftool -Parameters -UserComment -Prompt -Workflow file.{jpg|webp|avif}
We are incompatible with extended-saveimage-comfyui – This node can be safely discarded, as it only offers WebP output anyways. My node already adds JPEG and WebP.
You asked for it… Now you can select which node to get the widget values from! Formerly, this custom node would simply return the last value found: useless if you have multiple identical nodes…
To see node numbers in the UI, enable the badge IDs:
jobs.json sample: always generated and appended, not sure what it can be used for tho.
BUG discovered with rgthree‘s Ksampler Config: using steps_total
as an input to a Ksampler, will issue the index of the output, instead of the steps value (“[nodeNum, 0]” instead of actual steps input value).
FIX: use steps_total
instead of steps
!
RoadMap
I won’t promise you the moon, but since I use this node myself, I will maintain it as much as I can. I do provide a way to contact me, and will accept PR and collabs.
Once I feel like I don’t have time to work on it, I will gladly transfer ownership or let collabs maintain it.
TODO:
– [ ] improve get_latest_counter: restarts when user renames files after the counter part.
– [ ] offer to place the counter anywhere, as a key in filename_keys
– [ ] keep same counter if extension changes?
– [ ] files will be out of order if prefixes change… that is expected, but is this what we want?
- release 2.70 💾
- added JPEG-XL
added JPEG2000
fixed help popup text color in dark mode
- added JPEG-XL
- release 2.65 💾
- published in comfy-registry
- release 2.64 💾
- added Help at top-right corner, based off KJNodes
- release 2.63 💾
- fixed negative_prompt job save overwritten by positive_prompt
– [x] remove job_custom_text? no, some ppl use it apparently
– [x] remove jobs.json? no, some ppl use it apparently
– [x] ComfyRoll CR XY Save Grid Image: it offers jpeg webp tif – check how it embeds prompt – nope it does not
- fixed negative_prompt job save overwritten by positive_prompt
- release 2.62 💾
- prompt and workflow are saved in IFD 270 and 271 for better load compatibility
– disabled jobs.json by default, this thingy seems useless to me
- prompt and workflow are saved in IFD 270 and 271 for better load compatibility
- release 2.61 💾
- added quality input
- release 2.60 💾
- added extensions jpeg, gif, tiff, bmp
– added image_optimization (only for jpeg)
– now saves prompt and workflow separately into 0x9286/UserComment and 0x010e/ImageDescription
- added extensions jpeg, gif, tiff, bmp
- release 2.51 💾
- added native unix datetime format
- release 2.50 💾
- added JXL support
- added ‘BOOLEAN’ support
- release 2.46 💾
- BUG discovered with rgthree‘s Ksampler Config: using
steps_total
as an input to a Ksampler, will issue the index of the output, instead of the steps value (“\[nodeNum, 0]” instead of steps value). FIX: usesteps_total
instead ofsteps
! - uncommented
__all__
in init.py - potential bugfix in splitKey,
len(splitKey) = 2
to identify actual “node.widget” format
- BUG discovered with rgthree‘s Ksampler Config: using
Wrapping Up
Thoughts? Comments? Bugs to report? Requests? Let’s meet at the discussion section!
wow