Nodes/ComfyUI-PJLatent/PJ 图像智能记忆拼接器
ComfyUI Node

PJ 图像智能记忆拼接器

A montage node that remembers what you didn't re-run

By pongjoo·Created 7 months ago·Updated 3 days ago· 0
PJ 图像智能记忆拼接器
  • 槽位1_图片
  • 槽位2_图片
  • 槽位3_图片
  • 槽位4_图片
  • 槽位5_图片
  • 槽位6_图片
  • 槽位7_图片
  • 槽位8_图片
  • 槽位9_图片
  • 槽位10_图片
  • 槽位11_图片
  • 槽位12_图片
  • 槽位13_图片
  • 槽位14_图片
  • 槽位15_图片
  • 槽位16_图片
  • 槽位17_图片
  • 槽位18_图片
  • 槽位19_图片
  • 槽位20_图片
  • 槽位21_图片
  • 槽位22_图片
  • 槽位23_图片
  • 槽位24_图片
  • 槽位25_图片
  • 槽位26_图片
  • 槽位27_图片
  • 槽位28_图片
  • 槽位29_图片
  • 槽位30_图片
  • 批次图片输入
  • 拼接大图
  • 记忆图批次
拼接模式四宫格 (2x2)
尺寸适配方式等比裁剪并填充 (Cover)
拼接边尺寸限制0
拼缝间距0
背景填充颜色黑色
记忆缓存模式正常记忆 (自动检测改动)
自定义行数2
自定义列数2

Every grid-image workflow - character sheets, storyboards, 2×2 style comparisons, comic panels - has the same annoyance: you regenerate one cell, and now you have to re-stitch all of them, dragging five images back into place because the graph only executes what you touched. PJ_Image_Stitcher (pongjoo/ComfyUI-PJLatent, menu "PJ_Nodes/Image") takes a different, slightly clever angle: it remembers what each slot held last run, so when you only re-roll one panel it rebuilds the montage from the three panels it already has. It calls that "memory"; it's really a per-node cache that makes iterative panel editing feel like editing instead of re-assembling.

How it works. The node keeps an in-Python cache per graph node (keyed by the node's unique id). Every run, each 槽位N_图片 that's connected gets an MD5 hash of its tensor; if the hash changed, the cached image for that slot is replaced. Disconnected a slot entirely? The previous image is kept and still used in the stitch. So the editing loop becomes: generate a 2×2, don't like panel 3, disconnect that slot, re-roll it, reconnect - run the graph, and the output is a fresh 2×2 where panels 1, 2 and 4 are the exact images you already approved. Only the changed pixels moved through the sampler.

That behavior is governed by 记忆缓存模式 (memory mode):

  • 正常记忆 (auto-detect changes) - the default above: update what changed, reuse what didn't.
  • 锁定记忆 (read old only) - never overwrites; every slot is whatever the cache holds. Stops the montage from mutating at all while you tune something upstream.
  • 清空重置 (force overwrite) - pure one-shot stitcher: everything connected is used, nothing cached. Choose this if the memory behavior is confusing you - it's exactly a normal montage node.

The layout side. 拼接模式 offers 四宫格 (2×2), 九宫格 (3×3), 左右横向 (side by side), 上下纵向 (stacked), or 自定义网格 with 自定义行数/列数. 尺寸适配方式 decides how mismatched inputs are handled: Cover (crop to fill each cell), 保持比例并居中留白 (letterbox on a colored background), or Stretch. 拼接边尺寸限制 - 0 means auto-align to the longest input edge; set it to force a fixed basis (the tooltip spells out the orientation rules: horizontal stitch constrains height, vertical constrains width, grid constrains each cell's longest side). 拼缝间距 adds a gap between cells and 背景填充颜色 picks black/white/gray/transparent for the seams and letterbox area.

Outputs: 拼接大图 (the composite) and 记忆图批次 (all cell images, fitted to a uniform size, in one batch - handy if you want to save or re-use the aligned cells).

Two things to know before you trust the memory. First, it lives in the running Python process, not in your workflow file - restart ComfyUI and every node's cache is gone, and the first run after a restart rebuilds from whatever is currently connected. If a slot is disconnected and the cache was cleared, that slot just doesn't appear. Second, the node deliberately always re-executes (IS_CHANGED returns NaN), so ComfyUI never cache-skips it - that's what lets it detect changes every run, but it also means the stitch recomputes on every queue tick even when nothing upstream moved. Harmless; just don't expect it to be skipped.

When to reach for it. This is the one I'd grab for multi-panel iterative work over a plain grid-stitch node: if you're doing a character sheet and want to swap one outfit iteration without regenerating the other three cells, the memory saves real GPU time and keeps your good panels pixel-identical. For a one-shot collage, run it in 清空重置 mode and it's just a tidy montage node with Cover/letterbox/stretch options.

Install

Ships in pongjoo/ComfyUI-PJLatent (MIT, Chinese-authored). ComfyUI Manager → search "ComfyUI-PJLatent", or:

cd ComfyUI/custom_nodes/
git clone https://github.com/pongjoo/ComfyUI-PJLatent.git

Restart ComfyUI - torch-only, no models. The bundled frontend shows five slot ports by default and auto-adds another the moment every existing slot has a wire (up to 30), then reclaims empty trailing ports when you disconnect - so the canvas tracks how many panels you're actually assembling. Look for PJ 图像智能记忆拼接器 under "PJ_Nodes/Image".

CategoryPJ_Nodes/Image

Inputs (39)

NameTypeDefaultDescription
拼接模式COMBO四宫格 (2x2)5 options: 四宫格 (2x2), 左右横向拼接, 上下纵向拼接, 九宫格 (3x3), 自定义网格
尺寸适配方式COMBO等比裁剪并填充 (Cover)3 options: 等比裁剪并填充 (Cover), 保持比例并居中留白, 拉伸至统一尺寸 (Stretch)
拼接边尺寸限制INT00–163840 为自动按输入图片中最长边智能对齐;大于 0 时强制设定拼接基准边尺寸(横拼限制高度,竖拼限制宽度,网格限制单元格最长边)
拼缝间距INT00–200
背景填充颜色COMBO黑色4 options: 黑色, 白色, 灰色, 透明/暗色
记忆缓存模式COMBO正常记忆 (自动检测改动)3 options: 正常记忆 (自动检测改动), 锁定记忆 (仅读取旧图), 清空重置 (强制覆盖)
自定义行数optINT21–20
自定义列数optINT21–20
槽位1_图片optIMAGE
槽位2_图片optIMAGE
槽位3_图片optIMAGE
槽位4_图片optIMAGE
槽位5_图片optIMAGE
槽位6_图片optIMAGE
槽位7_图片optIMAGE
槽位8_图片optIMAGE
槽位9_图片optIMAGE
槽位10_图片optIMAGE
槽位11_图片optIMAGE
槽位12_图片optIMAGE
槽位13_图片optIMAGE
槽位14_图片optIMAGE
槽位15_图片optIMAGE
槽位16_图片optIMAGE
槽位17_图片optIMAGE
槽位18_图片optIMAGE
槽位19_图片optIMAGE
槽位20_图片optIMAGE
槽位21_图片optIMAGE
槽位22_图片optIMAGE
槽位23_图片optIMAGE
槽位24_图片optIMAGE
槽位25_图片optIMAGE
槽位26_图片optIMAGE
槽位27_图片optIMAGE
槽位28_图片optIMAGE
槽位29_图片optIMAGE
槽位30_图片optIMAGE
批次图片输入optIMAGE

Outputs (2)

NameTypeDescription
拼接大图IMAGE
记忆图批次IMAGE