ComfyUI Node

Curves

The tone-curve editor that finally feels like Lightroom, minus the subscription

By criskb·Created 7 months ago·Updated 5 months ago· 0
Curves
  • image
  • mask
  • image
  • mask
  • curves_info
settings_json{"master_shadows":0.0,"master_midtones":0.0,"master_highlights":0.0,"red_curve":0.0,"green_curve":0.0,"blue_curve":0.0,"contrast":1.0,"mix":1.0,"mask_feather":12.0,"invert_mask":false}

x1Curves is the color node that makes ComfyUI feel less like a science experiment and more like a grading suite. It gives you a proper tone curve - lift shadows, pull highlights, warm the red channel independently - and it does it through an actual curve editor UI instead of a wall of sliders. If you've been reaching for gamma nodes and wishing they'd just behave like Photoshop's Curves tool, this is that.

It's one node in the big MKRShift Nodes pack by Cris K B, a single-install "everything for image craft and finishing" collection. This one lives under MKRShift Nodes/Color/Grade and it's the pack's everyday grade tool, sitting naturally right before a save or after a VAE decode.

How it works

Under the hood it's a classic tone-mapping pass over luma plus per-channel curves. You get three master controls - master_shadows, master_midtones, master_highlights - which push or pull (-1 to +1) the dark, mid, and bright ranges, and then three channel curves - red_curve, green_curve, blue_curve - for exactly the tint separation that's painful to fake with a saturation slider. A single contrast (0.3–2.5) handles the S-curve. The curve is applied per-pixel on the 0-1 float image, so nothing about it is model-based or hallucinated; it's just a fast, well-behaved curve.

The wrinkle: the node takes one settings_json string input, not a row of sliders. That's the full config in a JSON blob, defaulting to something like {"master_shadows":0.0,"master_midtones":0.0,"master_highlights":0.0,"red_curve":0.0,"green_curve":0.0,"blue_curve":0.0,"contrast":1.0,"mix":1.0,"mask_feather":12.0,"invert_mask":false}. You can edit that JSON directly, but the pack ships a custom frontend (colorCurvesPhysical.js) so in practice you get a click-and-drag curve widget. If the widget isn't showing for you, editing the JSON works fine - and if you feed malformed JSON, the node quietly falls back to defaults instead of exploding, which is friendlier than it sounds.

The inputs that matter

The only required inputs are image and settings_json. The ones you'll actually touch inside the JSON:

  • master_shadows / master_midtones / master_highlights - the classic three-point lift/pull.
  • red_curve / green_curve / blue_curve - channel tints, e.g. +warm in the reds.
  • contrast - the global S-curve; 1.0 is neutral.

There's also an optional mask input, plus mask_feather and invert_mask in the JSON, so you can grade only part of the frame. The node outputs image, a mask (the actual applied region, useful if you want to reuse it), and a curves_info string that summarizes what ran - wire that to a text preview node if you like to see the settings echoed back.

Installing it

It ships inside MKRShift Nodes, so:

cd ComfyUI/custom_nodes
git clone https://github.com/criskb/MKRShift_Nodes

Then restart ComfyUI. Or skip the terminal and search MKRShift_Nodes in ComfyUI Manager. Good news for once: the pack has no requirements.txt, so no pip downloads, no model files, no API keys. These are pure numpy/PIL/torch image operations. (The pack as a whole mentions installing ffmpeg for its video/audio nodes, but nothing in this node needs it.)

Gotchas

Because everything is one JSON blob, the classic mistake is editing settings_json and accidentally breaking the JSON - a missing comma and your curve silently resets to default. Copy the default string first and edit in place. And remember every value gets clamped to its min/max in the source, so don't bother typing contrast: 99 expecting a cliff. It's cheap, instant, and one of the few nodes in this pack I'd describe as a daily driver.

CategoryMKRShift Nodes/Color/Grade

Inputs (3)

NameTypeDefaultDescription
imageIMAGE
settings_jsonSTRING{"master_shadows":0.0,"master_midtones":0.0,"master_highlights":0.0,"red_curve":0.0,"green_curve":0.0,"blue_curve":0.0,"contrast":1.0,"mix":1.0,"mask_feather":12.0,"invert_mask":false}
maskoptMASK

Outputs (3)

NameTypeDescription
imageIMAGE
maskMASK
curves_infoSTRING