LC Aspect Ratio Pipe (In/Edit)
LC Aspect Ratio Pipe (In/Edit)
- pipe
- image
- mask
- latent
- pipe
Every pack that grows past thirty nodes eventually invents a pipe. rgthree has Context, Efficiency Nodes had its dependency tuples, Easy-Use threads a pipe dict - the idea is always the same, and it's the single most useful pattern in ComfyUI's plumbing layer: instead of dragging twelve wires across the canvas, you bundle the values that travel together into one object and let each node pull off what it needs. LC123's flavour is LC_PIPE, and LC Aspect Ratio Pipe (In/Edit) is the packing end. Image, mask, width, height, latent, batch size and resolution go in; one wire comes out.
Why you'd reach for it
You already have the values - you just have to keep rebuilding the trio of image + size + latent every time you resize upstream of a sampler. Or you want the size that actually went into the latent available four nodes later, where a filename token or a metadata node needs it. Either way the pipe turns six wires into one and, more importantly, gives width and height a single authoritative source instead of six chances to disagree.
How it works
The pipe is a plain Python dict tagged _type: "LC_PIPE". The node's whole job is this: if you feed it an existing pipe on the optional pipe socket, it copies that dict and overwrites the keys you actually wired. If you don't feed it one, it starts a fresh dict and fills it from the sockets. Since ComfyUI simply doesn't pass an optional input you left unconnected, "wired" and "not wired" is exactly the line between overwrite and pass through. Nothing is cleared, nothing is merged by guesswork.
One detail worth knowing before you hunt for a number box: width, height, batch and resolution are declared as forced inputs, so on this node they only exist as sockets - you wire them, you can't type them. resolution is the pack's shorthand for the longer side (the bigger of width and height). If you wire width and/or height but leave resolution empty, it fills itself in as max(width, height), which is what you almost always want.
The sockets that matter
Of the eight optional inputs, beginners need four:
- image and mask - overwrite the pipe's copies when wired. This is how you get a resized image and its matching mask onto the same wire.
- width / height - the number everything downstream sizes itself from.
- pipe - only if you're editing. Wire an upstream pipe here and this node becomes a filter rather than a source.
latent and batch are for the case where you're carrying the empty latent that matches your size. Skip them if you're not.
The output is a single pipe. It fans out to the unpacker side of the pair - class LCAspectRatioPipe, which is the node displayed as LC Aspect Ratio Pipe Out - and to anything else in the pack that reads an LC_PIPE, including the metadata node and the MiniMax H3 pipe.
Naming catches people out, so: the class LCAspectRatioPipeIn shows up in search as LC Aspect Ratio Pipe (In/Edit), and the older class LCAspectRatioPipe shows as LC Aspect Ratio Pipe Out. Older workflows that contain a node literally called "Pipe (In/Edit)" are loading the unpacker - the class key predates this node and always meant the out end. If your graph has one and it's spitting out six sockets, that's why.
Installing it
The whole pack installs in one step, and there is no requirements.txt - the repo has no pip step at all, only what ComfyUI already ships (torch, numpy, Pillow).
cd ComfyUI/custom_nodes
git clone https://github.com/lonecatone23/ComfyUI_LC123_nodes.git
ComfyUI Manager also has it: search ComfyUI LC123 Nodes. Then restart. On boot the console prints [LC123] loading from … and a [LC123] total N nodes: [...] line, one + module row per file.
Common issues
The nested-folder trap. If you grabbed the zip and it unpacked into ComfyUI_LC123_nodes/ComfyUI_LC123_nodes/, __init__.py is one level too deep and nothing registers. The pack actually detects this and prints a warning naming the ignored path. Move the inner files up one level and restart.
An empty pipe is a valid pipe. Wire nothing and the node happily returns {_type: "LC_PIPE"}. Downstream, the unpacker reads a missing width as 0 and computes resolution as max(0, 0). A 0-wide latent will blow up somewhere far away from here, which is a miserable way to find out you forgot to wire the size.
Partial edits are silent by design. If you wire image but not width, the width that comes out is the one on the incoming pipe - not "unchanged", but inherited. When something downstream is the wrong size, check whether the width you're looking at came from an upstream pipe assembled before your resize. That's the generic failure mode of every context bus: with forty wires you can see the bad connection, with one wire the connection is fine and the contents are stale.
Inputs (8)
| Name | Type | Default | Description |
|---|---|---|---|
| pipeopt | LC_PIPE | Existing LC_PIPE to edit (optional). Every other key on it passes through. | |
| imageopt | IMAGE | image. Overwrites the pipe's image when wired. | |
| maskopt | MASK | mask. Overwrites the pipe's mask when wired. | |
| widthopt | INT | 00–4294967295 | width. Overwrites the pipe's width when wired. |
| heightopt | INT | 00–4294967295 | height. Overwrites the pipe's height when wired. |
| latentopt | LATENT | latent. Overwrites the pipe's latent when wired. | |
| batchopt | INT | 00–4294967295 | batch. Overwrites the pipe's batch when wired. |
| resolutionopt | INT | 00–4294967295 | resolution. Overwrites the pipe's resolution when wired. |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| pipe | LC_PIPE | — |