Levels (HSL)
The Photoshop-style lightness curve, minus Photoshop
- image
- mask_opt
- image
Every image editor has a Levels tool, and Photoshop users reflexively reach for it when an image has crushed shadows, blown highlights, or a flat middle. Levels (HSL) is that tool inside ComfyUI, operating on the lightness channel of an HSL conversion. It's the most "editor-like" node in the Basix Image Filters pack - instead of one knob, you get three (shadows, midtones, highlights), which gives you the control the one-knob darken/lighten nodes don't have. If your render is "almost right but the whole tonal range needs massaging," this is where you land.
How it works
The node converts the image to HSL, then runs the lightness channel through a classic three-step levels pipeline. First, any lightness below shadows is clipped to black. Then the remaining range is rescaled and a gamma curve (the midtones value) is applied to the middle of the range. Finally, anything above highlights is clipped to white. The result converts back to RGB. Note the gamma direction, which trips up everyone once: midtones above 1 darken the midtones, values below 1 lighten them (it's pow(brightness, gamma), and raising a number between 0 and 1 to a power >1 pulls it down). The README says "above 2 darkens, below 1 lightens" - same idea, one knob.
The inputs that matter
Four, plus the pack's standard pair:
shadows(default 0, range 0–1) - lightness below this gets crushed to black. Raising it from 0 deepens the dark end.midtones(default 1, range 0–100) - the gamma curve. 1 is neutral; below 1 lifts the mids; above 1 (way above, if you like) sinks them.highlights(default 1, range 0–1) - lightness above this clips to white. Dropping it recovers detail in blown areas.masked_area+ optionalmask_opt- the pack-wide mask system.
Output is a single image tensor. Everything is applied to lightness only, so hue and saturation survive the trip - a real advantage over RGB-channel levels when you're grading tone without shifting color.
What to watch for
The midtones range goes to 100, which looks absurd next to shadows' 0–1. That's just the raw gamma range; for normal work you'll live between roughly 0.5 and 2.5, and the wide ceiling only exists so you can do dramatic crushed looks. Also note the in-UI description is generic (it parrots "0.0 = black, 1.0 = original" language that doesn't really fit a three-knob node) - ignore it and use the three sliders empirically. Test on one image; it's instant.
Installing it
ComfyUI Manager → search "Basix Image Filters" (repo basix_image_filters) → install → restart. Or manually:
cd ComfyUI/custom_nodes
git clone https://github.com/maludwig/basix_image_filters
Restart, done. No models, no dependencies beyond stock torch - the whole pack is lightweight by design.
The workflow it's built for
The README's example is a dark green landscape that needs to stay green and stormy. Because this node edits HSL lightness and nothing else, you can darken the whole scene without shifting its palette - exactly the kind of "hint" that works beautifully fed back through an img2img pass at 0.7–0.9 denoise, or applied surgically via mask_opt when only the grass (not the sky) needs crushing.
Inputs (6)
| Name | Type | Default | Description |
|---|---|---|---|
| image | IMAGE | — | |
| masked_area | BOOLEAN | true | — |
| shadows | FLOAT | 0.00–1 | — |
| midtones | FLOAT | 1.00–100 | — |
| highlights | FLOAT | 1.00–1 | — |
| mask_optopt | MASK | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| image | IMAGE | — |