Nodes/ComfyUI-Darkroom/Color Space Transform
ComfyUI Node

Color Space Transform

The missing color-management layer in ComfyUI

By jeremieLouvaert·Created 5 months ago·Updated 2 days ago· 101
Color Space Transform
  • image
  • image
source_spacesRGB
target_spaceACEScg
gamut_clipClip
strength1.00

Here's a ComfyUI gap most people never notice because they never leave sRGB: the tool has no built-in way to move between color spaces. You can't convert to linear light, you can't step into ACEScg, you can't hand an image off to anything that expects Rec.2020. Color Space Transform is the pack's answer - a real color-management node that converts between six working spaces, and the only ACES-aware color management in ComfyUI, per the author's own claim.

The spaces

The source_space and target_space dropdowns each offer the same six options:

  • sRGB - the default display space. Where most ComfyUI images live.
  • Linear sRGB - sRGB with the gamma removed. This is where the whole Darkroom pack does its processing internally.
  • ACEScg - the Academy's wide-gamut working space, the standard for film/VFX pipelines. Linear and huge.
  • ACEScct - the log-encoded ACES space (the "cct" is the log curve), used for grading in log.
  • Rec.2020 - the broadcast/video wide-gamut space.
  • DCI-P3 - the digital cinema projector space.

Set source_space to where your image currently is, target_space to where you need it, and the node does the matrix math in between.

Why you'd actually use it

The practical case is HDR and film-pipeline work. The typical chain in the Darkroom world:

  1. Take an sRGB render and transform to Linear sRGB (or ACEScg).
  2. Do exposure and grading in linear light, where the math is physically correct.
  3. ACES Tonemap compresses the result back into a displayable range.
  4. Optionally transform back to sRGB for output.

Without this node that chain is impossible - you'd be tonemapping already-gamma-encoded pixels and getting washed-out doubles of everything. It also pairs with RAW Load, which can output linear-scene data that needs a transform on its way to the display.

The controls that matter

  • source_space / target_space - the two ends. Get source_space right; feeding the wrong source is the #1 mistake and it silently double-converts every color.
  • gamut_clip - what to do with values that fall outside the target gamut. Clip hard-clamps to [0,1]. Soft Compress gently rolls values off as they approach the boundary - the better-looking option for wide-gamut → sRGB moves, since it preserves highlight detail instead of shearing it.
  • strength - the universal blend, so you can fade a transform in if you want to get weird with it. (Usually you want this at 1.0.)

Output is a single image. And yes, it's a per-pixel color transform, so it's on the README's allowed list for LUT bake chains - you can bake a space conversion into a .cube if you ever need a LUT that starts in one space and ends in another.

Gotcha

This node is a matrix transform, not a tonemapper. If you convert an HDR image into sRGB, values above 1.0 will clip hard (or soft-compress, if you chose that). That's not a bug - it's what out-of-gamut means. The correct flow is transform to a working space, grade, tonemap, then transform the result back. Skip the tonemap and you're just clipping.

Installing it

Part of the full ComfyUI-Darkroom pack:

cd ComfyUI/custom_nodes
git clone https://github.com/jeremieLouvaert/ComfyUI-Darkroom.git
pip install -r ComfyUI-Darkroom/requirements.txt

Or search "Darkroom" in ComfyUI Manager. Needs scipy, opensimplex, rawpy, exifread, Pillow. Restart and it's under AKURATE/Darkroom/Pipeline. No GPU, no model downloads, no API costs - just matrix math.

If you never leave sRGB, you may never need this node. The day you want a real film pipeline, HDR handling, or anything ACES, it's the foundation everything else sits on.

CategoryAKURATE/Darkroom/Pipeline

Inputs (5)

NameTypeDefaultDescription
imageIMAGE
source_spaceCOMBOsRGBColor space of the input image
target_spaceCOMBOACEScgColor space for the output image
gamut_clipoptCOMBOClipHow to handle out-of-gamut values. Clip = hard clamp to [0,1]. Soft Compress = gently roll off values approaching gamut boundary
strengthoptFLOAT1.000–1Blend between original (0) and transformed (1)

Outputs (1)

NameTypeDescription
imageIMAGE