LayersSaver - Save Layer From Images
Batch of images → one layered PSD, without touching a graphics app
- input_image
- layers
Every image in your batch becomes its own layer in one Photoshop file. That's the whole pitch of LayersSaver - Save Layer From Images, and if you've ever stood in front of twelve generated variations you wanted to composite by hand, you already know why that's worth having.
It's the mask-free sibling of the "Save Layer" node in the same tiny pack (ComfyUI-Layers, ~60 stars, unmaintained since mid-2024). Where the other node needs masks to carve an image into layers, this one just takes whatever batch you feed it and stacks every frame as a layer named Image_1, Image_2, and so on. Think: seed variations, inpaint passes, an animation frame stack, or a "generated + cleaned-up + upscaled" set you want to hand a designer as one file.
How it works
The mechanism is about as simple as it gets. The node reads your batch as a [batch, height, width, channels] tensor, adds an alpha channel to anything that isn't already RGBA (fully opaque, so your transparency doesn't surprise you), then walks through the batch and writes each image as a separate layer record into a .psd via pytoshop. Nothing is resized, nothing is composited - the images land in the file exactly as they came in.
One quirk in the code worth knowing: if you feed it the wrong shape, the error message says the input should be [batch_size, channels, height, width]. That's wrong on ComfyUI - its image tensors are [batch, height, width, channels]. The actual dimension check looks at the right slot, so the node works fine; just don't let the scary-looking message make you think your data is malformed.
The inputs and output
It's the thinnest input list in the pack, which is the point:
input_image- your batch of images. Batch size is unlimited as far as the code is concerned; each one becomes a layer.output_path- the only real decision. If it doesn't end in.psd, it's treated as a directory (created if missing) and a timestampedlayered_image_<date>.psdis written inside. End it in.psdand it writes straight to that file. Leave it empty and the node dies with a confusingFileNotFoundError- always put a real path in.
The layers output (type IMAGE) just hands the now-RGBA batch back to the graph, so you can wire it somewhere if you want to see what got written. It's not an output node, so nothing appears in the image tray - your artifact is the .psd on disk.
Installing it
Same story as the sibling node: it's registered, so ComfyUI Manager will find ComfyUI-Layers or Save Layers Node for ComfyUI. Manual install is two lines plus the Python deps:
cd ComfyUI/custom_nodes
git clone https://github.com/alessandrozonta/ComfyUI-Layers
cd ComfyUI-Layers
pip install pytoshop -I --no-cache-dir
pip install psd-tools --no-deps
Restart ComfyUI and you're done - no models to download, CPU only. Note the README's own clone example points at github.com/yourusername/...; that's a placeholder, use the real URL above.
Gotchas to plan around
This pack is effectively abandoned - no commits since July 2024 and open issues no one has answered - so the troubleshooting is on you. The known ones:
- NumPy. Installing via Manager has been reported to bump NumPy past 2.0 and break ComfyUI's image loading and preview entirely.
psd-toolsis deliberately installed with--no-depsto dodge this, butpytoshopstill pulls NumPy in. If ComfyUI breaks right after install, pin NumPy below 2.0. - PSDs that won't open. Open issue: "unexpected end-of-life was encountered" when opening generated files. Compression (RLE) is another reported source of corrupted layers.
- Layer pile-up. After a long session, PSDs can accumulate layers from previous runs - restart ComfyUI to clear it.
Honest verdict: for "dump a batch into a layered PSD" this is the fastest thing in the ecosystem, and if it ever breaks you're only a restart or a pinned NumPy away. For anything fancier - per-image names, masks, blend modes - the mask-based "Save Layer" node in the same pack is the one to reach for.
Inputs (2)
| Name | Type | Default | Description |
|---|---|---|---|
| input_image | IMAGE | — | |
| output_path | STRING | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| layers | IMAGE | — |