Table of Contents

Class ColorTransform

Namespace
Egami.Colors
Assembly
Egami.dll

A conversion from one color encoding to another, compiled once and then applied to spans of pixels of any type. Reusable and safe to share between threads. Transforms are cached per EgamiContext, so creating the same one again is cheap.

public sealed class ColorTransform
Inheritance
ColorTransform
Inherited Members

Examples

// A transform is compiled once (and cached), then applied to spans of any pixel type, in place or into another type.
ColorTransform transform = ColorTransform.Create(ColorProfile.DisplayP3, ColorProfile.Srgb, new ColorTransformOptions { Intent = RenderingIntent.Perceptual });
Rgba8[] pixels = [new(255, 0, 0, 255), new(0, 128, 255, 128)];
transform.Apply<Rgba8>(pixels);
RgbaF32[] wide = new RgbaF32[pixels.Length];
transform.Apply<Rgba8, RgbaF32>(pixels, wide);   // float types keep values outside 0..1

Remarks

Pixels are read in the source encoding's model and written in the target's: RGB pixel types give and take red, green and blue; gray types their gray value; CMYK types (Cmyk8, Cmyk16) their inks. A pixel type of another model is converted to the encoding's model numerically first, as PixelConvert would (an RGB pixel's gray is its luma), and results land in it the same way. Alpha is carried over unchanged, and is opaque when the source has none.

8-bit RGB, BGR, RGBA, BGRA, gray, gray-alpha and CMYK pixels take a fast path; other types go through floats, so float and half types keep values outside 0..1 (as wide-gamut and HDR conversions produce) and integer types are clamped.

Properties

InputChannels

Gets the channels of each color converted from: the source's ChannelCount.

public int InputChannels { get; }

Property Value

int

IsIdentity

Gets a value indicating whether the two encodings mean the same colors, so applying the transform changes nothing.

public bool IsIdentity { get; }

Property Value

bool

Options

Gets the intent and black point compensation.

public ColorTransformOptions Options { get; }

Property Value

ColorTransformOptions

OutputChannels

Gets the channels of each color converted to: the target's ChannelCount.

public int OutputChannels { get; }

Property Value

int

Source

Gets the encoding converted from.

public ColorProfile Source { get; }

Property Value

ColorProfile

Target

Gets the encoding converted to.

public ColorProfile Target { get; }

Property Value

ColorProfile

Methods

Apply(ReadOnlySpan<float>, Span<float>)

Converts colors stored as floats, InputChannels per color in and OutputChannels out, each 0 to 1 (inks as tints): the way to convert from or to an n-colour profile, which no pixel type holds, and for any other values that are not pixels. Inputs are clamped to 0 to 1; outputs keep any value the conversion gives.

public void Apply(ReadOnlySpan<float> source, Span<float> destination)

Parameters

source ReadOnlySpan<float>

The colors, a whole number of InputChannels values each.

destination Span<float>

Where to write them: OutputChannels values for each color in source.

Exceptions

ArgumentException

source is not a whole number of colors, or destination is too short.

Apply<TPixel>(Span<TPixel>)

Converts pixels in place.

public void Apply<TPixel>(Span<TPixel> pixels) where TPixel : unmanaged, IPixelType<TPixel>

Parameters

pixels Span<TPixel>

The pixels.

Type Parameters

TPixel

The pixel type.

Apply<TFrom, TTo>(ReadOnlySpan<TFrom>, Span<TTo>)

Converts pixels from one type to another; the spans may be the same memory when the types are the same.

public void Apply<TFrom, TTo>(ReadOnlySpan<TFrom> source, Span<TTo> destination) where TFrom : unmanaged, IPixelType<TFrom> where TTo : unmanaged, IPixelType<TTo>

Parameters

source ReadOnlySpan<TFrom>

The pixels to convert.

destination Span<TTo>

Where to write them, at least as long as source.

Type Parameters

TFrom

The source pixel type.

TTo

The destination pixel type.

Exceptions

ArgumentException

destination is shorter than source.

Create(ColorProfile, ColorProfile, ColorTransformOptions?, EgamiContext?)

Compiles the conversion from source to target, or returns it from the cache.

public static ColorTransform Create(ColorProfile source, ColorProfile target, ColorTransformOptions? options = null, EgamiContext? context = null)

Parameters

source ColorProfile

The encoding of the pixels given.

target ColorProfile

The encoding to convert to.

options ColorTransformOptions

The intent and black point compensation, or null for Default.

context EgamiContext

The context whose cache to use, or null for Default.

Returns

ColorTransform

The transform.

Examples

// A transform is compiled once (and cached), then applied to spans of any pixel type, in place or into another type.
ColorTransform transform = ColorTransform.Create(ColorProfile.DisplayP3, ColorProfile.Srgb, new ColorTransformOptions { Intent = RenderingIntent.Perceptual });
Rgba8[] pixels = [new(255, 0, 0, 255), new(0, 128, 255, 128)];
transform.Apply<Rgba8>(pixels);
RgbaF32[] wide = new RgbaF32[pixels.Length];
transform.Apply<Rgba8, RgbaF32>(pixels, wide);   // float types keep values outside 0..1

Exceptions

ArgumentNullException

source or target is null.

UnsupportedFormatException

An ICC profile has no tables for the direction it is used in, such as an input-only profile as the target.