72 lines
2.3 KiB
Markdown
72 lines
2.3 KiB
Markdown
## A close look at the sRGB formula ##
|
||
|
||
[Source](https://blog.demofox.org/2018/03/10/dont-convert-srgb-u8-to-linear-u8/)
|
||
[Specific page](http://entropymine.com/imageworsener/srgbformula/)
|
||
|
||
The formulas for converting sRGB colors to linear, and the reverse, are usually
|
||
given as follows:
|
||
|
||
```
|
||
sRGB to Linear
|
||
|
||
Condition Value
|
||
0 ≤ S ≤ 0.04045 L = S/12.92
|
||
0.04045 < S ≤ 1 L = ((S+0.055)/1.055)^2.4
|
||
```
|
||
|
||
```
|
||
Linear to sRGB
|
||
|
||
Condition Value
|
||
0 ≤ L ≤ 0.0031308 S = L×12.92
|
||
0.0031308 < L ≤ 1 S = 1.055×L^(1/2.4) − 0.055
|
||
```
|
||
|
||
The definition uses two different functions – a straight line and an
|
||
exponential curve – glued together at a certain “cutoff point”. The implication
|
||
is that these functions (the ones in the sRGB to Linear definition) intersect
|
||
at the point:
|
||
|
||
**(0.0404500000000000, 0.00313080000000000)**
|
||
|
||
If we take a close look at the function, though, we can see this intersection
|
||
point is not exact, so the formula has a slight discontinuity:
|
||
|
||
* sRGB: 0.0404500000000000
|
||
* sRGB: 0.0404500000000001
|
||
* Linear: 0.00313080495356037
|
||
* Linera: 0.00313080728306769
|
||
|
||
If we extend the functions, we see that they actually intersect at two points:
|
||
|
||
1. (0.0381547987133173, 0.00295315779514840)
|
||
2. (0.0404482362771082, 0.00313066844250063)
|
||
|
||
If we use either of these two points as the cutoff point, there will be no
|
||
discontinuity at all. It’s apparent that the sRGB inventors selected the second
|
||
of these points, and rounded its value to 4 significant digits to get 0.04045.
|
||
They then used that rounded sRGB value to recalculate the Linear value, and got
|
||
0.00313080. I don’t know why their Linear value has more significant digits (5
|
||
or 6) than their sRGB value (4).
|
||
|
||
I guess that if you’re a perfectionist, and want no discontinuity at all, you
|
||
can tweak the formulas like this:
|
||
|
||
```
|
||
sRGB to Linear
|
||
|
||
Condition Value
|
||
0 ≤ S ≤ 0.0404482362771082 L = S/12.92
|
||
0.0404482362771082 < S ≤ 1 L = ((S+0.055)/1.055)^2.4
|
||
```
|
||
|
||
```
|
||
Linear to sRGB
|
||
|
||
Condition Value
|
||
0 ≤ L ≤ 0.00313066844250063 S = L×12.92
|
||
0.00313066844250063 < L ≤ 1 S = 1.055×L^(1/2.4) − 0.055
|
||
```
|
||
|
||
It doesn’t make any practical difference. The two functions are extremely close
|
||
together in this region, so the precise cutoff point is almost irrelevant.
|