AM OCIO Colorspace
Actually color-manage ComfyUI instead of guessing
- image
- video
- image
- video
If you've ever handed a ComfyUI PNG to a compositor and watched them sigh, this node is the fix. AM OCIO Colorspace applies a real OpenColorIO 2.x transform between any two colorspaces in your active config - the same machinery Nuke, Katana, and every serious VFX pipeline use. It's how you get from "8-bit sRGB-ish tensor in a 0-1 range" to "scene-linear float that a comp can actually work with," and back.
It's part of comfyui-am-vfx-tools ("AM VFX Tools/Color" category), Adrian Meyer's 13-node VFX toolkit. The KB's take on this corner of the ecosystem is blunt and correct: OCIO in r/StableDiffusion is nearly invisible - the people who need it are compositors, not prompters - but the moment AI output has to survive as an element in a color-managed shot next to real footage, you need all of it, because one un-managed decode poisons the comp.
How it works
You pick two colorspaces from a dropdown of 56 choices - everything from Display/sRGB - Display and Display/Gamma 2.2 Rec.709 - Display through ACES/ACES2065-1, ACES/ACEScc, Rec.2100-HLG, and PQ. The node converts input_colorspace → working_colorspace through OpenColorIO's ColorProcessor. The list isn't hardcoded; it's generated from whichever OCIO config is active.
The config hierarchy is the same one the whole pack uses:
$OCIOenvironment variable, if set and resolvable- OCIO 2.5+ built-in Studio config (ACES)
- OCIO 2.5+ built-in CG config
- An identity stub so the nodes still load with no config at all
That means it works out of the box on any ComfyUI install with opencolorio>=2.5.0 - you don't need to source a studio config to get going, and you can point OCIO=/path/to/your.ocio to bring in your shop's real one.
When you reach for it
Three cases, honestly:
- Getting generated output into a comp - sRGB → ACES/ACES2065-1 before writing an EXR.
- Feeding a model with a colorspace assumption - many video models and samplers are trained on log or linear data; this is how you hand them the right thing.
- Just checking your work - convert a linear plate to sRGB to see what a viewer will actually see.
The two inputs are input_colorspace and working_colorspace, plus optional image and video (the video path is lazy per-frame). Outputs: image and video. Alpha passes through untouched either way.
Installing it
cd ComfyUI/custom_nodes
git clone https://github.com/am-pipeline-prod/comfyui-am-vfx-tools.git
cd comfyui-am-vfx-tools
pip install -r requirements.txt
Restart ComfyUI, or search comfyui-am-vfx-tools in ComfyUI Manager. The opencolorio>=2.5.0 dependency - the floor for the built-in Studio/CG configs - comes from that pip line, so don't skip it.
Where people get burned
The dropdown choices depend on the active config, so if your options look different from a tutorial's, you're on a different config - that's expected, not broken. And the classic mistake: applying a display transform and then grading in that display space. The pack's own nodes (AM Grade, AM Color Correct) assume scene-linear with a 0.18 pivot, so the sane chain is: read in → transform to linear working space → grade → transform to display → write. If your grades feel wrong, check which space the OCIO node put you in before you blame the grade.
Inputs (4)
| Name | Type | Default | Description |
|---|---|---|---|
| input_colorspace | COMBO | ACES/ACES2065-1 | Source colorspace — the space the input pixels are in. The OCIO transform converts from this to `working_colorspace`. |
| working_colorspace | COMBO | Display/sRGB - Display | Destination colorspace — the space the output pixels will be in. |
| imageopt | IMAGE | Image batch to transform. | |
| videoopt | VIDEO | Optional VIDEO input. When wired, returns a lazy `OCIOTransformVideo` wrapper applying the OCIO transform per-frame on consumption — no IMAGE materialisation here. Alpha (when present) passes through untouched. `image` is ignored when `video` is wired. See invariant 28. |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| image | IMAGE | Transformed image batch (same shape and channels as the input). |
| video | VIDEO | Lazy VIDEO output — emits an `OCIOTransformVideo` wrapper when `video` is wired, else a zero-copy `VideoFromComponents` around the IMAGE batch. None when no input is wired. |