Nodes/NH-Nodes/Layer Stack Composite (NH)
ComfyUI Node

Layer Stack Composite (NH)

Drop layers onto a canvas with exact coordinates

By jetthuangai·Created 5 months ago·Updated 21 days ago· 6
Layer Stack Composite (NH)
  • background_image
  • layer_1
  • layer_2
  • layer_3
  • layer_4
  • layer_5
  • layer_6
  • layer_7
  • layer_8
  • layer_9
  • layer_10
  • layer_11
  • layer_12
  • layer_13
  • layer_14
  • layer_15
  • layer_16
  • layer_17
  • layer_18
  • layer_19
  • layer_20
  • layer_21
  • layer_22
  • layer_23
  • layer_24
  • layer_25
  • layer_26
  • layer_27
  • layer_28
  • layer_29
  • layer_30
  • layer_31
  • layer_32
  • layer_33
  • layer_34
  • layer_35
  • layer_36
  • layer_37
  • layer_38
  • layer_39
  • layer_40
  • layer_41
  • layer_42
  • layer_43
  • layer_44
  • layer_45
  • layer_46
  • layer_47
  • layer_48
  • layer_49
  • layer_50
  • layer_51
  • layer_52
  • layer_53
  • layer_54
  • layer_55
  • layer_56
  • layer_57
  • layer_58
  • layer_59
  • layer_60
  • layer_61
  • layer_62
  • layer_63
  • layer_64
  • image
  • used_count
  • layer_info
layer_count1
positions0,0

Sometimes you don't want a smart layout - you want each image exactly where you tell it, on top of a specific background. That's Layer Stack Composite (NH) (class NH_LayerStackComposite). It pastes up to 64 layers onto a background image at explicit pixel coordinates, the way you'd drag elements onto a design canvas. Think product shots on a branded background, cutouts assembled into a scene, or any "stack these things" composite where a grid just won't do.

How it works

You give it a background_image (any image), a layer_count, and a multiline positions box where each line is x,y for one layer. Up to 64 layer_1layer_64 IMAGE inputs - wire in as many as you set layer_count to. Each layer is pasted at its coordinates, clipped at the canvas edge, and later layers paint over earlier ones. Straightforward compositing, no resize magic: layers paste at their native resolution, so if a layer is bigger than the background it just gets clipped.

The outputs are image (the composite), used_count, and a JSON layer_info string. One implementation detail worth knowing: this node forces itself to rerun every time (its IS_CHANGED returns NaN), which means widget-driven positions always apply fresh and you never get a stale composite from ComfyUI's cache. That's deliberate - with 64 layers, a cached stale result would be maddening.

The inputs that matter

  • positions - one x,y per layer, in order, one per line. Layer 1 gets the first line, layer 2 the second, and so on. Coordinates are pixels from the top-left of the background.
  • layer_count - how many layers to actually paste. Set it to the number of wired layers; unused inputs are ignored.
  • background_image - the canvas everything lands on. If you want a solid color instead, feed a solid-color image in.

Where you'd actually use it

This is the VTON/product-workflow glue of the NH pack - pair it with the pack's garment masks or cutouts, or with Layer Layout Composite (NH) when you want slot math instead of raw coordinates. Because positions are plain text, you can also drive them from a text node or a Math Eval (NH) upstream if you want computed placement. It's not an output node, so chain it into a save node or the large-preview nodes when you're done.

Installing

ComfyUI Manager → search NH-Nodes → install → restart. Or:

cd ComfyUI/custom_nodes
git clone https://github.com/jetthuangai/NH-Nodes.git
cd NH-Nodes
pip install -r requirements.txt

Restart and refresh the browser tab if the node looks cached. Pillow/numpy is all this one touches from the requirements.

Gotchas

Layers don't get resized, which trips people up when their cutouts are huge and the background is small - check dimensions before you wire things in. And positions is positional: miss a line and everything below it shifts. Keep the count of lines in sync with layer_count or you'll spend an afternoon wondering why layer 12 is somewhere surprising. Also remember it always re-runs, so if you drop this into a huge graph it will invalidate the cache downstream - fine for a compositor, annoying if you accidentally leave one mid-pipeline.

CategoryNH-Nodes/Image

Inputs (67)

NameTypeDefaultDescription
background_imageIMAGE
layer_countINT10–64
positionsSTRING0,0
layer_1optIMAGE
layer_2optIMAGE
layer_3optIMAGE
layer_4optIMAGE
layer_5optIMAGE
layer_6optIMAGE
layer_7optIMAGE
layer_8optIMAGE
layer_9optIMAGE
layer_10optIMAGE
layer_11optIMAGE
layer_12optIMAGE
layer_13optIMAGE
layer_14optIMAGE
layer_15optIMAGE
layer_16optIMAGE
layer_17optIMAGE
layer_18optIMAGE
layer_19optIMAGE
layer_20optIMAGE
layer_21optIMAGE
layer_22optIMAGE
layer_23optIMAGE
layer_24optIMAGE
layer_25optIMAGE
layer_26optIMAGE
layer_27optIMAGE
layer_28optIMAGE
layer_29optIMAGE
layer_30optIMAGE
layer_31optIMAGE
layer_32optIMAGE
layer_33optIMAGE
layer_34optIMAGE
layer_35optIMAGE
layer_36optIMAGE
layer_37optIMAGE
layer_38optIMAGE
layer_39optIMAGE
layer_40optIMAGE
layer_41optIMAGE
layer_42optIMAGE
layer_43optIMAGE
layer_44optIMAGE
layer_45optIMAGE
layer_46optIMAGE
layer_47optIMAGE
layer_48optIMAGE
layer_49optIMAGE
layer_50optIMAGE
layer_51optIMAGE
layer_52optIMAGE
layer_53optIMAGE
layer_54optIMAGE
layer_55optIMAGE
layer_56optIMAGE
layer_57optIMAGE
layer_58optIMAGE
layer_59optIMAGE
layer_60optIMAGE
layer_61optIMAGE
layer_62optIMAGE
layer_63optIMAGE
layer_64optIMAGE

Outputs (3)

NameTypeDescription
imageIMAGE
used_countINT
layer_infoSTRING