Extensions/ComfyUI-PSD-Layers
ComfyUI Extension

ComfyUI-PSD-Layers

ComfyUI nodes: save Seedream layer-separation results as smart-object PSD / load any PSD layer by layer with interactive panel and Photoshop blend modes

By coeyes·Created a day ago·Updated a day ago· 1
coeyes/ComfyUI-PSD-Layers
Nodes2
On cloudLocal install
Categoryimage
Stars1
Updateda day ago
Readme

ComfyUI-PSD-Layers

PSD layer workflow nodes for ComfyUI. No Photoshop installation required.

한국어 문서 (Korean)

  • Save Seedream Layers PSD — save ByteDance Seedream layer-separation results as a smart-object PSD
  • Load Layers PSD — load any PSD layer by layer with a composite output and per-layer image/mask outputs

Both nodes ship an interactive panel: stacked preview, alpha-accurate object picking with bounding-box highlight, drag-to-reorder z order, per-layer visibility toggles, and a status bar.

<p align="center"> <img src="https://raw.githubusercontent.com/coeyes/ComfyUI-PSD-Layers/main/docs/screenshot_load.png" alt="Load Layers PSD" height="560"> <img src="https://raw.githubusercontent.com/coeyes/ComfyUI-PSD-Layers/main/docs/screenshot_save.png" alt="Save Seedream Layers PSD" height="560"> </p>

Unlike canvas-editor nodes (e.g. XISER Canvas) that pack images into their own state format, this pack is a native PSD round-trip: it reads real PSDs (masks, clipping, blend modes), writes real smart-object PSDs that Photoshop opens losslessly, and wires everything into the graph as per-layer outputs.

Node: Save Seedream Layers PSD

Connect the outputs of ByteDanceSeedreamLayerSeparationNode (everything except layer_stack) straight into the node, top to bottom.

Inputs

| Input | Type | Connect to | |---|---|---| | base_image | IMAGE | base_image (background plate) | | base_mask | MASK | base_mask (1 = transparent) | | layers | IMAGE | layers batch (full canvas / minimal size both supported) | | masks | MASK | masks (1 = transparent) | | bboxes | BOUNDING_BOX | bboxes (uses name/z_index/content_rect from metadata) | | filename_prefix | STRING | same prefix templates as SaveImage (subfolder/name, %date:...%, …) |

Outputs

| Output | Type | Description | |---|---|---| | composite_image | IMAGE | composite of all layers (identical to the saved PNG) |

Behavior

  • On execution, saves <prefix>_00001_.psd + <prefix>_00001_.png (composite preview) to the output folder.
  • The PSD stacks the background plus each layer as an embedded smart object in z-index order.
  • Panel: click objects in the preview (alpha hit test) or rows in the list to select, drag rows to change z order, toggle visibility with the eye icon.
  • Re-save PSD button: saves again with the adjusted order/visibility without re-running the graph (counter increments). Hidden layers are included in the PSD with visible=false and excluded from the preview PNG.

Note: the Save button session lives in server memory — after a server restart, run the node once before using the button.

Node: Load Layers PSD

Pick a PSD from the input folder, or drag & drop a file onto the node (general purpose — not Seedream-specific). PSB is supported too.

Set psd_path to an absolute path on the server (pasted quotes are fine) to read that file directly instead of the input-folder combo — ideal for the edit-in-Photoshop-then-Reload loop. For remote access the path must be readable by the server; otherwise use drag & drop upload.

Outputs

| Output | Type | Description | |---|---|---| | composite_image | IMAGE | full composite. Before any edit: the PSD's embedded Photoshop render (pixel-perfect). After editing: recomposited with the psd-tools blend engine | | layers_batch / masks_batch | IMAGE / MASK | all layers on full-size canvases (no layer-count limit) | | layer_N_image / layer_N_mask | IMAGE / MASK | per-layer tight-crop pairs (up to 32, fixed bottom-to-top PSD order). Unused slots collapse automatically in the UI |

Behavior

  • Group flattening: only leaf layers are extracted. Layer masks, group raster masks and clipping masks are pre-applied to the alpha.
  • Text layers use the embedded raster (no fonts needed); shape layers are rasterized via psd-tools vector masks.
  • All Photoshop blend modes supported (reusing psd-tools BLEND_FUNC; measured mean error vs. the Photoshop render ≈ 0.03/255).
  • Adjustment layers / layer styles (effects): not applied when recompositing — a persistent warning appears in the status bar. They are present in the unedited composite (embedded render).
  • Reordering / hiding layers in the panel is serialized into the layer_state widget → invalidates the cache and affects the composite output. Per-layer output slots keep the original PSD order regardless of edits.
  • Reload button, plus automatic reload on the next run when the source file changes (mtime-based IS_CHANGED).

Installation

Copy this folder into ComfyUI/custom_nodes/, then:

pip install -r requirements.txt   # psd-tools>=1.18.0, pillow, numpy

Example workflows

example_workflows/ ships ready-made templates (also exposed in ComfyUI's workflow template browser): load_psd_layers and seedream_separation_to_psd.

Localization

Node tooltips/descriptions and the panel UI follow the ComfyUI language setting (Settings → Locale). Included: English, 한국어, 日本語, 中文, Español, Français, Русский. Panel texts switch immediately; translations live in locales/ and web/js/psdI18n.js.

Implementation notes

psd-tools does not officially support writing smart objects. The Save node assembles the SoLd/PlLd/lnk2 binary blocks from base64 templates extracted from a real Photoshop file, patching only uuid/transform/size at runtime, and works around a psd-tools bug (missing contentID in LinkedLayer v8 that makes Photoshop reject the file) via a LinkedLayerV8 subclass.

The Load node reads raster layers directly (layer.numpy(), ~10x faster than the compositing engine) and falls back to the engine only for vector content. UI preview assets are LANCZOS-downscaled (2048 px cap) with premultiplied alpha; graph-side rendering uses high-quality createImageBitmap caching with a zoom-settle redraw.

_smoke_test*.py provide offline verification (builder, save node, load node).

License / Author

MIT License — see LICENSE.

Author: Hyeongjik Song [email protected]