ToneCurve Class
An immutable tone curve: a function that gives a new value to a sample value, for ImageProcessingExtensions.ApplyToneCurve and ImageProcessingExtensions.ApplyToneCurves.
public sealed class ToneCurveRemarks
Values are fractions of the largest sample value: 0 is black and 1 is full intensity, for every pixel format (a level v of an 8-bit sample is v / 255). A curve is made of a gamma correction (ToneCurve.CreateGamma), a levels adjustment (ToneCurve.CreateLevels), a smooth curve through control points (ToneCurve.CreateFromPoints), a one-dimensional lookup table (ToneCurve.CreateFromTable), or a sequence of them (ToneCurve.Then), and ToneCurve.Evaluate gives its value anywhere.
Every function is defined for every number, so that floating-point samples outside [0, 1] (highlights, negative out-of-gamut colors) have a value too: see each factory method. A value that is not a number stays one.
Properties
| Name | Description |
|---|---|
| Identity | Gets the curve that keeps every value. |
| IsIdentity | Gets a value indicating whether the curve keeps every value: it is ToneCurve.Identity, or a sequence of curves that keep every value. |
Identity
ToneCurve.csIsIdentity
ToneCurve.csGets a value indicating whether the curve keeps every value: it is ToneCurve.Identity, or a sequence of curves that keep every value.
public bool IsIdentity { get; }Property value
Methods
| Name | Description |
|---|---|
| CreateFromPoints(ReadOnlySpan<PointD>) | Creates a smooth curve through control points: the curves of photo editors. Between two points, the curve is the monotone piecewise cubic Hermite interpolation of Fritsch and Carlson (PCHIP): it goes through every point, never overshoots them, and rises (or falls) wherever the points do, so that it never inverts the tones between two points. |
| CreateFromTable(ReadOnlySpan<double>) | Creates a curve from a one-dimensional lookup table: the values of the curve at evenly spaced inputs from 0 to 1, interpolated linearly in between. A table of n values gives value i to the input i / (n - 1). |
| CreateGamma(double) | Creates a gamma correction: a value v becomes v^(1 / gamma), so a gamma above 1 brightens the midtones and a gamma below 1 darkens them, while 0 and 1 are kept. It is the gamma of ImageMagick's -gamma and of the middle slider of the levels of Photoshop and GIMP. |
| CreateLevels(double, double, double, double, double) | Creates a levels adjustment: the values from inputBlack to inputWhite are stretched to [0, 1], clipped, corrected by gamma, and stretched to the range from outputBlack to outputWhite. |
| Evaluate(double) | Gets the value of the curve at a value. |
| Then(ToneCurve) | Gets the curve that applies this one, then another one to its result. |
CreateFromPoints(ReadOnlySpan<PointD>)
ToneCurve.csCreates a smooth curve through control points: the curves of photo editors. Between two points, the curve is the monotone piecewise cubic Hermite interpolation of Fritsch and Carlson (PCHIP): it goes through every point, never overshoots them, and rises (or falls) wherever the points do, so that it never inverts the tones between two points.
public static ToneCurve CreateFromPoints(params scoped ReadOnlySpan<PointD> points)Parameters
pointsReadOnlySpan<PointD>- At least two points, ordered by increasing
PointD.X, with finite coordinates;PointD.Xis the input value andPointD.Ythe output value. They are copied.
Returns
ToneCurve The curve.
Exceptions
ArgumentException- There are fewer than two points, a coordinate is not finite, or the
PointD.Xcoordinates are not strictly increasing.
Remarks
The slopes at the points are those of SciPy's PchipInterpolator (and of MATLAB's pchip): 0 at a point where the curve changes direction, the weighted harmonic mean of the slopes of the two segments elsewhere, and a three-point estimate at the first and the last point. Two points give a straight line.
Before the first point and after the last one, the curve is flat: it keeps the value of the nearest point, as in Photoshop and GIMP. To clip the shadows, start at (0.1, 0); to keep the whole range, start at (0, 0) and end at (1, 1).
CreateFromTable(ReadOnlySpan<double>)
ToneCurve.csCreates a curve from a one-dimensional lookup table: the values of the curve at evenly spaced inputs from 0 to 1, interpolated linearly in between. A table of n values gives value i to the input i / (n - 1).
public static ToneCurve CreateFromTable(params scoped ReadOnlySpan<double> values)Parameters
valuesReadOnlySpan<double>- At least two finite values. They are copied.
Returns
ToneCurve The curve.
Exceptions
ArgumentException- There are fewer than two values, or a value is not finite.
Remarks
Before 0 and after 1, the curve keeps the first and the last value of the table. A table of 256 values applied to an 8-bit sample reads exactly one value per level, without interpolation.
CreateGamma(double)
ToneCurve.csCreates a gamma correction: a value v becomes v^(1 / gamma), so a gamma above 1 brightens the midtones and a gamma below 1 darkens them, while 0 and 1 are kept. It is the gamma of ImageMagick's -gamma and of the middle slider of the levels of Photoshop and GIMP.
Parameters
gammadouble- The gamma. Must be a positive finite number; 1 gives
ToneCurve.Identity.
Returns
ToneCurve The curve.
Exceptions
ArgumentOutOfRangeExceptiongammais not a positive finite number.
Remarks
A negative value v becomes -(-v)^(1 / gamma), so the curve is odd and keeps the sign.
CreateLevels(double, double, double, double, double)
ToneCurve.csCreates a levels adjustment: the values from inputBlack to inputWhite are stretched to [0, 1], clipped, corrected by gamma, and stretched to the range from outputBlack to outputWhite.
public static ToneCurve CreateLevels(double inputBlack, double inputWhite, double gamma = 1d, double outputBlack = 0d, double outputWhite = 1d)Parameters
inputBlackdouble- The value that becomes
outputBlack. Must be finite. inputWhitedouble- The value that becomes
outputWhite. Must be finite and greater thaninputBlack. gammadouble- The gamma correction of the midtones, as
ToneCurve.CreateGamma. Must be a positive finite number. outputBlackdouble- The darkest value of the result. Must be finite.
outputWhitedouble- The brightest value of the result. Must be finite.
Returns
ToneCurve The curve.
Exceptions
ArgumentException- A value is not finite, or
inputWhiteis not greater thaninputBlack. ArgumentOutOfRangeExceptiongammais not a positive finite number.
Remarks
A value v becomes outputBlack + (outputWhite - outputBlack) * t^(1 / gamma), where t = clamp((v - inputBlack) / (inputWhite - inputBlack), 0, 1): the levels of Photoshop and GIMP, and ImageMagick's -level followed by +level. Every value below inputBlack becomes outputBlack and every value above inputWhite becomes outputWhite, floating-point values outside [0, 1] included: the input range clips. An output black above the output white inverts the values.
Evaluate(double)
ToneCurve.csGets the value of the curve at a value.
Parameters
valuedouble- The value, a fraction of the largest sample value.
Returns
double The value of the curve; Double.NaN when value is not a number.
Then(ToneCurve)
ToneCurve.csGets the curve that applies this one, then another one to its result.
Parameters
nextToneCurve- The curve applied to the values of this one.
Returns
ToneCurve The combined curve: next.Evaluate(this.Evaluate(v)).
Exceptions
ArgumentNullExceptionnextisnull.