Nodes/LatentPNG/Load LPNG
ComfyUI Node

Load LPNG

The image loader that skips the VAE when it can

By Anze-·Created 7 months ago·Updated 7 months ago· 6
Load LPNG
  • vae
  • IMAGE
  • MASK
  • LATENT
  • info
image

The name undersells this node. It isn't a niche format loader you have to go hunting for - it's a drop-in replacement for the stock Load Image that, when the PNG happens to carry a latent inside it, hands you that latent directly instead of re-encoding your image through a VAE. And when the file has no latent (a normal PNG), it just does the ordinary thing: encodes the pixels with the VAE you plugged in. Swap it into a workflow that doesn't know about LPNG and nothing breaks. That fallback is the whole trick.

Why you'd reach for it

Multi-pass editing. img2img chains, inpainting round-trips, hi-res fix passes, "feed it through three models" experiments - every time you render an image and send it back into the model, the pixels go through VAE decode then VAE encode, and each round trip is lossy. Saturation creeps up, fine texture softens, the picture drifts a little further from what you actually made. That's the "re-baking" problem.

LatentPNG's bet is that you should treat the latent the way a photographer treats a RAW file: keep the model-native representation around so the next pass starts from the state you left it in, not a re-compressed copy. The author's analogy is literally that - LPNG is "RAW for generated images." The Load node is the half of that deal that reads it back.

How it works

A Save LPNG node (same pack) stores the latent as compressed, base64-encoded bytes inside a standard PNG iTXt metadata chunk with the keyword LPNG_LATENT. PNG text chunks are optional by design, so any normal viewer ignores it and just shows the picture - the same mechanism ComfyUI already uses to embed your whole workflow in an image.

On load, Load LPNG looks for that chunk:

  • Found → decompress, reshape to the stored [C, H, W] shape, and output it as a LATENT. No VAE encode, no loss, done.
  • Missing → fall back to vae.encode() on the pixels, with a warning printed to the console ("this should happen only on your first pass").

There are only two inputs you actually set:

  • image - pick from the files sitting in ComfyUI's input folder, or upload one. Standard loader behavior.
  • vae - required even though it's only used on the fallback path. It should be the VAE of whatever model produced the latent.

Outputs are IMAGE, MASK, LATENT, and info. The LATENT is the point: wire it straight into a sampler's latents input and you've skipped VAE Encode entirely. info is a string - "OK, latent image data was found!" versus "No latent data found, using VAE!" - and the README's tip is a good one: put a text preview node on it so you can confirm what path a given file actually took.

The trap nobody warns you about

The latent is model-native. SD1.5 and SDXL latents are 4 channels; Flux and the newer DiT-era VAEs run 16. Load a Flux-saved LPNG and feed it into an SDXL sampler and you'll get noise, flat color, or a hard error - the node stores the shape but never checks which model family the latent came from. The README is blunt about it: "users will make sure the latents are compatible with the model manually." Keep LPNG files and their source model together, and if a downloaded LPNG looks wrong, suspect provenance first.

Also: the README describes checksum and VAE-hash verification, but the shipped code does none of that - it trusts the metadata. Don't treat an LPNG you didn't generate yourself as tamper-proof.

One more gotcha: the chunk dies if the file is re-encoded. Screenshots, JPEG conversion, and image hosts that recompress (Reddit, Discord previews) strip every ancillary chunk. The node then silently falls back to VAE encode - it still loads, it just stops helping.

Install

ComfyUI Manager → Install Custom Nodes → search LatentPNG → install → restart. Or by hand:

cd ComfyUI/custom_nodes
git clone https://github.com/Anze-/LatentPNG

Then restart ComfyUI. No extra Python packages and no model downloads - it only needs what ComfyUI already ships (PyTorch, Pillow, numpy), so there's no dependency hell to wade through. It's a small, honest pack; for anyone doing serious iterative img2img work, the pair of nodes it adds is quietly worth having.

Categoryimage

Inputs (2)

NameTypeDefaultDescription
imageCOMBO1 options: example.png
vaeVAE

Outputs (4)

NameTypeDescription
IMAGEIMAGE
MASKMASK
LATENTLATENT
infoinfo