Nodes/ComfyUI-JH-PixelPro/Color: Apply ColorLab Preset
ComfyUI Node

Color: Apply ColorLab Preset

Grade One Frame, Apply It to Four Hundred Photos

By jetthuangai·Created 6 months ago·Updated a day ago· 6
Color: Apply ColorLab Preset
  • image
  • mask
  • image
  • params_json
◄params_json—►
◄strength1.00►

If you've ever built a grade in ComfyUI you know the pain: twenty widgets on one node, and the only way to reuse them is to duplicate the node and hope you didn't miss a slider. Lightroom solved this in 2007 with presets and an Amount slider. Color: Apply ColorLab Preset (JHPixelProColorLabApply) is that idea, wired as a node.

You grade one hero frame in ColorLab. Its params_json output is the preset. Feed that into this node and every image you pass through gets the same look, with one strength slider standing in for Lightroom's Amount.

The mechanism

params_json is read using the same rules as ColorLab's own params_json input, starting from neutral. Every numeric amount is multiplied by strength - exposure, contrast, HSL, grading saturation, all of it shrinks or grows together. Then the scaled settings run through the full ColorLab pipeline (tone_engine = local, edge-aware tone tools, exposure in linear light). With a mask, the result is original + (graded − original) × mask.

Two things deliberately don't scale, and this is the part that makes it behave like a real preset rather than a global opacity:

  • Grading hues stay put. A teal shadow stays teal at 0.3 - only its strength changes. Scaling hue would be nonsense.
  • Shape settings don't shrink. Vignette midpoint/feather/roundness and grain size/roughness hold; their amounts scale.

Point curves move toward a straight line as strength drops. A black-and-white preset fades in rather than snapping: below strength 1 the B&W result is blended over the colour one, so 0.5 keeps about half the colour.

Inputs and outputs

image - a photo or a whole batch. params_json - connection only, from a ColorLab, a Lightroom Preset node, or a text node holding a saved preset. Invalid JSON stops the run with an error; unknown setting names are warned about and ignored. strength (0–2, default 1.0) - 0 returns the original unchanged, above 1 exaggerates. 0.5–0.8 for subtle, 1.2–1.5 to rescue a weak preset. mask (optional) - applies the preset only where the mask is white, soft edges where grey. Must match the image's height and width, or the node raises.

Out comes image and a second params_json describing the preset at the chosen strength - which is genuinely useful: apply at 0.5, then feed that back into ColorLab's params_json input and your sliders now start from the halved version instead of the original.

The workflow this enables

Grade the most typical frame in a series. Run the rest through this node. That's the whole batch-consistency speech from every colour-grading tutorial, minus the hand labour. Then check your darkest and brightest frames, because a preset built on a well-exposed image reads heavy on a dark one - lower strength for those instead of rebuilding anything.

The other use: params_json from Auto Tone goes straight in here. Auto Tone measure-and-corrects one photo, you reuse those exact settings on the shoot. It's the difference between "each photo got auto-corrected" and "the shoot has one look".

Install

cd ComfyUI/custom_nodes
git clone https://github.com/jetthuangai/ComfyUI-JH-PixelPro.git
cd ComfyUI-JH-PixelPro
pip install -r requirements.txt   # the Python that runs ComfyUI

Or via ComfyUI Manager: search ComfyUI-JH-PixelPro → Install → restart. Find it at Add Node → ComfyUI-JH-PixelPro → color. Dependencies are kornia>=0.7, mediapipe>=0.10.33, opencv-python-headless>=4.8, scipy>=1.10, with PyTorch supplied by ComfyUI. No model downloads, no onnxruntime needed.

The traps

  • Don't stack it after a ColorLab. Feed this node the original, not an already-graded image, or the look doubles.
  • A mask of the wrong size is a hard error, not a silently reshaped one. Worth knowing before you queue a 40-image batch overnight.
  • Sanity-check the shadows. The single most common complaint about any preset pipeline is "it crushed my blacks" - that's strength being tuned on a bright frame.
  • Already have the look as a .cube? Use LUT Import instead; it also has strength and mask, and it doesn't route through ColorLab's parameter model.

For context on why this class of node matters at all: colour work is the deterministic layer under the generative one, and the reason to know which primitive does which job is so you don't re-roll a generation because the grade is off. A statistics or parameter transfer is instant and repeatable; a re-gen is a lottery. This node is the parameter-transfer version for looks you built by hand.

The pack is Apache-2.0, maintained by JH (@jetthuangai), currently 1.10.0 with 64 nodes. There's no Reddit folklore on it - the pack name returns one unrelated browser extension in the corpus - so the bundled docs, which have a before/after image and a settings table per node, are your best reference.

CategoryComfyUI-JH-PixelPro/color

Inputs (4)

NameTypeDefaultDescription
imageIMAGEImage to grade.
params_jsonSTRINGPreset from a ColorLab or Lightroom Preset node.
strengthFLOAT1.000–2Scales every amount (grading hues are kept). 0 = original.
maskoptMASKOptional mask limiting where the preset applies.

Outputs (2)

NameTypeDescription
imageIMAGEImage with the preset applied.
params_jsonSTRINGThe preset at the chosen strength.