UV ImageBatch To Latent
Hand real frames to the VAE and get a latent out
- images
- vae
- latent
Video models and img2img workflows don't eat pixels - they eat latents. If you've got real frames and you want them to become conditioning or an image-to-video starting point, something has to sit between the IMAGE tensor and the KSampler and compress each frame through a VAE. That something is UV_ImageBatchToLatent. It's the "latent bridge" the pack's README talks about, and it's the piece that completes the pipeline: UV_LoadVideo gets frames in, this node gets them into latent space, and then you're talking to the sampler.
Mechanically it's nearly a one-liner: take the images batch, feed it through the vae you provide, and return a LATENT. But there are two details that make it worth reading about.
First, the frame batch is sliced to three channels - images[:, :, :, :3] - so any alpha channel is dropped before encoding. That matters if your frames came from a source with an alpha channel: the VAE encodes RGB, and if you need the alpha preserved for a later master export, you're better off splitting it out earlier in the graph. For ordinary RGB sources this is a non-event.
Second, the tiled option. When tiled is on (and your VAE exposes encode_tiled, which the standard ComfyUI VAEs do), it encodes in tiles of tile_size by tile_size, defaulting to 512. This is your tool for big frames: encoding a full 1080p+ batch through a non-tiled VAE encode is a fast way to hit a VRAM wall, and tiling spreads the memory cost out. If you're running short on memory or your resolution exceeds what your card likes, flip tiled on and leave tile_size at 512 unless you have a reason to change it. If it fits in VRAM untiled, leave it off - tiled encoding is slightly lossier at tile seams and measurably slower.
The one input that matters more than all the others is vae. It's a VAE socket, not a string, so you wire in whatever VAE the rest of your workflow uses. The KB's concepts essay hammers this and it's worth repeating: the VAE is what converts between pixel space and the latent space the diffusion model works in, and the encode and decode halves are a matched pair. Encode with one VAE and decode with another and you get noise or flat color, not a subtle mistake. When in doubt, use the same VAE the model checkpoint ships with or was trained on.
What it wires into
The single output, latent, plugs into any node that takes a LATENT - a KSampler for img2img, an image-to-video model's conditioning, or a VAE decode node to round-trip back to pixels. The pack's example workflow is exactly this: UV_LoadVideo → UV_ImageBatchToLatent → sampler.
Install
Nothing exotic - the whole pack installs the same way:
cd ComfyUI/custom_nodes
git clone https://github.com/GeekatplayStudio/ComfyUI-UniversalVideoIO
cd ComfyUI-UniversalVideoIO
pip install -r requirements.txt
Restart ComfyUI. Dependencies are imageio, imageio-ffmpeg, numpy, and torch - all either already present in a ComfyUI install or trivial. No model files to fetch; the VAE is yours, pulled from wherever you already load it. If your first run throws a "Cannot handle this data type" style error at the decode side, that's a VAE mismatch downstream, not this node - check which VAE you wired in.
Inputs (4)
| Name | Type | Default | Description |
|---|---|---|---|
| images | IMAGE | — | |
| vae | VAE | — | |
| tiled | BOOLEAN | false | — |
| tile_size | INT | 51264–2048 | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| latent | LATENT | — |