What is the gamma encoding and why are my color computations wrong? - Printable Version +- Gimp-Forum.net (https://www.gimp-forum.net) +-- Forum: GIMP (https://www.gimp-forum.net/Forum-GIMP) +--- Forum: Tutorials and tips (https://www.gimp-forum.net/Forum-Tutorials-and-tips) +--- Thread: What is the gamma encoding and why are my color computations wrong? (/Thread-What-is-the-gamma-encoding-and-why-are-my-color-computations-wrong) |
What is the gamma encoding and why are my color computations wrong? - Ofnuts - 07-16-2024 So, you tried to predict or emulate Gimp's behavior with math and failed. And you wonder why. You have come to the right place, take a seat and fasten you seat belt. Also, make sure you check all images at their actual size (click on them to see them in a separate tab, and make sure your browser is exactly 100%zoom) otherwise some example could seem to demonstrated exactly the opposite of what is stated in the text. The root cause is that our eyes are not linear devices. If you double the power output (for instance, switch on a second light), you don't perceive the room twice as bright. Somewhat brighter, yes, but certainly not twice as bright. Furthermore, our eyes are more sensitive to small differences between dark tones that between light ones. So, when pixel color values are encoded on a byte, encoding the physical output directly (which is what Gimp calls Linear light) wastes precious bytes values encoding bright nuances we can't perceive, and leaves a handful of values to encode all the subtle darkness nuances we can distinguish. To avoid this, the values are encoded using a power law that has two nice advantages:
In practice images are encoded using a slightly enhanced law called the sRGB color space where the "physical" medium gray is #BC [attachment=12155]
So far, so good. So, where is the problem? The problem is that if the gamma-encoded values are a good way to store the values, they cannot be used directly to compute things. For instance, the average color of an area with an equal number of black (#00) and white (#FF) pixels is not #80. This area emits towards your eyes half the power of the fully white area, so its average color is the "physical" medium gray, not the "perceived" medium gray as demonstrated by the picture below (that should be checked at full scale(*)): [attachment=11076]
Which side is closer to the middle? In fact, making the square on the right indistinguishable from the one in the middle is a good way to tune your display... The rule is: when doing computations that are based on physical models (spoiler alert: most are), channel values should always be converted to physical values (Gimp's Linear light) before any math is applied to them. This applies equally to the three color channels. For instance if you do a red-green gradient, you would expect the midpoint of the gradient to be orange.
[attachment=12122]
If you use Filters > Blur > Pixellize on the pattern, you should obtain the same color.
All these examples show that the direct computation in the sRGB space produces results that are too dark. Some more notes:
Code: import sys,math (*) Browsers scale images using the sRGB values directly, so scaled images may end up darker than the original image. The three-color average example above is a good example. At native size the linear average (right square) is identical to the pattern at the top, but if the image is scaled by your browser (just zoom in/out) your browser will gamma-average the pattern at some point and make it look like the bottom left square. RE: What is the gamma encoding and why are my color computations wrong? - Ofnuts - 07-16-2024 Going next level... how is opacity/transparency handled? The usual Normal more is what is known as the over operator in computer graphics. The general formula or pixel A over pixel B is: alphaOut = alphaA + alphaB * (1 - alphaA) channelOut = ( channelA * alphaA + channelB * alphaB * (1 - alphaA) ) / alphaOut In the frequent case where the bottom is fullly opaque (alphaB = 1), this simplifies to: alphaOut = 1 channelOut = channelA * alphaA + channel B * (1 - alphaA) Of course Gimp uses these formulas, but the question is, what are the actual input values... and the answer is, it depends The great distinction is between Default and Legacy blend modes: In Default mode:
The computations: [attachment=12147]
The results in Default mode:
[attachment=12148]
The results in Legacy mode (where the outcome is the average of the two layers)
[attachment=12149]
Augmented spreadsheet with three macros/functions (all inputs and outputs are assumed "linear"):[attachment=12150]
RE: What is the gamma encoding and why are my color computations wrong? - PixLab - 07-17-2024 A lot of work in it you did, an absolute great job! (07-16-2024, 07:25 PM)Ofnuts Wrote: luminosity ** 2.2 Just a POV about the "**", I would suggest to use ^ instead of ** as the later is mostly known by programmer, which most of us are not, and GIMP does not know it either [attachment=12125] [attachment=12126] RE: What is the gamma encoding and why are my color computations wrong? - Ofnuts - 07-17-2024 The real exponentiation notation is superscript, everything else is conventions. And most questions I answered about this so far have been from programmers and they mostly use **. RE: What is the gamma encoding and why are my color computations wrong? - Ofnuts - 07-17-2024 Just for fun, another demo of your browser improperly scaling on gamma values. Zoom the image below to see it turn red. [attachment=12131]
But if you import it in Gimp and zoom in Gimp (or scale it...) its color won't change. RE: What is the gamma encoding and why are my color computations wrong? - Ofnuts - 07-18-2024 Added a post on transparency handling. For ease of reference, I moved it to the beginning of the thread. |