public class LinearRgb extends Object
Why this class exists: The standard RGB (sRGB) color space is optimized for the visual response of the human eye. As such, it is based on a non-linear response to intensity values. This approach works well for display purposes, but has a disadvantage when used for interpolation, color-blending, or other purposes which would benefit from a linear intensity scale. Therefore, in image processing applications it is common to map the standard RGB (sRGB) to a linear form.
The conversion between non-linear and linear intensities depends on a power function and is sometimes computationally expensive. To streamline that process, this class implements a logic to perform the conversion using a lookup table. The sRGB to linear RGB conversion is straightforward because it maps simple byte values (in the range 0 to 255) to floating-point values (in the range 0 to 1.0). The conversion from linear RGB to sRGB is more complicated. While a simple lookup operation is feasible, the operations results in a small error (one level of intensity) in approximately 0.7 percent of all cases. This class trades uses an interpolation technique to reduce the error to less than 0.1 percent. The interpolation is more costly than a simple look up, but requires about half the processing time of the direct power function. The resulting errors tend to be due to round off of values very close to the midpoint between two integral values (for example, a value of 100.499 for the interpolated method versus 100.5001 for the directly computed method).
Using this class: This class is implemented as a thread-safe singleton. You may invoke it as shown in the code example below:
Color orange = Color.orange; int r = orange.getRed(); int g = orange.getGreen(); int b = orange.getBlue(); LinearRgb linearRgb = LinearRgb.getInstance(); // get single instance float rLinear = linearRgb.standardToLinear(r); // value in range 0 to 1 float gLinear = linearRgb.standardToLinear(g); // value in range 0 to 1 float bLinear = linearRgb.standardToLinear(b); // value in range 0 to 1 double yLinear = 0.2126*rLinear + 0.7152*gLinear+0.0722*bLinear; int gray = linearRgb.linearToStandard(yLinear); Color orange2Grayscale = new Color(gray, gray, gray);
Performance: The performance of this class was tested on a mid-level laptop processing 1 million samples. The results collected over several trials are summarized below:
Method Time to Process Direct computation sRGB to Linear 33.21 milliseconds Lookup table standardToLinear() 1.01 milliseconds Direct computation Linear to sSGB 36.86 milliseconds Interpolated lookup linearToStandard() 12.90 millisecondsThe interpolation-based lookup used for the linearToStandard() class requires more processing time than a simple lookup, but returns a match for the direct computation in more than 99.9 percent of all cases and never experiences an error greater than 1 level.
Modifier and Type | Method and Description |
---|---|
double |
computeLinear(int standard)
Compute the linear form of the specified value from the standard
sRGB color space.
|
double |
computeStandard(double linear)
Compute the standard form of the specified value from the linear
color space.
|
static LinearRgb |
getInstance()
Returns a single, sharable, read-only instance of this class.
|
int |
linearToStandard(double linearValue)
Converts an intensity value from the linear color space to its equivalent
in the standard RGB (sRGB) space.
|
float |
standardToLinear(int p)
Converts a value giving an intensity from one of the color components
in the sRGB space to the linear equivalent.
|
double |
testLinearToStandard(double linearValue)
Provides a test method for evaluating the linear interpolation
performed by this class's linearToStandard method.
|
public static LinearRgb getInstance()
public final double computeLinear(int standard)
standard
- a R,G, or B value from the standard (non-linear)
sRGB color space; value 0 to 255.public final double computeStandard(double linear)
linear
- a linear value in the range 0 to 1public float standardToLinear(int p)
p
- a value in the range 0 to 255.public int linearToStandard(double linearValue)
Even good resampling techniques including Lanczos and B-Sline methods can result in values that are out of the range 0 to 1. In such cases, this method truncates the input value so that it is restricted to the valid range.
linearValue
- a value in the range 0 to 1; out-of-range
values will be truncated.public double testLinearToStandard(double linearValue)
linearValue
- a value in the range 0 to 1, with out-of-range
values being truncated.Copyright © 2022. All rights reserved.