Table of Contents

Class Compositor

Namespace
Egami.Operations
Assembly
Egami.dll

Blends rows of pixels with a BlendMode, for code that composites outside an operation chain: a custom IRasterOperation, a rasterizer filling spans, a layer merge. It runs the kernels DrawImage runs, so Blend<TPixel>(BlendMode, ReadOnlySpan<TPixel>, Span<TPixel>, float, ColorSpace) on a row gives the pixels DrawImage gives there. Every method works for every pixel type, allocates nothing once warm, and is safe to call from many threads at once.

public static class Compositor
Inheritance
Compositor
Inherited Members

Examples

// Blend rows in your own code: a source row, a destination row, and coverage from an antialiased edge.
Rgba8[] source = new Rgba8[256], destination = new Rgba8[256];
byte[] coverage = new byte[256];
for (int x = 0; x < 256; x++)
{
    source[x] = new Rgba8((byte)x, 80, 200, 255);
    destination[x] = new Rgba8(250, 250, 240, 255);
    coverage[x] = (byte)Math.Clamp((x - 100) * 8, 0, 255);   // a soft edge from x = 100 to 132
}

Compositor.Blend<Rgba8>(BlendMode.Multiply, source, destination, coverage);

// One color through coverage, the way a rasterizer fills a shape's spans.
Compositor.Blend(BlendMode.SourceOver, new Rgba8(255, 0, 0, 128), destination.AsSpan(), coverage);

Methods

Blend(BlendMode, Rgba8, Rgba8)

Blends one pixel onto another and returns the result, as DrawImage would for that pair.

public static Rgba8 Blend(BlendMode mode, Rgba8 source, Rgba8 destination)

Parameters

mode BlendMode

How the pixels combine.

source Rgba8

The pixel on top.

destination Rgba8

The pixel under it.

Returns

Rgba8

The blended pixel.

Exceptions

ArgumentOutOfRangeException

mode is not defined.

Blend(BlendMode, RgbaF32, RgbaF32)

Blends one float pixel onto another and returns the result, as DrawImage would for that pair.

public static RgbaF32 Blend(BlendMode mode, RgbaF32 source, RgbaF32 destination)

Parameters

mode BlendMode

How the pixels combine.

source RgbaF32

The pixel on top.

destination RgbaF32

The pixel under it.

Returns

RgbaF32

The blended pixel.

Exceptions

ArgumentOutOfRangeException

mode is not defined.

Blend<TPixel>(BlendMode, Rgba8, Span<TPixel>, ReadOnlySpan<byte>, float, ColorSpace)

Blends one color onto every pixel of destination through per-pixel coverage: the span fill a rasterizer draws a shape with. Coverage 0 leaves a pixel as it was.

public static void Blend<TPixel>(BlendMode mode, Rgba8 color, Span<TPixel> destination, ReadOnlySpan<byte> coverage, float opacity = 1, ColorSpace colorSpace = ColorSpace.Encoded) where TPixel : unmanaged, IPixelType<TPixel>

Parameters

mode BlendMode

How the color combines with each pixel.

color Rgba8

The color, with straight alpha.

destination Span<TPixel>

The pixels to change.

coverage ReadOnlySpan<byte>

One coverage value per pixel, 0 to 255; the same length as destination.

opacity float

Multiplies the color's alpha before the mode: 1 uses it as it is.

colorSpace ColorSpace

Where pixels are blended. Defaults to Encoded.

Type Parameters

TPixel

The pixel type of the row.

Examples

// Blend rows in your own code: a source row, a destination row, and coverage from an antialiased edge.
Rgba8[] source = new Rgba8[256], destination = new Rgba8[256];
byte[] coverage = new byte[256];
for (int x = 0; x < 256; x++)
{
    source[x] = new Rgba8((byte)x, 80, 200, 255);
    destination[x] = new Rgba8(250, 250, 240, 255);
    coverage[x] = (byte)Math.Clamp((x - 100) * 8, 0, 255);   // a soft edge from x = 100 to 132
}

Compositor.Blend<Rgba8>(BlendMode.Multiply, source, destination, coverage);

// One color through coverage, the way a rasterizer fills a shape's spans.
Compositor.Blend(BlendMode.SourceOver, new Rgba8(255, 0, 0, 128), destination.AsSpan(), coverage);

Exceptions

ArgumentException

The coverage differs in length from the row.

ArgumentOutOfRangeException

opacity is outside 0..1, or an enum value is not defined.

Blend<TPixel>(BlendMode, RgbaF32, Span<TPixel>, ReadOnlySpan<byte>, float, ColorSpace)

Blends one float color onto every pixel of destination through per-pixel coverage. The color keeps its full precision: a float or 16-bit destination blends it as it is, values above 1 included, and an 8-bit destination blends it rounded to 8 bits, exactly as the Rgba8 overload does.

public static void Blend<TPixel>(BlendMode mode, RgbaF32 color, Span<TPixel> destination, ReadOnlySpan<byte> coverage, float opacity = 1, ColorSpace colorSpace = ColorSpace.Encoded) where TPixel : unmanaged, IPixelType<TPixel>

Parameters

mode BlendMode

How the color combines with each pixel.

color RgbaF32

The color, with straight alpha.

destination Span<TPixel>

The pixels to change.

coverage ReadOnlySpan<byte>

One coverage value per pixel, 0 to 255; the same length as destination.

opacity float

Multiplies the color's alpha before the mode: 1 uses it as it is.

colorSpace ColorSpace

Where pixels are blended. Defaults to Encoded.

Type Parameters

TPixel

The pixel type of the row.

Examples

// Blend rows in your own code: a source row, a destination row, and coverage from an antialiased edge.
Rgba8[] source = new Rgba8[256], destination = new Rgba8[256];
byte[] coverage = new byte[256];
for (int x = 0; x < 256; x++)
{
    source[x] = new Rgba8((byte)x, 80, 200, 255);
    destination[x] = new Rgba8(250, 250, 240, 255);
    coverage[x] = (byte)Math.Clamp((x - 100) * 8, 0, 255);   // a soft edge from x = 100 to 132
}

Compositor.Blend<Rgba8>(BlendMode.Multiply, source, destination, coverage);

// One color through coverage, the way a rasterizer fills a shape's spans.
Compositor.Blend(BlendMode.SourceOver, new Rgba8(255, 0, 0, 128), destination.AsSpan(), coverage);

Exceptions

ArgumentException

The coverage differs in length from the row, or the color is not finite.

ArgumentOutOfRangeException

opacity is outside 0..1, or an enum value is not defined.

Blend<TPixel>(BlendMode, ReadOnlySpan<TPixel>, Span<TPixel>, ReadOnlySpan<byte>, float, ColorSpace)

Blends source onto destination through per-pixel coverage, as an antialiased edge needs: each result is mixed with the original destination pixel by its coverage, so 0 leaves the pixel as it was and 255 gives the full blend.

public static void Blend<TPixel>(BlendMode mode, ReadOnlySpan<TPixel> source, Span<TPixel> destination, ReadOnlySpan<byte> coverage, float opacity = 1, ColorSpace colorSpace = ColorSpace.Encoded) where TPixel : unmanaged, IPixelType<TPixel>

Parameters

mode BlendMode

How each source pixel combines with the destination pixel under it.

source ReadOnlySpan<TPixel>

The pixels to blend on top.

destination Span<TPixel>

The pixels to change; the same length as source.

coverage ReadOnlySpan<byte>

One coverage value per pixel, 0 to 255; the same length as destination.

opacity float

Multiplies the source's alpha before the mode: 1 uses it as it is.

colorSpace ColorSpace

Where pixels are blended. Defaults to Encoded.

Type Parameters

TPixel

The pixel type of both rows.

Examples

// Blend rows in your own code: a source row, a destination row, and coverage from an antialiased edge.
Rgba8[] source = new Rgba8[256], destination = new Rgba8[256];
byte[] coverage = new byte[256];
for (int x = 0; x < 256; x++)
{
    source[x] = new Rgba8((byte)x, 80, 200, 255);
    destination[x] = new Rgba8(250, 250, 240, 255);
    coverage[x] = (byte)Math.Clamp((x - 100) * 8, 0, 255);   // a soft edge from x = 100 to 132
}

Compositor.Blend<Rgba8>(BlendMode.Multiply, source, destination, coverage);

// One color through coverage, the way a rasterizer fills a shape's spans.
Compositor.Blend(BlendMode.SourceOver, new Rgba8(255, 0, 0, 128), destination.AsSpan(), coverage);

Exceptions

ArgumentException

The rows or the coverage differ in length.

ArgumentOutOfRangeException

opacity is outside 0..1, or an enum value is not defined.

Blend<TPixel>(BlendMode, ReadOnlySpan<TPixel>, Span<TPixel>, float, ColorSpace)

Blends source onto destination, pixel by pixel, in place.

public static void Blend<TPixel>(BlendMode mode, ReadOnlySpan<TPixel> source, Span<TPixel> destination, float opacity = 1, ColorSpace colorSpace = ColorSpace.Encoded) where TPixel : unmanaged, IPixelType<TPixel>

Parameters

mode BlendMode

How each source pixel combines with the destination pixel under it.

source ReadOnlySpan<TPixel>

The pixels to blend on top.

destination Span<TPixel>

The pixels to change; the same length as source.

opacity float

Multiplies the source's alpha before the mode: 1 uses it as it is.

colorSpace ColorSpace

Where pixels are blended. Defaults to Encoded; Linear uses the sRGB curve.

Type Parameters

TPixel

The pixel type of both rows.

Examples

// Blend rows in your own code: a source row, a destination row, and coverage from an antialiased edge.
Rgba8[] source = new Rgba8[256], destination = new Rgba8[256];
byte[] coverage = new byte[256];
for (int x = 0; x < 256; x++)
{
    source[x] = new Rgba8((byte)x, 80, 200, 255);
    destination[x] = new Rgba8(250, 250, 240, 255);
    coverage[x] = (byte)Math.Clamp((x - 100) * 8, 0, 255);   // a soft edge from x = 100 to 132
}

Compositor.Blend<Rgba8>(BlendMode.Multiply, source, destination, coverage);

// One color through coverage, the way a rasterizer fills a shape's spans.
Compositor.Blend(BlendMode.SourceOver, new Rgba8(255, 0, 0, 128), destination.AsSpan(), coverage);

Exceptions

ArgumentException

The rows differ in length.

ArgumentOutOfRangeException

opacity is outside 0..1, or an enum value is not defined.