Save Layered TIFF (XMP)
Save Layered TIFF (XMP)
- preview_image
- layers
- filepath
Some pipelines don't produce one image - they produce a stack. The composite, the mask, the outpainted region, the upscale pass. The usual answer is either a folder full of files held together by a naming convention nobody remembers, or intermediates that stay in memory and vanish when the queue finishes. Save Layered TIFF (XMP) is the third option: one lossless TIFF where every page is a named layer, with the full workflow, prompt, and model hashes embedded as XMP on page 0.
Drop the result into Photoshop or Affinity Photo and each page appears as a separate, named layer in the Layers panel - standard TIFF behavior, not a plugin requirement. macOS renders it natively (Finder thumbnails, QuickLook, Preview.app). It's a reference implementation of the Layered TIFF + XMP spec, and it's the reason the whole pack exists.
How it works
The node writes a multi-page TIFF with tifffile. Page 0 is your preview layer; every extra page carries its name in TIFF tag 285 (PageName), and the XMP block - workflow graph, prompt graph, model SHA256 hashes, comma-separated layer names, author - lives in tag 700 on page 0. Each page compresses independently: Deflate at level 9 plus a delta predictor, which is lossless and typically 30–50% smaller than raw. It also writes a throwaway PNG per layer to temp so the node UI previews every layer, not just page 0.
The inputs that matter:
- preview_image - page 0, your thumbnail or composite; preview_name labels it (default "preview").
- layers - the IMAGE list with the rest; layer_names - a STRING list aligned to layers, e.g. "mask, composite, upscale". Let the alignment drift and pages come out named layer-01, layer-02.
- json_metadata - arbitrary JSON stored in
comfy:json. - author - embedded in the XMP
dc:creatorfield. - sidecar_xmp - also drops a standalone
.xmpfile beside the TIFF. - filename_prefix -
ComfyUI-XMP_00001.tiff, auto-incremented.
Output: filepath, a STRING. Wire it to a text or display node if you want the path on canvas or chained downstream.
Pair it with LayerPack
This node expects lists - INPUT_IS_LIST is on, and layer_names has to line up with layers. That's exactly what the pack's Layer Pack node exists for: feed it up to 16 image/name pairs and it hands you the two aligned lists. Assembling them by hand is where people go wrong.
Installing it
Same pack, so no separate install to think about: ComfyUI Manager, search "Save Image (XMP)", or:
cd ComfyUI/custom_nodes
git clone https://github.com/connerkward/comfyui-save-image-xmp.git
pip install tifffile
tifffile is genuinely required here, and there's a trap: the import happens inside the save function, so the node loads fine and only dies at save time if you skipped the install. Install the dependency.
Common issues
- Only the first frame of any batch is saved - a batch of previews collapses to image one. Feed single frames or pick your page before saving.
- Classic TIFF tops out at 4GB (the pack writes
bigtiff=False). A tall stack of 8K layers can get uncomfortable; keep layer counts sane. - Drag-back workflow reload doesn't work on TIFF the way it does on PNG - but the workflow is in the XMP, readable with exiftool or comfy-viewer, so the recipe isn't lost.
Inputs (8)
| Name | Type | Default | Description |
|---|---|---|---|
| preview_image | IMAGE | — | |
| preview_name | STRING | preview | — |
| filename_prefix | STRING | ComfyUI-XMP | — |
| author | STRING | — | |
| sidecar_xmp | BOOLEAN | false | — |
| layersopt | IMAGE | — | |
| layer_namesopt | STRING | — | |
| json_metadataopt | STRING | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| filepath | STRING | — |