Classic black / midtones / white levels: set the black and white points, then bend the midtones with a PixInsight-style Midtones Transfer Function. Live curve, histogram overlay, per-channel, and mask-aware.
Drag the three handles on the curve (or use the sliders/spin-boxes), watch the preview and the original-vs-result histogram, then Apply. The curve's black and white handles carry the midtone proportionally, so narrowing the range doesn't jump the midpoint.
| Control | What it does |
|---|---|
| Channel | L (luminance, chroma preserved), K (brightness — same curve on R, G, B), or a single R/G/B. Mono images are locked to L. |
| Black point | Input level mapped to 0. Everything at or below it is clipped to black. |
| Midtones | The input level pulled to mid-grey (0.5) — the gamma-like bend between black and white. |
| White point | Input level mapped to 1. Everything at or above it is clipped to white. |
| Live preview | Recompute the preview on every change (debounced). |
| Curve + histogram | Draggable B/M/W handles; the histogram shows original (dim) vs result (bright) for R/G/B and luminance. |
| Apply / Apply as New / Reset | Write to the document, open the result as a new view, or return the handles to 0 / 0.5 / 1. |
| Grip (bottom-left) | Drag to the canvas to mint a Levels shortcut, or drop on an image to apply headlessly. |
The clip readout reports, for the selected channel, how many pixels the current black/white points drive to pure black or white; a min/max readout shows the data's actual range.
Two stages per channel: a linear black/white rescale, then a non-linear midtones transfer. Everything operates on float data in [0,1].
The black point b and white point w linearly remap
and clip the input:
The rescaled value is bent by the PixInsight Midtones Transfer Function with a
single midtone parameter m:
It is pinned at the ends and sends the midtone to mid-grey:
The Midtones handle is an absolute input level; it is converted to the MTF parameter relative to the black/white window before the curve is evaluated, so the midpoint stays meaningful as you move the end points:
This is the same midtones transfer that Statistical Stretch uses — here you place black/mid/white by hand (midtone → 0.5), whereas Statistical Stretch solves the midtone analytically to land a target median.
For the selected channel's values v (L and K use the luminance
proxy), the readout counts what the current end points clip:
If the document has an active mask, the transform is blended back against the original over the mask (and the mask is resized to match — downsampled for the preview, full-res on apply, so what you see matches what you get):