1
$\begingroup$

I am struggling understanding gamma encoding/decoding.

So the colors I see and the values I get from a color picker application(like MS Paint) are already in sRGB space(correct?).

Assume the color picker gives color C1=(186,70,2). If I create an image programmatically with all pixels in color C1 and Do Not apply gamma encoding C1^(1/gamma), and save it as ppm file, I see exactly same color C1 on opening the file on a viewer.

But this is not the case in my experiment. I save values of color C1 into the file and see color C1. And this is what I don't understand: if the display raise the input color C1 by gamma why do I still see C1 on the screen? Should I not expect to get C1^gamma?

UPDATE:

Basically here is the ppm file with all pixel RGB values (128,128,128). No gamma-encoding has been applied. That is simply writing linear values of 128.

P3
400 400
255
128 128 128
128 128 128
128 128 128
128 128 128
128 128 128
...

According to Wikipedia Gamma correction page:

For example, when using 24-bit RGB color (8 bits per channel), writing a value of 128 (rounded midpoint of the 0–255 byte range) in video memory it outputs the proportional ≈ 0.5 voltage to the display, which it is shown darker due to the monitor behavior.

Wikipedia clearly says write a value 128 and you will see a darker than you expect. Those values in my ppm file are not gamma-encoded and so I expect seeing a darker color(0.5^gamma) on the screen. Yet this is not the case and if you open this file on a viewer you will see pixels with brightness half as white.

127 in file -> screen outputs -> ~20% light -> eye sees -> ~50% as bright

That is what I don't get.

Update 2 (After Nathan good answer..)

So with input of 186 the screen outputs 50% of white intensity? And the eye perceives it as 50% as bright as white? is this right? But if the screen output is 50% in intensity, and eye has its own curve(roughly power of 1/gamma) then the screen output of 50% should be seen brighter?

Another question I have is that, So is it the programmer responsibility to write gamma-corrected values into the file or the whatever API we use to save image file formats does it internally? For example i use .Net Bitmap class. Do I need to save bitmap with gamma-encoded values or Bitmap.Save method does it? I ask this since according Wikipedia, and you mentioned this too, almost all image formats are encoded

binary data in still image files (such as JPEG) are explicitly encoded (that is, they carry gamma-encoded values, not linear intensities)

$\endgroup$
3
  • 1
    $\begingroup$ The gamma correction covers how the real world measurement differes from the numerical values. So if you had say a color of 127, 127, 127 and measured its intensity. If you then measured 255,255,255. Then it wouldnt report double the intensity. There is no use measuring this inside the computer it does not know this. Its important of you want to calculate on color physicaly plausibly but not otherwise. Also if you do measure you will find that your monitor isnt sRGB since you havent profiled/calibrated it in less than a month. $\endgroup$
    – joojaa
    Commented May 22, 2020 at 5:34
  • 1
    $\begingroup$ But that is again the reason we gamma correct. Human eye is not linearily sensitive. So gamma correction is a sort of compression to use the limited resolution of colors better. $\endgroup$
    – joojaa
    Commented May 22, 2020 at 15:42
  • $\begingroup$ @joojaa, thanks for your comments. I appreciate if I have your thoughts on the update I made on the question plz. $\endgroup$
    – ali
    Commented May 22, 2020 at 16:49

1 Answer 1

2
$\begingroup$

Almost all image formats store colors gamma-encoded, so if you write out those values to a file then that's what you'll see on opening it. The pixel pickers etc operate on the same values stored in the file. It's much less common to store linear-light color values in a file (one example is digital camera RAW files).

When you "see color C1" on the screen, you are seeing C1^gamma. Or rather, you are seeing however that particular monitor renders the RGB value C1, which is at least approximately described by C1^gamma for some gamma. The color you see does not differ between the paint program and the programmatically generated file because they're both sending C1 to the monitor, and the monitor is doing the same thing with it.

Re: your update, you wrote:

if you open this file on a viewer you will see pixels with brightness half as white

Think about this carefully. How are you judging that the pixels are "half as white"? Are you measuring them with a photometer and finding that they emit half the luminous intensity of a full white pixel? Or are you looking at them and judging that they appear roughly halfway between black and white?

Human perception of brightness is very non-linear. A value that looks perceptually halfway between black and white is physically closer to 20% of the brightness of white, not 50%.

A good way to find a true 50% brightness is to create an image with a checkerboard of black and white pixels, then defocus your eyes slightly, or stand farther away from the monitor, so that the pattern blurs into a uniform grey. That grey is 50% brightness (because it's an average over 50% black pixels and 50% white pixels). You will find that this grey looks considerably brighter than an RGB (128, 128, 128) grey.

For example, open this image in a new tab to be sure it's appearing at 1:1 resolution (browsers resizing it do not necessarily respect gamma): gamma test image You will see that the checkerboard in the center looks a lot brighter than the 128 grey on the left, and should be pretty close to the 186 grey on the right. The 186 is encoding a 50% brightness at 2.2 gamma.

Re: update 2, you wrote:

So with input of 186 the screen outputs 50% of white intensity? And the eye perceives it as 50% as bright as white?

Not quite—the eye perceives a 50% physical intensity as more than halfway between black and white. Maybe around 70% or so. Conversely, the grey that the eye perceives as halfway between black and white is more like a 20% physical intensity.

Actually, gamma-encoded values are a fairly close match to how we perceive brightness, which is convenient (although it's sort of a coincidence; the original reason for gamma was due to how CRT phosphors worked, not anything to do with perception). For a true perceptually uniform color space, you can look at CIELAB, which has a more complicated nonlinear transformation that's designed to mimic average human perception.

is it the programmer responsibility to write gamma-corrected values into the file or the whatever API we use to save image file formats does it internally?

It's the programmer's responsibility. Almost all image file formats, libraries, and APIs are just passing around gamma-encoded values and do not do any transformations on them.

$\endgroup$
13
  • $\begingroup$ many thanks for the answer. Still I cannot understand it fully. I have updated the question could you plz take time and have a look. $\endgroup$
    – ali
    Commented May 22, 2020 at 14:32
  • $\begingroup$ @ali I updated the answer $\endgroup$ Commented May 22, 2020 at 19:56
  • $\begingroup$ that is a really good answer. Thanks. I also updated the question for couple of more questions . could you have a look plz. $\endgroup$
    – ali
    Commented May 23, 2020 at 11:19
  • $\begingroup$ @ali Sure, updated again $\endgroup$ Commented May 23, 2020 at 18:55
  • 1
    $\begingroup$ 186 input produces 50% intensity by the screen, and our eye percieves this as 70% as bright as white. Then the column 186 is not close to half white. $\endgroup$
    – ali
    Commented May 23, 2020 at 20:46

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.