AutoExpress Save Expressions
28 PNGs called joy.png, which is the whole point
- images
What it's for
You've just generated twenty-eight versions of the same face. ComfyUI's own Save Image node will happily write all of them out as ComfyUI_00042_.png through ComfyUI_00069_.png, and then you get to open them one by one to work out which is which. Not fun at 28 images. Genuinely miserable at 28 images per character, three characters deep.
This node exists so the filenames carry the information. It writes <expression>.png - joy.png, anger.png, neutral.png - into a per-character folder. Which is, not by accident, exactly the naming convention SillyTavern's Character Expressions extension looks for. The pack's stated use case is character cards and visual novels; this node is where that stops being marketing and becomes a directory listing.
The mechanism
It's an output node with list inputs, so ComfyUI calls it once, after everything else has finished, with the full set of images and the full set of names. Then it walks the list in order: image i gets names[i], and gets saved to output/autoexpress/<character_name>/<names[i]>.png.
Both the folder name and the filename are sanitised - anything that isn't alphanumeric, dash, underscore or space becomes an underscore. There's also a fallback: if there are more images than names, the extras get expression_00, expression_01, and so on. That's a hint about the other requirement, which is that the order of names has to match the order of images. Both come out of the prompts node in the same order, so as long as you wire both from the same node you're fine.
Inputs
Three, all required:
- images - the IMAGE output of your FaceDetailer (or your Qwen-Image-Edit decode).
- names - the
nameslist from AutoExpress Expression Prompts or Edit Instructions. This is the input that makes the node worth using; without it the filenames are meaningless. - character_name - the folder. Defaults to
New_Character, which is a trap in slow motion: forget to change it and every character you ever make lands in the same folder, each new run overwriting the last one'sjoy.png.
No outputs. The node previews the images it wrote in its own body, so you get a visual confirmation in the graph without a Preview Image node.
Why the naming actually matters
The KB's character-consistency notes are clear that the hard part of a sprite set is never generating one good face - it's keeping the same character across all the variants, and then keeping track of which is which. Tools like VNCCS solve the first half with pose control and per-sprite regeneration; the second half is filenames, and it's the half people skip.
With this node the delivery step is one cp:
cp -r ComfyUI/output/autoexpress/MyCharacter \
SillyTavern/data/default-user/characters/MyCharacter/
Or zip the folder and use Upload sprite pack in SillyTavern. The extensions want the images unlabelled, uncropped and unrenamed, so resist the urge to tidy them.
Install
This node ships with the pack, so:
cd ComfyUI/custom_nodes
git clone https://github.com/deepratna-awale/AutoExpress
Or ComfyUI Manager → AutoExpress, or comfy node install autoexpress. Restart ComfyUI. It has no model requirements of its own, but it's useless without the rest of the pipeline - the prompts node to feed names and Impact Pack's FaceDetailer (plus Impact Subpack for the detector) to feed images.
Skip the repo's root install.sh; that one is the standalone Flask app's installer and it starts by upgrading your system packages with sudo apt.
Gotchas
The PNGs have no workflow metadata. This is a plain Pillow save() - no embedded ComfyUI prompt graph. If you're used to dragging a generated image back into ComfyUI to recover its settings, that won't work with these files. Keep your workflow saved, or save a parallel pass through the normal Save Image node.
Output lives outside the default folder. Files land in output/autoexpress/<character>/, not output/. If you're on a remote box, that's one extra directory level before the download button appears in your file browser.
Overwrites are silent. Run the same character twice and the second run replaces the first's files with no prompt, no (1) suffix, no warning. If you're iterating on intensity, either change character_name per attempt (MyCharacter_i04) or copy the folder out between runs. This is the one behaviour I'd change about the node, and it's cheap to work around once you know.
Inputs (3)
| Name | Type | Default | Description |
|---|---|---|---|
| images | IMAGE | — | |
| names | STRING | — | |
| character_name | STRING | New_Character | — |
Outputs (0)
No outputs