Class ToneCurve
- Namespace
- Egami.Operations
- Assembly
- Egami.dll
A curve from 0..1 to 0..1 for one channel, as a photo editor's curves dialog draws it: inputs outside 0..1 are clamped first and results are clamped to 0..1. Use one in Curves(ToneCurve); the tone steps (Level, Gamma and the rest) are curves too, evaluated exactly.
public sealed class ToneCurve
- Inheritance
-
ToneCurve
- Inherited Members
Examples
// Curves as a photo editor draws them: a smooth curve through the points that never overshoots, here a mild S on all
// three channels and a lift in the blue shadows.
ToneCurve s = ToneCurve.FromPoints([(0, 0), (0.25f, 0.2f), (0.75f, 0.82f), (1, 1)]);
ToneCurve blue = ToneCurve.FromPoints([(0, 0.06f), (0.5f, 0.5f), (1, 1)]);
raster.Apply(o => o.ApplyFilter(ColorFilter.Curves(s, s, s.Then(blue))), Ct);
Remarks
Immutable and safe to share between threads.
Properties
Identity
Gets the curve that changes nothing.
public static ToneCurve Identity { get; }
Property Value
Methods
Evaluate(float)
Returns the curve's value at x.
public float Evaluate(float x)
Parameters
xfloatThe input; values outside 0..1 are clamped, and NaN reads as 0.
Returns
- float
The output, from 0 to 1.
FromFunction(Func<float, float>, int)
Returns a curve sampled from function at samples evenly spaced inputs and run straight
between them. The function is called only here, so the curve is safe to share whatever the function captures.
public static ToneCurve FromFunction(Func<float, float> function, int samples = 4096)
Parameters
functionFunc<float, float>The function; results are clamped to 0..1, and NaN reads as 0.
samplesintHow many samples, from 2 to 65,536. Defaults to 4,096.
Returns
- ToneCurve
The curve.
Exceptions
- ArgumentNullException
functionis null.- ArgumentOutOfRangeException
samplesis outside 2 to 65,536.
FromPoints(ReadOnlySpan<(float X, float Y)>)
Returns the smooth curve through points: a monotone cubic (Fritsch and Carlson, 1980), so a curve through
rising points rises everywhere and never overshoots, as photo editors' curves do. Before the first point and after the last
the curve stays flat at their values.
public static ToneCurve FromPoints(ReadOnlySpan<(float X, float Y)> points)
Parameters
pointsReadOnlySpan<(float X, float Y)>At least two points, each coordinate from 0 to 1, with strictly increasing
X.
Returns
- ToneCurve
The curve.
Exceptions
- ArgumentException
There are fewer than two points, a coordinate is outside 0..1, or the
Xvalues do not strictly increase.
FromTable(ReadOnlySpan<float>)
Returns the curve that passes through table's values at evenly spaced inputs (the first at 0, the last at 1)
and runs straight between them, as a .cube file's 1D table and Skia's TableARGB do.
public static ToneCurve FromTable(ReadOnlySpan<float> table)
Parameters
tableReadOnlySpan<float>At least two values, each from 0 to 1. The table is copied.
Returns
- ToneCurve
The curve.
Exceptions
- ArgumentException
The table has fewer than two values or a value outside 0..1.
Then(ToneCurve)
Returns the curve that applies this one and then next.
public ToneCurve Then(ToneCurve next)
Parameters
nextToneCurveThe curve applied second.
Returns
- ToneCurve
The combined curve.
Exceptions
- ArgumentNullException
nextis null.