Donut Histogram Stretch (DEPRECATED)
The auto-levels fix for flat renders
- image
- image
Every diffusion model has a "slightly milky, no true black, no true white" default. DonutHistogramStretch is the node that fixes exactly that: it remaps the image so the darkest pixel becomes 0 and the brightest becomes 1, reclaiming the full dynamic range. It's the auto-levels button from every photo editor ever, wrapped for the graph - and if the model nailed your composition but forgot to give you contrast, this is the $0, millisecond fix that beats re-sampling.
Yes, it's DEPRECATED, same story as its siblings in this pack: the unified DonutImageAdjust node now carries it as the histogram_stretch operation, and this standalone node is kept around (hidden from the menu) so saved workflows keep loading. Same code path either way.
How it works
It's a percentile-based stretch, which is the part most people get wrong with naive auto-levels. You pick where black and white should land:
- black_point (default 0, max 49) - the percentile used for the black end. 0 = absolute darkest pixel. 1+ = "robust," meaning it ignores the stray outlier pixels so a single hot pixel doesn't wreck your contrast.
- white_point (default 100, min 51) - same idea at the bright end; 100 = absolute max, 99- = robust.
mode decides how the stretch is applied:
global- bounds come from luminance, same stretch applied to all RGB. Preserves color ratios; the safe default if you don't care about color.per_channel- each channel stretched independently. Maximum punch, but it can shift colors since it changes the balance between channels.luminance- stretches only the L channel in LAB space, leaving hue and saturation untouched. The author notes this "matches LayerStyle," and it's the one to pick when you want contrast without any color drama.
Output is a single image.
Install
It ships with the ComfyUI-DonutNodes pack:
cd ComfyUI/custom_nodes
git clone https://github.com/DonutsDelivery/ComfyUI-DonutNodes.git donutnodes
cd donutnodes
python -m pip install -r requirements.txt
Or ComfyUI Manager → search "DonutNodes." Then restart.
Using it well
The author's own hint is to pair it with gamma: stretch to maximize dynamic range first, then gamma to place the midtones where you want them. That's a solid two-node recipe for "flat render → finished look" - and both operations live in DonutImageAdjust now, so you can do the whole pass in one node. Start with luminance mode and robust points like 1/99; only drop to per_channel if the result still looks washed out and you're OK babysitting color.
Inputs (4)
| Name | Type | Default | Description |
|---|---|---|---|
| image | IMAGE | — | |
| black_point | FLOAT | 0.00–49 | Percentile for black point (0 = absolute min, 1+ = robust) |
| white_point | FLOAT | 100.051–100 | Percentile for white point (100 = absolute max, 99- = robust) |
| mode | COMBO | luminance | global: bounds from luminance, same stretch to RGB (preserves ratios). per_channel: stretch RGB independently (may shift colors). luminance: LAB L-only (preserves hue/saturation, matches LayerStyle) |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| image | IMAGE | — |