🖥️ NL Preview
The viewer that shows you the truth about your colors
- image
- mask
- comparison_images
- image
- mask
- image_info_json
For 95% of ComfyUI users, the stock PreviewImage is fine. You generate, you squint, you move on. Then you hit the situation where what's on your monitor is a lie. You're working in a color-managed pipeline - the tensor is in ACEScg working space, linear-ish, and your screen wants Rec.709 - and the default viewer shows you washed-out garbage that doesn't match what your save node writes. NL Preview is the pack's answer to that: a managed viewer that understands color metadata instead of pretending every IMAGE tensor is already sRGB.
It comes from ComfyUI-NL_Nodes, a studio-built pack (think Nuke-style node names, ACEScg, OCIO configs, ShotGrid integration - this is VFX-post DNA). It's built around a color-managed IO foundation where NL Read stamps each image with serialized color metadata, and everything downstream can honor it. NL Preview is the display side of that story.
How it works
Feed it any IMAGE tensor and it previews it, but with two color controls that matter. input_colorspace tells it how to interpret what it's getting - leave it on auto and it resolves the colorspace from NL Read's image_info_json; feed it a bare KSampler output with no metadata and it assumes ACEScg. preview_colorspace is the display-only OCIO View target (default Output - Rec.709). Here's the design point people trip over: preview_colorspace only affects what you see. The image output passes through untouched, so your downstream save still gets the working-space tensor. It's a viewer that doesn't lie to the pipeline.
preview_mode picks what you're looking at: color, color+mask, mask, rgba, comparison, or comparison reveal. The mask and rgba modes need the mask input; comparison modes need a second comparison_images input and give you an A/B (with a reveal interaction in the reveal variant). Handy when you're grading - the pack's NL Grade or a Nuke-style workflow - and you want to check your matte against your plate.
Inputs that matter
preview_mode- what you're viewing,colorby defaultinput_colorspace-autoresolves fromimage_info_json, otherwise assumes ACEScgpreview_colorspace- the display View,Output - Rec.709default
Optionals: image, mask, comparison_images, and image_info_json (the serialized color metadata from NL Read). Outputs are image, mask, and image_info_json - so it doubles as a passthrough: you can drop it inline, keep your metadata flowing, and still see what you're doing.
Installing it
Easiest via ComfyUI Manager - search "ComfyUI-NL_Nodes". Or by hand:
cd ComfyUI/custom_nodes
git clone https://github.com/NOLABEL-VFX/ComfyUI-NL_Nodes
# restart ComfyUI
Base deps (numpy, Pillow, PyYAML, imageio) are already in ComfyUI. But the color magic isn't free - it needs the optional color stack:
cd ComfyUI/custom_nodes/ComfyUI-NL_Nodes
pip install -r requirements-color.txt # opencolorio + OpenEXR
Without PyOpenColorIO installed, the managed preview degrades hard. ffmpeg on your system is also worth having if you preview video sequences.
Where people get burned
- Expecting NL Preview to convert the image. It doesn't - display only. If you want an actual colorspace conversion, that's NL OCIO Convert or NL Preview Transform's job.
autoinput colorspace only works if there's metadata to read. Feeding it a raw IMAGE from a VAE decode with noimage_info_jsonmeans ACEScg is assumed, and if your tensor is actually sRGB you'll wonder why everything looks flat.- Comparing modes silently show nothing if you haven't wired
comparison_images.
It's not a node you strictly need - it's a node you reach for when "good enough" previews stop being good enough.
Inputs (7)
| Name | Type | Default | Description |
|---|---|---|---|
| preview_mode | COMBO | color | Viewer mode for the managed preview. |
| input_colorspace | STRING | auto | Incoming image colorspace. Auto resolves from image_info_json, otherwise assumes ACEScg. |
| preview_colorspace | COMBO | Output - Rec.709 | Display-only OCIO View target. |
| imageopt | IMAGE | Primary image or image-sequence input. | |
| maskopt | MASK | Optional mask used for mask and RGBA preview. | |
| comparison_imagesopt | IMAGE | Optional comparison image or sequence. | |
| image_info_jsonopt | STRING | Optional serialized color metadata from NL Read. |
Outputs (3)
| Name | Type | Description |
|---|---|---|
| image | IMAGE | — |
| mask | MASK | — |
| image_info_json | STRING | — |