Skip to content

fix(modifiers): pivot the contrast adjustment on mid grey - #133

Merged
olivervogel merged 1 commit into
Intervention:developfrom
nlemoine:fix/contrast-pivot
Oct 8, 2026
Merged

olivervogel merged 1 commit into
Intervention:developfrom
nlemoine:fix/contrast-pivot

Conversation

@nlemoine

@nlemoine nlemoine commented Oct 8, 2026

Copy link
Copy Markdown
Contributor

ContrastModifier calls linear($a, $b) with $b = 255 * (1 - $a). That keeps white fixed, so a positive level darkens every tone below it instead of spreading them around mid grey. Measured on a flat grey image, contrast(50), red channel:

input   gd    imagick   vips (develop)   vips (branch)
80      20    22        0                56
128     128   129       64               128
175     234   233       135              198

The offset is now computed from mid grey. Mid grey depends on the interpretation of the image, the same ranges RotateModifier uses: 65535 for RGB16/GREY16, 1 for scRGB, 255 otherwise. Without that a 16-bit source would pivot near black.

The existing testApply expected the darker color, so its value changes (0095eb to 00bbff). New tests cover positive and negative levels, with and without alpha, and a 16-bit source.

The effect is still weaker than GD and Imagick (175 goes to 198, not ~234). GD squares the factor and Imagick uses a sigmoid, I did not try to match either one. Happy to change it if you prefer one of them.

The linear() call used 255 * (1 - a) as offset, which keeps white
fixed and makes a positive level darken every tone below it. A light
grey of 175 went down to 135 at level 50, where GD and Imagick push it
up to about 234.

Pivot on mid grey instead, on the value range that goes with the
interpretation of the image, so 16-bit and scRGB sources get the same
behavior as 8-bit ones.
@olivervogel

Copy link
Copy Markdown
Member

Thanks.

@olivervogel
olivervogel merged commit 5d475d6 into Intervention:develop Oct 8, 2026
8 checks passed
@nlemoine
nlemoine deleted the fix/contrast-pivot branch October 8, 2026 12:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants