Color: Shadows/Highlights Pro
Camera Raw's Two Best Sliders, Without Opening Lightroom
- image
- mask
- image
There's a specific kind of bad image that comes out of every AI generation pipeline: the light is right, the composition is right, and the tonal range is too wide. A face in shade against a bright sky. A dark jacket with no detail in it. A window that's a white rectangle. The fix in any editor is the same two sliders, and now they're nodes.
Color: Shadows/Highlights Pro (JHPixelProShadowsHighlights) lifts what's dark relative to its surroundings and pulls back what's bright, without flattening the image into that grey, cheap-HDR look.
Why this isn't just a curve
The reason people reach for curves and get a flat result is that a curve moves every pixel with the same value the same amount. It has no idea that a mid-grey pixel is a lit wall or a shadowed cheek - it just sees 0.45 and multiplies it.
Shadows/highlights is local: it looks at each area's neighbourhood and asks whether this pixel is darker or brighter than what's around it. Lift the ones that are darker, recover the ones that are brighter, keep local contrast. That's the difference between "the shadows opened up" and "everything turned to milk".
It also sits in a specific spot in a sane finish order. Global tonal work first (exposure, white balance), then local tone (this), then local contrast if you need punch back, then sharpen, then grain. If you find yourself doing colour correction with img2img, this is the deterministic, millisecond, zero-seed-lottery alternative - the boring primitive that does the job better.
Two models in one node
mode chooses which maths you get, and they are not equivalent:
camera_raw (the default) is the Lightroom/Camera Raw slider model: a fast local Laplacian filter on log2 luminance, run on a proxy and carried back to full resolution, applied as a gain on linear RGB. Two things follow. Hue is preserved because only brightness moves, and hard edges stay halo-free. Both shadows and highlights work in both directions here.
photoshop follows Image → Adjustments → Shadows/Highlights, with its Tone, Radius, Color and Midtone controls exposed as ps_shadow_tone, ps_shadow_radius, ps_highlight_tone, ps_highlight_radius, ps_color and ps_midtone. Like the real dialog, it can only lift shadows and darken highlights - negative shadows and positive highlights do nothing, and with shadows at 0 or below and highlights at 0 or above the image passes through untouched, so ps_color and ps_midtone alone have no effect. That trips people up. It's a faithful imitation of a dialog with an asymmetric model, not a bug.
Start in camera_raw. Go to photoshop when you want the dialog's specific character (crunchier, more local, radius-driven), not because it's better.
The inputs
shadows (default 30) and highlights (default −30) are the two you'll touch. 20 to 50 of shadow lift covers most portraits; −20 to −60 of highlight recovery covers most skies and skin shine. Beyond that you're into rescue territory and should expect to add contrast back afterwards.
The optional mask limits where the effect applies, must match the image size, and a one-image mask broadcasts across the batch. Masking the subject on a backlit portrait is the single best use of it - you lift the face and leave the bright background airy. A luminosity mask works too if you want tone-driven rather than subject-driven.
One output: image, same size as the input, and with both sliders at 0 it's the input unchanged.
Install
Manager: search ComfyUI-JH-PixelPro, install, restart. Manual:
cd ComfyUI/custom_nodes
git clone https://github.com/jetthuangai/ComfyUI-JH-PixelPro.git
cd ComfyUI-JH-PixelPro
pip install -r requirements.txt
Restart, then Add Node → ComfyUI-JH-PixelPro → color. Pack deps: Python 3.10+, kornia>=0.7, MediaPipe, OpenCV headless, SciPy. No models, nothing to download, and no prompting - the whole pack is 64 deterministic retouch nodes, Apache-2.0, one maintainer.
Common issues
The whole image got darker when I recovered highlights. Documented behaviour in camera_raw: the darkest content is pinned, so extra highlight recovery pulls the overall level down slightly, exactly as Camera Raw does. Add a touch of exposure after with the pack's ColorLab node if it bothers you.
Nothing happens in photoshop mode. See above - you're using the signs the dialog can't do. Flip them.
It looks flat and grey. Too strong a lift. The recovery move is local contrast (CLAHE, or a gentle S-curve) afterwards; the other move is to mask the effect so only the subject gets lifted.
Speed. Roughly 0.1 s per 4K image on a warmed-up CUDA card, under 1 GB peak VRAM - but about 14 s on CPU. If you're CPU-only and batching, drop resolution before you drop the node.
It's slow on a huge image. The local Laplacian runs on a proxy capped at 1600 px on the long edge and is guided back up, so cost shouldn't scale linearly with resolution - but the guided upsample and the linear-RGB round trip still cost. If you're at 8K, work at output size.
The honest caveat about the pack: there's no community discussion of it anywhere I can find, so nobody's published a "my favourite settings" thread. What there is instead: measured comparison against Photoshop's own Camera Raw numbers in the docs (Shadows +100 → 165.2 of 255 against a published 165.3), which is a more useful kind of claim than a stranger's slider preference.
Inputs (11)
| Name | Type | Default | Description |
|---|---|---|---|
| image | IMAGE | Input image (B,H,W,3). | |
| shadows | FLOAT | 30-100–100 | Positive lifts dark areas relative to their surroundings. |
| highlights | FLOAT | -30-100–100 | Negative recovers bright areas (skies, windows, skin shine). |
| mode | COMBO | camera_raw | camera_raw = Lightroom/Camera Raw sliders (no halos). photoshop = Image > Adjustments > Shadows/Highlights; only lifting shadows and darkening highlights. |
| maskopt | MASK | Optional mask limiting where the effect applies. | |
| ps_shadow_toneopt | FLOAT | 500–100 | Photoshop mode. Tonal width of the shadows (%). |
| ps_shadow_radiusopt | FLOAT | 300–2500 | Photoshop mode. Shadows neighbourhood (px). |
| ps_highlight_toneopt | FLOAT | 500–100 | Photoshop mode. Tonal width of the highlights (%). |
| ps_highlight_radiusopt | FLOAT | 300–2500 | Photoshop mode. Highlights neighbourhood (px). |
| ps_coloropt | FLOAT | 20-100–100 | Photoshop mode. Saturation in the adjusted tones. |
| ps_midtoneopt | FLOAT | 0-100–100 | Photoshop mode. Midtone contrast. |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| image | IMAGE | — |