Nodes/TrentNodes/PSD Layer Compositor
ComfyUI Node

PSD Layer Compositor

Recomposing a PSD After You've Swapped the Background

By TrentHunter82·Created 9 months ago·Updated 4 days ago· 36
PSD Layer Compositor
  • replacement_image
  • image
  • change_log
  • summary
  • psd_path
folder_path
replacement_index0
replacement_end_index-1
replacement_modesingle
replacement_fitstretch
range_fitcanvas
background_colortransparent
respect_visibilitytrue
output_psd_pathPSDComp
text_recolor_modeoff
text_color#FFFFFF
auto_contrast_threshold0.50
text_layer_pattern(?:(?<![A-Za-z])[Tt][Ee][Xx][Tt](?![a-z])|文字|文本|标题|字幕)
text_shadowfalse
flatten_recolored_textfalse
delete_replaced_layersfalse

The splitter took your PSD apart; this node puts it back together - with one crucial difference: it lets you swap a layer (or a whole run of layers) for an image you generated, then recomposites everything at the original canvas size using the manifest's positions, opacity, and visibility. It's the workhorse of the "AI background replacement in a real design file" workflow, and the version in the README has grown three replacement modes precisely because real PSDs are messy.

The three replacement modes

  • single - replace one layer at replacement_index (0 = bottom, usually the background) with replacement_image. The original behavior, and the one that covers a clean PSD.
  • replace_range - swap a contiguous range [replacement_index..replacement_end_index] with one image. This is for the messy case where the "background" is actually five stacked layers (gradient, texture, soft shadow, sky, wall) and no single layer is the background. range_fit decides whether the replacement is sized to the full canvas or to the union bounding box of the replaced layers.
  • underlay - paste the replacement under all original layers. It's the escape hatch when you genuinely can't pin down which layers are the background; you get the new backdrop behind everything and toggle offending layers' visibility off in the source PSD.

The README's ladder is worth internalizing: try single → detect a range (with PSDBackgroundDetect feeding the indices) → fall back to underlay. Each mode trades automation for reliability.

replacement_fit (stretch / fit / cover / center) and background_color (transparent / white / black / hex) round out the basics - fit letterboxes and cover crops, so pick the one that doesn't distort your generated art.

The fancy part: text recolor

Behind the optional inputs lives real polish: text_recolor_mode can recolor text layers in the output. manual uses text_color for every text layer; auto_contrast picks black or white per layer from the luminance behind it; complement follows the magazine convention (white on dark, black on light). Combined with text_shadow, this keeps captions readable when you've dropped in a wild new background. When output_psd_path is set, recolored text is saved as a clipping PixelLayer above each TypeLayer - so the text stays editable in Photoshop.

The outputs

image is the flat recomposite at original canvas size - the thing you actually wanted. change_log is a detailed run-down of what changed (replaced layers, recolor decisions per layer, shadows, skipped layers, output path); summary is the one-sentence version; psd_path is where the re-exported PSD landed, if you set output_psd_path. That save works in single mode only in v1 - a documented limitation, so don't expect a re-exported PSD from a range swap yet.

Installing it

Part of TrentNodes; install the pack once:

cd ComfyUI/custom_nodes
git clone https://github.com/TrentHunter82/TrentNodes.git
cd TrentNodes
pip install -r requirements.txt

ComfyUI Manager ("Trent Nodes") works too, modulo the known day-one repo-rename quirk that makes Manager sometimes flag the pack as "unsafe" - clone manually if it refuses. Needs psd-tools (in requirements) and the splitter's output folder; no model downloads.

Where people get burned

  • replacement_index semantics - it's the bottom layer that's index 0, matching the splitter. A background that's near the top of the layer panel will not be index 0.
  • Range indices - replacement_end_index is inclusive. Off-by-ones here are the most common PSD complaint.
  • Hidden layers reappearing - respect_visibility (default on) skips them; flip it off only if you deliberately want hidden layers composited.
CategoryTrent/PSD

Inputs (17)

NameTypeDefaultDescription
folder_pathSTRINGFolder from PSD Layer Splitter (must contain _manifest.json)
replacement_indexINT0-1–9999Layer index to replace (or start of range). 0 = bottom (usually background). -1 = no replacement. Ignored when replacement_mode = underlay.
replacement_end_indexINT-1-1–9999Inclusive end of layer range to replace. -1 = single-layer swap (use replacement_index alone). Only used when replacement_mode = replace_range.
replacement_modeCOMBOsinglesingle = swap one layer at replacement_index. replace_range = swap layers [start..end] with one image. underlay = paste replacement under all original layers (escape hatch for messy PSDs).
replacement_fitCOMBOstretchHow to size the replacement image. stretch = exact fit. fit = preserve AR, letterbox. cover = preserve AR, crop. center = no resize, center
range_fitCOMBOcanvasTarget area for replace_range mode. canvas = full PSD canvas (usually what you want). union_bbox = combined bbox of the replaced layers.
background_colorSTRINGtransparentCanvas backdrop: 'transparent', 'white', 'black', or hex like '#FFFFFF'
respect_visibilityBOOLEANtrueIf True, skip layers marked hidden in the original PSD
replacement_imageoptIMAGENew image to insert at replacement_index
output_psd_pathoptSTRINGPSDCompFilename or path for the saved .psd. Three modes: - bare prefix ('PSDComp', 'posters/run'): saves to ComfyUI output folder with auto-incrementing counter (PSDComp_00001_.psd, etc.). Subfolders are auto-created. - absolute path ('/abs/path.psd'): saves to that exact path; overwrites if it exists. - empty: skip PSD save (only produce the flat IMAGE output). Original source PSD is never overwritten. Requires replacement_image and replacement_index >= 0.
text_recolor_modeoptCOMBOoffRecolor PSD text layers (kind=='type') in the output. off = leave colors alone. manual = use text_color for every text layer. auto_contrast = pick black or white per layer based on the luminance of pixels behind it. complement = magazine-cover convention: white on darker bg, black on lighter bg, decided per text layer from the bg luminance underneath. Combine with text_shadow for busy bgs. When output_psd_path is set, recolor is also applied to the saved PSD as clipping PixelLayers above each text layer (text stays editable).
text_coloroptSTRING#FFFFFFColor for text layers when text_recolor_mode=manual. Hex (#RRGGBB), CSS name, or rgb().
auto_contrast_thresholdoptFLOAT0.500–1Used when text_recolor_mode=auto_contrast. If avg luminance under the text (0..1) is below this, recolor to white; otherwise to black.
text_layer_patternoptSTRING(?:(?<![A-Za-z])[Tt][Ee][Xx][Tt](?![a-z])|文字|文本|标题|字幕)Regex matched against layer names. Any layer whose name matches is treated as text and recolored, in addition to real TypeLayers and text-shaped Smart Objects. The default catches 'Text 1', 'Layer 4 - text', 'header_text', 'TextLayer', plus Chinese 文字 / 文本 / 标题 / 字幕 (text / title / subtitle), while excluding 'texture', 'context', 'subtext'. (Layers covering >60% of the canvas are also ignored as a safety net against matched overlays/textures.) Clear the field to recolor TypeLayers only.
text_shadowoptBOOLEANfalseAdd a soft drop shadow behind each recolored text layer. Helps text read on busy or chromatic backgrounds. Applied to flat IMAGE preview and (when output_psd_path is set) inserted as a separate raster layer below each TypeLayer in the saved PSD. No-op when text_recolor_mode=off.
flatten_recolored_textoptBOOLEANfalseAffects the saved PSD only. OFF (default): keep TypeLayers editable - insert a same-shaped clipping PixelLayer above each recolored TypeLayer to tint it. ON: rasterize recolored TypeLayers in place as flat PixelLayers - the saved PSD shows clean recolored text with no clip-layer indirection, but the text is no longer editable in Photoshop. Useful for clean handoffs when the recipient doesn't need to change the words. Shadow/glow/box decoration layers are unaffected. No-op when text_recolor_mode=off.
delete_replaced_layersoptBOOLEANfalseAffects the saved PSD only. Applies in replace_range mode to the layers between replacement_index+1 and replacement_end_index (the ones swallowed by the replacement image). OFF (default): those layers stay in the saved PSD but are set to visible=False (recoverable if needed). ON: those layers are removed from the saved PSD entirely - cleaner handoff, smaller file. Only affects the saved file; the source PSD is never modified. No-op in single or underlay replacement_mode.

Outputs (4)

NameTypeDescription
imageIMAGEComposited image at the original PSD canvas size
change_logSTRINGDetailed summary of what changed from the input: replaced layers, text recolors (with chosen colors per layer), shadows added, skipped layers, and output PSD path.
summarySTRINGShort sentence-form description of the changes (e.g. "Replaced 4 layers; recolored 4 text layers to white; added shadow to text.").
psd_pathSTRINGAbsolute path of the saved PSD file (after resolution of relative paths / counter increment). Empty string when output_psd_path is blank (no PSD save was requested).