sharkdp / pastel

A command-line tool to generate, analyze, convert and manipulate colors
Apache License 2.0
5k stars 97 forks source link

Setting lab lightness value does not work as expected? #108

Open JuanPotato opened 4 years ago

JuanPotato commented 4 years ago

I would expect pastel set lightness 100 to set a color's lab lightness to 100. The code does seem to try and set lab.l = value but it doesn't actually result in a lab lightness value of 100. Which seemed odd.

 % pastel format lab orange
Lab(75, 24, 79)
 % pastel set lightness 100 orange | pastel format lab
Lab(92, -8, 68)

I have no idea if this is an issue with converting between colorspaces or just unavoidable.

At 149, the lab lightness value seems to be shown as 100, but it isn't pure white.

 % pastel set lightness 149 orange | pastel format lab
Lab(100, -3, 9)

At 156, it finally reaches pure white.

 % pastel set lightness 156 orange | pastel format lab
Lab(100, 0, -0)

You can keep try setting it to 100 lightness and it will increase slightly which is odd

 % pastel set lightness 100 orange | pastel format lab
Lab(92, -8, 68)
 % pastel set lightness 100 orange | pastel set lightness 100 | pastel format lab
Lab(98, -17, 65)
 % pastel set lightness 100 orange | pastel set lightness 100 | pastel set lightness 100 | pastel format lab
Lab(98, -17, 63)
sharkdp commented 4 years ago

Thank you for the detailed bug report.

I have no idea if this is an issue with converting between colorspaces ...

It probably is. Either with the precision of the conversion (hopefully not) or with the sRGB gamut boundary limitations.

... or just unavoidable.

I'm not sure. We should look into it.

sigprof commented 3 years ago

The problem is that an attempt to set the color to Lab(100, 24, 79) results in a color which is out of the sRGB gamut, and the method of bringing the color into gamut used by pastel is very simple — just clamp R, G, and B components into the [0.0, 1.0] range. This method does not preserve the Lab lightness value.

Maybe you expected some other method of bringing the color into gamut (e.g., keeping the LCh hue constant and adjusting the LCh chroma if needed — this would give pure white when setting lightness to 100), but currently no other methods except clamping the RGB values are implemented.

There is also another issue — rounding of the printed Lab values loses some information (as you noticed when comparing results for pastel set lightness 149 and pastel set lightness 156). Actually the first color is rgb(255, 255, 235), which has Lab lightness ≈ 99.6, but pastel prints that lightness as 100, and reading that Lab value back gives rgb(255, 255, 255). Maybe Lab and LCh values should be printed with at least 1 digit after the decimal point, so that reading that representation would not result in a different RGB color (but I'm not 100% sure that 1 digit would be enough in all cases).

sharkdp commented 3 years ago

@sigprof Thank you for the insights and thoughts. I currently don't find the time to work on this myself.