Browse Source

Pixel-agnostic Binarization processors

pull/908/head
Anton Firszov 7 years ago
parent
commit
e22c5b5c3f
  1. 2
      src/ImageSharp/Color.cs
  2. 47
      src/ImageSharp/Processing/BinaryDiffuseExtensions.cs
  3. 40
      src/ImageSharp/Processing/BinaryDitherExtensions.cs
  4. 49
      src/ImageSharp/Processing/BinaryThresholdExtensions.cs
  5. 68
      src/ImageSharp/Processing/Processors/Binarization/BinaryErrorDiffusionProcessor.cs
  6. 77
      src/ImageSharp/Processing/Processors/Binarization/BinaryErrorDiffusionProcessor{TPixel}.cs
  7. 67
      src/ImageSharp/Processing/Processors/Binarization/BinaryOrderedDitherProcessor.cs
  8. 75
      src/ImageSharp/Processing/Processors/Binarization/BinaryOrderedDitherProcessor{TPixel}.cs
  9. 63
      src/ImageSharp/Processing/Processors/Binarization/BinaryThresholdProcessor.cs
  10. 70
      src/ImageSharp/Processing/Processors/Binarization/BinaryThresholdProcessor{TPixel}.cs
  11. 2
      src/ImageSharp/Processing/Processors/Convolution/EdgeDetector2DProcessor{TPixel}.cs
  12. 2
      src/ImageSharp/Processing/Processors/Convolution/EdgeDetectorCompassProcessor{TPixel}.cs
  13. 2
      src/ImageSharp/Processing/Processors/Convolution/EdgeDetectorProcessor{TPixel}.cs
  14. 8
      src/ImageSharp/Processing/Processors/Convolution/SobelProcessor.cs
  15. 8
      src/ImageSharp/Processing/Processors/Filters/GrayscaleBt709Processor.cs
  16. 15
      src/ImageSharp/Processing/Processors/ImageProcessorExtensions.cs
  17. 4
      src/ImageSharp/Processing/Processors/Transforms/EntropyCropProcessor{TPixel}.cs
  18. 717
      src/ImageSharp/Source/ImageSharp/Color.NamedColors.cs
  19. 54
      tests/ImageSharp.Tests/Processing/Binarization/BinaryDitherTest.cs
  20. 28
      tests/ImageSharp.Tests/Processing/Binarization/BinaryThresholdTest.cs

2
src/ImageSharp/Color.cs

@ -7,7 +7,7 @@ using SixLabors.ImageSharp.PixelFormats;
namespace SixLabors.ImageSharp
{
public readonly struct Color
public readonly partial struct Color
{
private readonly Rgba64 data;

47
src/ImageSharp/Processing/BinaryDiffuseExtensions.cs

@ -1,7 +1,6 @@
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
using SixLabors.ImageSharp.PixelFormats;
using SixLabors.ImageSharp.Processing.Processors.Binarization;
using SixLabors.ImageSharp.Processing.Processors.Dithering;
using SixLabors.Primitives;
@ -9,7 +8,7 @@ using SixLabors.Primitives;
namespace SixLabors.ImageSharp.Processing
{
/// <summary>
/// Defines extension methods to apply binary diffusion on an <see cref="Image{TPixel}"/>
/// Defines extension methods to apply binary diffusion on an <see cref="Image"/>
/// using Mutate/Clone.
/// </summary>
public static class BinaryDiffuseExtensions
@ -17,19 +16,19 @@ namespace SixLabors.ImageSharp.Processing
/// <summary>
/// Dithers the image reducing it to two colors using error diffusion.
/// </summary>
/// <typeparam name="TPixel">The pixel format.</typeparam>
/// <param name="source">The image this method extends.</param>
/// <param name="diffuser">The diffusion algorithm to apply.</param>
/// <param name="threshold">The threshold to apply binarization of the image. Must be between 0 and 1.</param>
/// <returns>The <see cref="IImageProcessingContext{TPixel}"/> to allow chaining of operations.</returns>
public static IImageProcessingContext<TPixel> BinaryDiffuse<TPixel>(this IImageProcessingContext<TPixel> source, IErrorDiffuser diffuser, float threshold)
where TPixel : struct, IPixel<TPixel>
=> source.ApplyProcessor(new BinaryErrorDiffusionProcessor<TPixel>(diffuser, threshold));
public static IImageProcessingContext BinaryDiffuse(
this IImageProcessingContext source,
IErrorDiffuser diffuser,
float threshold) =>
source.ApplyProcessor(new BinaryErrorDiffusionProcessor(diffuser, threshold));
/// <summary>
/// Dithers the image reducing it to two colors using error diffusion.
/// </summary>
/// <typeparam name="TPixel">The pixel format.</typeparam>
/// <param name="source">The image this method extends.</param>
/// <param name="diffuser">The diffusion algorithm to apply.</param>
/// <param name="threshold">The threshold to apply binarization of the image. Must be between 0 and 1.</param>
@ -37,28 +36,33 @@ namespace SixLabors.ImageSharp.Processing
/// The <see cref="Rectangle"/> structure that specifies the portion of the image object to alter.
/// </param>
/// <returns>The <see cref="IImageProcessingContext{TPixel}"/> to allow chaining of operations.</returns>
public static IImageProcessingContext<TPixel> BinaryDiffuse<TPixel>(this IImageProcessingContext<TPixel> source, IErrorDiffuser diffuser, float threshold, Rectangle rectangle)
where TPixel : struct, IPixel<TPixel>
=> source.ApplyProcessor(new BinaryErrorDiffusionProcessor<TPixel>(diffuser, threshold), rectangle);
public static IImageProcessingContext BinaryDiffuse(
this IImageProcessingContext source,
IErrorDiffuser diffuser,
float threshold,
Rectangle rectangle) =>
source.ApplyProcessor(new BinaryErrorDiffusionProcessor(diffuser, threshold), rectangle);
/// <summary>
/// Dithers the image reducing it to two colors using error diffusion.
/// </summary>
/// <typeparam name="TPixel">The pixel format.</typeparam>
/// <param name="source">The image this method extends.</param>
/// <param name="diffuser">The diffusion algorithm to apply.</param>
/// <param name="threshold">The threshold to apply binarization of the image. Must be between 0 and 1.</param>
/// <param name="upperColor">The color to use for pixels that are above the threshold.</param>
/// <param name="lowerColor">The color to use for pixels that are below the threshold</param>
/// <returns>The <see cref="IImageProcessingContext{TPixel}"/> to allow chaining of operations.</returns>
public static IImageProcessingContext<TPixel> BinaryDiffuse<TPixel>(this IImageProcessingContext<TPixel> source, IErrorDiffuser diffuser, float threshold, TPixel upperColor, TPixel lowerColor)
where TPixel : struct, IPixel<TPixel>
=> source.ApplyProcessor(new BinaryErrorDiffusionProcessor<TPixel>(diffuser, threshold, upperColor, lowerColor));
public static IImageProcessingContext BinaryDiffuse(
this IImageProcessingContext source,
IErrorDiffuser diffuser,
float threshold,
Color upperColor,
Color lowerColor) =>
source.ApplyProcessor(new BinaryErrorDiffusionProcessor(diffuser, threshold, upperColor, lowerColor));
/// <summary>
/// Dithers the image reducing it to two colors using error diffusion.
/// </summary>
/// <typeparam name="TPixel">The pixel format.</typeparam>
/// <param name="source">The image this method extends.</param>
/// <param name="diffuser">The diffusion algorithm to apply.</param>
/// <param name="threshold">The threshold to apply binarization of the image. Must be between 0 and 1.</param>
@ -68,8 +72,15 @@ namespace SixLabors.ImageSharp.Processing
/// The <see cref="Rectangle"/> structure that specifies the portion of the image object to alter.
/// </param>
/// <returns>The <see cref="IImageProcessingContext{TPixel}"/> to allow chaining of operations.</returns>
public static IImageProcessingContext<TPixel> BinaryDiffuse<TPixel>(this IImageProcessingContext<TPixel> source, IErrorDiffuser diffuser, float threshold, TPixel upperColor, TPixel lowerColor, Rectangle rectangle)
where TPixel : struct, IPixel<TPixel>
=> source.ApplyProcessor(new BinaryErrorDiffusionProcessor<TPixel>(diffuser, threshold, upperColor, lowerColor), rectangle);
public static IImageProcessingContext BinaryDiffuse(
this IImageProcessingContext source,
IErrorDiffuser diffuser,
float threshold,
Color upperColor,
Color lowerColor,
Rectangle rectangle) =>
source.ApplyProcessor(
new BinaryErrorDiffusionProcessor(diffuser, threshold, upperColor, lowerColor),
rectangle);
}
}

40
src/ImageSharp/Processing/BinaryDitherExtensions.cs

@ -1,7 +1,6 @@
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
using SixLabors.ImageSharp.PixelFormats;
using SixLabors.ImageSharp.Processing.Processors.Binarization;
using SixLabors.ImageSharp.Processing.Processors.Dithering;
using SixLabors.Primitives;
@ -9,7 +8,7 @@ using SixLabors.Primitives;
namespace SixLabors.ImageSharp.Processing
{
/// <summary>
/// Defines extensions to apply binary dithering on an <see cref="Image{TPixel}"/>
/// Defines extensions to apply binary dithering on an <see cref="Image"/>
/// using Mutate/Clone.
/// </summary>
public static class BinaryDitherExtensions
@ -17,45 +16,46 @@ namespace SixLabors.ImageSharp.Processing
/// <summary>
/// Dithers the image reducing it to two colors using ordered dithering.
/// </summary>
/// <typeparam name="TPixel">The pixel format.</typeparam>
/// <param name="source">The image this method extends.</param>
/// <param name="dither">The ordered ditherer.</param>
/// <returns>The <see cref="IImageProcessingContext{TPixel}"/> to allow chaining of operations.</returns>
public static IImageProcessingContext<TPixel> BinaryDither<TPixel>(this IImageProcessingContext<TPixel> source, IOrderedDither dither)
where TPixel : struct, IPixel<TPixel>
=> source.ApplyProcessor(new BinaryOrderedDitherProcessor<TPixel>(dither));
public static IImageProcessingContext
BinaryDither(this IImageProcessingContext source, IOrderedDither dither) =>
source.ApplyProcessor(new BinaryOrderedDitherProcessor(dither));
/// <summary>
/// Dithers the image reducing it to two colors using ordered dithering.
/// </summary>
/// <typeparam name="TPixel">The pixel format.</typeparam>
/// <param name="source">The image this method extends.</param>
/// <param name="dither">The ordered ditherer.</param>
/// <param name="upperColor">The color to use for pixels that are above the threshold.</param>
/// <param name="lowerColor">The color to use for pixels that are below the threshold</param>
/// <returns>The <see cref="IImageProcessingContext{TPixel}"/> to allow chaining of operations.</returns>
public static IImageProcessingContext<TPixel> BinaryDither<TPixel>(this IImageProcessingContext<TPixel> source, IOrderedDither dither, TPixel upperColor, TPixel lowerColor)
where TPixel : struct, IPixel<TPixel>
=> source.ApplyProcessor(new BinaryOrderedDitherProcessor<TPixel>(dither, upperColor, lowerColor));
public static IImageProcessingContext BinaryDither(
this IImageProcessingContext source,
IOrderedDither dither,
Color upperColor,
Color lowerColor) =>
source.ApplyProcessor(new BinaryOrderedDitherProcessor(dither, upperColor, lowerColor));
/// <summary>
/// Dithers the image reducing it to two colors using ordered dithering.
/// </summary>
/// <typeparam name="TPixel">The pixel format.</typeparam>
/// <param name="source">The image this method extends.</param>
/// <param name="dither">The ordered ditherer.</param>
/// <param name="rectangle">
/// The <see cref="Rectangle"/> structure that specifies the portion of the image object to alter.
/// </param>
/// <returns>The <see cref="IImageProcessingContext{TPixel}"/> to allow chaining of operations.</returns>
public static IImageProcessingContext<TPixel> BinaryDither<TPixel>(this IImageProcessingContext<TPixel> source, IOrderedDither dither, Rectangle rectangle)
where TPixel : struct, IPixel<TPixel>
=> source.ApplyProcessor(new BinaryOrderedDitherProcessor<TPixel>(dither), rectangle);
public static IImageProcessingContext BinaryDither(
this IImageProcessingContext source,
IOrderedDither dither,
Rectangle rectangle) =>
source.ApplyProcessor(new BinaryOrderedDitherProcessor(dither), rectangle);
/// <summary>
/// Dithers the image reducing it to two colors using ordered dithering.
/// </summary>
/// <typeparam name="TPixel">The pixel format.</typeparam>
/// <param name="source">The image this method extends.</param>
/// <param name="dither">The ordered ditherer.</param>
/// <param name="upperColor">The color to use for pixels that are above the threshold.</param>
@ -64,8 +64,12 @@ namespace SixLabors.ImageSharp.Processing
/// The <see cref="Rectangle"/> structure that specifies the portion of the image object to alter.
/// </param>
/// <returns>The <see cref="IImageProcessingContext{TPixel}"/> to allow chaining of operations.</returns>
public static IImageProcessingContext<TPixel> BinaryDither<TPixel>(this IImageProcessingContext<TPixel> source, IOrderedDither dither, TPixel upperColor, TPixel lowerColor, Rectangle rectangle)
where TPixel : struct, IPixel<TPixel>
=> source.ApplyProcessor(new BinaryOrderedDitherProcessor<TPixel>(dither, upperColor, lowerColor), rectangle);
public static IImageProcessingContext BinaryDither(
this IImageProcessingContext source,
IOrderedDither dither,
Color upperColor,
Color lowerColor,
Rectangle rectangle) =>
source.ApplyProcessor(new BinaryOrderedDitherProcessor(dither, upperColor, lowerColor), rectangle);
}
}

49
src/ImageSharp/Processing/BinaryThresholdExtensions.cs

@ -1,14 +1,13 @@
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
using SixLabors.ImageSharp.PixelFormats;
using SixLabors.ImageSharp.Processing.Processors.Binarization;
using SixLabors.Primitives;
namespace SixLabors.ImageSharp.Processing
{
/// <summary>
/// Defines extension methods to apply binary thresholding on an <see cref="Image{TPixel}"/>
/// Defines extension methods to apply binary thresholding on an <see cref="Image"/>
/// using Mutate/Clone.
/// </summary>
public static class BinaryThresholdExtensions
@ -16,45 +15,45 @@ namespace SixLabors.ImageSharp.Processing
/// <summary>
/// Applies binarization to the image splitting the pixels at the given threshold.
/// </summary>
/// <typeparam name="TPixel">The pixel format.</typeparam>
/// <param name="source">The image this method extends.</param>
/// <param name="threshold">The threshold to apply binarization of the image. Must be between 0 and 1.</param>
/// <returns>The <see cref="IImageProcessingContext{TPixel}"/> to allow chaining of operations.</returns>
public static IImageProcessingContext<TPixel> BinaryThreshold<TPixel>(this IImageProcessingContext<TPixel> source, float threshold)
where TPixel : struct, IPixel<TPixel>
=> source.ApplyProcessor(new BinaryThresholdProcessor<TPixel>(threshold));
/// <returns>The <see cref="IImageProcessingContext"/> to allow chaining of operations.</returns>
public static IImageProcessingContext BinaryThreshold(this IImageProcessingContext source, float threshold) =>
source.ApplyProcessor(new BinaryThresholdProcessor(threshold));
/// <summary>
/// Applies binarization to the image splitting the pixels at the given threshold.
/// </summary>
/// <typeparam name="TPixel">The pixel format.</typeparam>
/// <param name="source">The image this method extends.</param>
/// <param name="threshold">The threshold to apply binarization of the image. Must be between 0 and 1.</param>
/// <param name="rectangle">
/// The <see cref="Rectangle"/> structure that specifies the portion of the image object to alter.
/// </param>
/// <returns>The <see cref="IImageProcessingContext{TPixel}"/> to allow chaining of operations.</returns>
public static IImageProcessingContext<TPixel> BinaryThreshold<TPixel>(this IImageProcessingContext<TPixel> source, float threshold, Rectangle rectangle)
where TPixel : struct, IPixel<TPixel>
=> source.ApplyProcessor(new BinaryThresholdProcessor<TPixel>(threshold), rectangle);
/// <returns>The <see cref="IImageProcessingContext"/> to allow chaining of operations.</returns>
public static IImageProcessingContext BinaryThreshold(
this IImageProcessingContext source,
float threshold,
Rectangle rectangle) =>
source.ApplyProcessor(new BinaryThresholdProcessor(threshold), rectangle);
/// <summary>
/// Applies binarization to the image splitting the pixels at the given threshold.
/// </summary>
/// <typeparam name="TPixel">The pixel format.</typeparam>
/// <param name="source">The image this method extends.</param>
/// <param name="threshold">The threshold to apply binarization of the image. Must be between 0 and 1.</param>
/// <param name="upperColor">The color to use for pixels that are above the threshold.</param>
/// <param name="lowerColor">The color to use for pixels that are below the threshold</param>
/// <returns>The <see cref="IImageProcessingContext{TPixel}"/> to allow chaining of operations.</returns>
public static IImageProcessingContext<TPixel> BinaryThreshold<TPixel>(this IImageProcessingContext<TPixel> source, float threshold, TPixel upperColor, TPixel lowerColor)
where TPixel : struct, IPixel<TPixel>
=> source.ApplyProcessor(new BinaryThresholdProcessor<TPixel>(threshold, upperColor, lowerColor));
/// <returns>The <see cref="IImageProcessingContext"/> to allow chaining of operations.</returns>
public static IImageProcessingContext BinaryThreshold(
this IImageProcessingContext source,
float threshold,
Color upperColor,
Color lowerColor) =>
source.ApplyProcessor(new BinaryThresholdProcessor(threshold, upperColor, lowerColor));
/// <summary>
/// Applies binarization to the image splitting the pixels at the given threshold.
/// </summary>
/// <typeparam name="TPixel">The pixel format.</typeparam>
/// <param name="source">The image this method extends.</param>
/// <param name="threshold">The threshold to apply binarization of the image. Must be between 0 and 1.</param>
/// <param name="upperColor">The color to use for pixels that are above the threshold.</param>
@ -62,9 +61,13 @@ namespace SixLabors.ImageSharp.Processing
/// <param name="rectangle">
/// The <see cref="Rectangle"/> structure that specifies the portion of the image object to alter.
/// </param>
/// <returns>The <see cref="IImageProcessingContext{TPixel}"/> to allow chaining of operations.</returns>
public static IImageProcessingContext<TPixel> BinaryThreshold<TPixel>(this IImageProcessingContext<TPixel> source, float threshold, TPixel upperColor, TPixel lowerColor, Rectangle rectangle)
where TPixel : struct, IPixel<TPixel>
=> source.ApplyProcessor(new BinaryThresholdProcessor<TPixel>(threshold, upperColor, lowerColor), rectangle);
/// <returns>The <see cref="IImageProcessingContext"/> to allow chaining of operations.</returns>
public static IImageProcessingContext BinaryThreshold(
this IImageProcessingContext source,
float threshold,
Color upperColor,
Color lowerColor,
Rectangle rectangle) =>
source.ApplyProcessor(new BinaryThresholdProcessor(threshold, upperColor, lowerColor), rectangle);
}
}
}

68
src/ImageSharp/Processing/Processors/Binarization/BinaryErrorDiffusionProcessor.cs

@ -2,22 +2,19 @@
// Licensed under the Apache License, Version 2.0.
using System;
using SixLabors.ImageSharp.Advanced;
using SixLabors.ImageSharp.PixelFormats;
using SixLabors.ImageSharp.Processing.Processors.Dithering;
using SixLabors.Primitives;
namespace SixLabors.ImageSharp.Processing.Processors.Binarization
{
/// <summary>
/// Performs binary threshold filtering against an image using error diffusion.
/// </summary>
/// <typeparam name="TPixel">The pixel format.</typeparam>
internal class BinaryErrorDiffusionProcessor<TPixel> : ImageProcessor<TPixel>
where TPixel : struct, IPixel<TPixel>
public class BinaryErrorDiffusionProcessor : IImageProcessor
{
/// <summary>
/// Initializes a new instance of the <see cref="BinaryErrorDiffusionProcessor{TPixel}"/> class.
/// Initializes a new instance of the <see cref="BinaryErrorDiffusionProcessor"/> class.
/// </summary>
/// <param name="diffuser">The error diffuser</param>
public BinaryErrorDiffusionProcessor(IErrorDiffuser diffuser)
@ -26,23 +23,23 @@ namespace SixLabors.ImageSharp.Processing.Processors.Binarization
}
/// <summary>
/// Initializes a new instance of the <see cref="BinaryErrorDiffusionProcessor{TPixel}"/> class.
/// Initializes a new instance of the <see cref="BinaryErrorDiffusionProcessor"/> class.
/// </summary>
/// <param name="diffuser">The error diffuser</param>
/// <param name="threshold">The threshold to split the image. Must be between 0 and 1.</param>
public BinaryErrorDiffusionProcessor(IErrorDiffuser diffuser, float threshold)
: this(diffuser, threshold, NamedColors<TPixel>.White, NamedColors<TPixel>.Black)
: this(diffuser, threshold, Color.White, Color.Black)
{
}
/// <summary>
/// Initializes a new instance of the <see cref="BinaryErrorDiffusionProcessor{TPixel}"/> class.
/// Initializes a new instance of the <see cref="BinaryErrorDiffusionProcessor"/> class.
/// </summary>
/// <param name="diffuser">The error diffuser</param>
/// <param name="threshold">The threshold to split the image. Must be between 0 and 1.</param>
/// <param name="upperColor">The color to use for pixels that are above the threshold.</param>
/// <param name="lowerColor">The color to use for pixels that are below the threshold.</param>
public BinaryErrorDiffusionProcessor(IErrorDiffuser diffuser, float threshold, TPixel upperColor, TPixel lowerColor)
public BinaryErrorDiffusionProcessor(IErrorDiffuser diffuser, float threshold, Color upperColor, Color lowerColor)
{
Guard.NotNull(diffuser, nameof(diffuser));
Guard.MustBeBetweenOrEqualTo(threshold, 0, 1, nameof(threshold));
@ -66,57 +63,18 @@ namespace SixLabors.ImageSharp.Processing.Processors.Binarization
/// <summary>
/// Gets the color to use for pixels that are above the threshold.
/// </summary>
public TPixel UpperColor { get; }
public Color UpperColor { get; }
/// <summary>
/// Gets the color to use for pixels that fall below the threshold.
/// </summary>
public TPixel LowerColor { get; }
public Color LowerColor { get; }
/// <inheritdoc/>
protected override void OnFrameApply(ImageFrame<TPixel> source, Rectangle sourceRectangle, Configuration configuration)
/// <inheritdoc />
public IImageProcessor<TPixel> CreatePixelSpecificProcessor<TPixel>()
where TPixel : struct, IPixel<TPixel>
{
byte threshold = (byte)MathF.Round(this.Threshold * 255F);
bool isAlphaOnly = typeof(TPixel) == typeof(Alpha8);
var interest = Rectangle.Intersect(sourceRectangle, source.Bounds());
int startY = interest.Y;
int endY = interest.Bottom;
int startX = interest.X;
int endX = interest.Right;
// Collect the values before looping so we can reduce our calculation count for identical sibling pixels
TPixel sourcePixel = source[startX, startY];
TPixel previousPixel = sourcePixel;
Rgba32 rgba = default;
sourcePixel.ToRgba32(ref rgba);
// Convert to grayscale using ITU-R Recommendation BT.709 if required
byte luminance = isAlphaOnly ? rgba.A : ImageMaths.Get8BitBT709Luminance(rgba.R, rgba.G, rgba.B);
for (int y = startY; y < endY; y++)
{
Span<TPixel> row = source.GetPixelRowSpan(y);
for (int x = startX; x < endX; x++)
{
sourcePixel = row[x];
// Check if this is the same as the last pixel. If so use that value
// rather than calculating it again. This is an inexpensive optimization.
if (!previousPixel.Equals(sourcePixel))
{
sourcePixel.ToRgba32(ref rgba);
luminance = isAlphaOnly ? rgba.A : ImageMaths.Get8BitBT709Luminance(rgba.R, rgba.G, rgba.B);
// Setup the previous pointer
previousPixel = sourcePixel;
}
TPixel transformedPixel = luminance >= threshold ? this.UpperColor : this.LowerColor;
this.Diffuser.Dither(source, sourcePixel, transformedPixel, x, y, startX, startY, endX, endY);
}
}
return new BinaryErrorDiffusionProcessor<TPixel>(this);
}
}
}

77
src/ImageSharp/Processing/Processors/Binarization/BinaryErrorDiffusionProcessor{TPixel}.cs

@ -0,0 +1,77 @@
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
using System;
using SixLabors.ImageSharp.Advanced;
using SixLabors.ImageSharp.PixelFormats;
using SixLabors.ImageSharp.Processing.Processors.Dithering;
using SixLabors.Primitives;
namespace SixLabors.ImageSharp.Processing.Processors.Binarization
{
/// <summary>
/// Performs binary threshold filtering against an image using error diffusion.
/// </summary>
/// <typeparam name="TPixel">The pixel format.</typeparam>
internal class BinaryErrorDiffusionProcessor<TPixel> : ImageProcessor<TPixel>
where TPixel : struct, IPixel<TPixel>
{
private readonly BinaryErrorDiffusionProcessor definition;
public BinaryErrorDiffusionProcessor(BinaryErrorDiffusionProcessor definition)
{
this.definition = definition;
}
/// <inheritdoc/>
protected override void OnFrameApply(ImageFrame<TPixel> source, Rectangle sourceRectangle, Configuration configuration)
{
TPixel upperColor = this.definition.UpperColor.ToPixel<TPixel>();
TPixel lowerColor = this.definition.LowerColor.ToPixel<TPixel>();
IErrorDiffuser diffuser = this.definition.Diffuser;
byte threshold = (byte)MathF.Round(this.definition.Threshold * 255F);
bool isAlphaOnly = typeof(TPixel) == typeof(Alpha8);
var interest = Rectangle.Intersect(sourceRectangle, source.Bounds());
int startY = interest.Y;
int endY = interest.Bottom;
int startX = interest.X;
int endX = interest.Right;
// Collect the values before looping so we can reduce our calculation count for identical sibling pixels
TPixel sourcePixel = source[startX, startY];
TPixel previousPixel = sourcePixel;
Rgba32 rgba = default;
sourcePixel.ToRgba32(ref rgba);
// Convert to grayscale using ITU-R Recommendation BT.709 if required
byte luminance = isAlphaOnly ? rgba.A : ImageMaths.Get8BitBT709Luminance(rgba.R, rgba.G, rgba.B);
for (int y = startY; y < endY; y++)
{
Span<TPixel> row = source.GetPixelRowSpan(y);
for (int x = startX; x < endX; x++)
{
sourcePixel = row[x];
// Check if this is the same as the last pixel. If so use that value
// rather than calculating it again. This is an inexpensive optimization.
if (!previousPixel.Equals(sourcePixel))
{
sourcePixel.ToRgba32(ref rgba);
luminance = isAlphaOnly ? rgba.A : ImageMaths.Get8BitBT709Luminance(rgba.R, rgba.G, rgba.B);
// Setup the previous pointer
previousPixel = sourcePixel;
}
TPixel transformedPixel = luminance >= threshold ? upperColor : lowerColor;
diffuser.Dither(source, sourcePixel, transformedPixel, x, y, startX, startY, endX, endY);
}
}
}
}
}

67
src/ImageSharp/Processing/Processors/Binarization/BinaryOrderedDitherProcessor.cs

@ -2,36 +2,30 @@
// Licensed under the Apache License, Version 2.0.
using System;
using SixLabors.ImageSharp.Advanced;
using SixLabors.ImageSharp.PixelFormats;
using SixLabors.ImageSharp.Processing.Processors.Dithering;
using SixLabors.Primitives;
namespace SixLabors.ImageSharp.Processing.Processors.Binarization
{
/// <summary>
/// Performs binary threshold filtering against an image using ordered dithering.
/// </summary>
/// <typeparam name="TPixel">The pixel format.</typeparam>
internal class BinaryOrderedDitherProcessor<TPixel> : ImageProcessor<TPixel>
where TPixel : struct, IPixel<TPixel>
public class BinaryOrderedDitherProcessor : IImageProcessor
{
/// <summary>
/// Initializes a new instance of the <see cref="BinaryOrderedDitherProcessor{TPixel}"/> class.
/// Initializes a new instance of the <see cref="BinaryOrderedDitherProcessor"/> class.
/// </summary>
/// <param name="dither">The ordered ditherer.</param>
public BinaryOrderedDitherProcessor(IOrderedDither dither)
: this(dither, NamedColors<TPixel>.White, NamedColors<TPixel>.Black)
: this(dither, Color.White, Color.Black)
{
}
/// <summary>
/// Initializes a new instance of the <see cref="BinaryOrderedDitherProcessor{TPixel}"/> class.
/// Initializes a new instance of the <see cref="BinaryOrderedDitherProcessor"/> class.
/// </summary>
/// <param name="dither">The ordered ditherer.</param>
/// <param name="upperColor">The color to use for pixels that are above the threshold.</param>
/// <param name="lowerColor">The color to use for pixels that are below the threshold.</param>
public BinaryOrderedDitherProcessor(IOrderedDither dither, TPixel upperColor, TPixel lowerColor)
public BinaryOrderedDitherProcessor(IOrderedDither dither, Color upperColor, Color lowerColor)
{
this.Dither = dither ?? throw new ArgumentNullException(nameof(dither));
this.UpperColor = upperColor;
@ -46,55 +40,18 @@ namespace SixLabors.ImageSharp.Processing.Processors.Binarization
/// <summary>
/// Gets the color to use for pixels that are above the threshold.
/// </summary>
public TPixel UpperColor { get; }
public Color UpperColor { get; }
/// <summary>
/// Gets the color to use for pixels that fall below the threshold.
/// </summary>
public TPixel LowerColor { get; }
public Color LowerColor { get; }
/// <inheritdoc/>
protected override void OnFrameApply(ImageFrame<TPixel> source, Rectangle sourceRectangle, Configuration configuration)
/// <inheritdoc />
public IImageProcessor<TPixel> CreatePixelSpecificProcessor<TPixel>()
where TPixel : struct, IPixel<TPixel>
{
bool isAlphaOnly = typeof(TPixel) == typeof(Alpha8);
var interest = Rectangle.Intersect(sourceRectangle, source.Bounds());
int startY = interest.Y;
int endY = interest.Bottom;
int startX = interest.X;
int endX = interest.Right;
// Collect the values before looping so we can reduce our calculation count for identical sibling pixels
TPixel sourcePixel = source[startX, startY];
TPixel previousPixel = sourcePixel;
Rgba32 rgba = default;
sourcePixel.ToRgba32(ref rgba);
// Convert to grayscale using ITU-R Recommendation BT.709 if required
byte luminance = isAlphaOnly ? rgba.A : ImageMaths.Get8BitBT709Luminance(rgba.R, rgba.G, rgba.B);
for (int y = startY; y < endY; y++)
{
Span<TPixel> row = source.GetPixelRowSpan(y);
for (int x = startX; x < endX; x++)
{
sourcePixel = row[x];
// Check if this is the same as the last pixel. If so use that value
// rather than calculating it again. This is an inexpensive optimization.
if (!previousPixel.Equals(sourcePixel))
{
sourcePixel.ToRgba32(ref rgba);
luminance = isAlphaOnly ? rgba.A : ImageMaths.Get8BitBT709Luminance(rgba.R, rgba.G, rgba.B);
// Setup the previous pointer
previousPixel = sourcePixel;
}
this.Dither.Dither(source, sourcePixel, this.UpperColor, this.LowerColor, luminance, x, y);
}
}
return new BinaryOrderedDitherProcessor<TPixel>(this);
}
}
}

75
src/ImageSharp/Processing/Processors/Binarization/BinaryOrderedDitherProcessor{TPixel}.cs

@ -0,0 +1,75 @@
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
using System;
using SixLabors.ImageSharp.Advanced;
using SixLabors.ImageSharp.PixelFormats;
using SixLabors.ImageSharp.Processing.Processors.Dithering;
using SixLabors.Primitives;
namespace SixLabors.ImageSharp.Processing.Processors.Binarization
{
/// <summary>
/// Performs binary threshold filtering against an image using ordered dithering.
/// </summary>
/// <typeparam name="TPixel">The pixel format.</typeparam>
internal class BinaryOrderedDitherProcessor<TPixel> : ImageProcessor<TPixel>
where TPixel : struct, IPixel<TPixel>
{
private readonly BinaryOrderedDitherProcessor definition;
public BinaryOrderedDitherProcessor(BinaryOrderedDitherProcessor definition)
{
this.definition = definition;
}
/// <inheritdoc/>
protected override void OnFrameApply(ImageFrame<TPixel> source, Rectangle sourceRectangle, Configuration configuration)
{
IOrderedDither dither = this.definition.Dither;
TPixel upperColor = this.definition.UpperColor.ToPixel<TPixel>();
TPixel lowerColor = this.definition.LowerColor.ToPixel<TPixel>();
bool isAlphaOnly = typeof(TPixel) == typeof(Alpha8);
var interest = Rectangle.Intersect(sourceRectangle, source.Bounds());
int startY = interest.Y;
int endY = interest.Bottom;
int startX = interest.X;
int endX = interest.Right;
// Collect the values before looping so we can reduce our calculation count for identical sibling pixels
TPixel sourcePixel = source[startX, startY];
TPixel previousPixel = sourcePixel;
Rgba32 rgba = default;
sourcePixel.ToRgba32(ref rgba);
// Convert to grayscale using ITU-R Recommendation BT.709 if required
byte luminance = isAlphaOnly ? rgba.A : ImageMaths.Get8BitBT709Luminance(rgba.R, rgba.G, rgba.B);
for (int y = startY; y < endY; y++)
{
Span<TPixel> row = source.GetPixelRowSpan(y);
for (int x = startX; x < endX; x++)
{
sourcePixel = row[x];
// Check if this is the same as the last pixel. If so use that value
// rather than calculating it again. This is an inexpensive optimization.
if (!previousPixel.Equals(sourcePixel))
{
sourcePixel.ToRgba32(ref rgba);
luminance = isAlphaOnly ? rgba.A : ImageMaths.Get8BitBT709Luminance(rgba.R, rgba.G, rgba.B);
// Setup the previous pointer
previousPixel = sourcePixel;
}
dither.Dither(source, sourcePixel, upperColor, lowerColor, luminance, x, y);
}
}
}
}
}

63
src/ImageSharp/Processing/Processors/Binarization/BinaryThresholdProcessor.cs

@ -3,36 +3,31 @@
using System;
using SixLabors.ImageSharp.Advanced;
using SixLabors.ImageSharp.ParallelUtils;
using SixLabors.ImageSharp.PixelFormats;
using SixLabors.Primitives;
namespace SixLabors.ImageSharp.Processing.Processors.Binarization
{
/// <summary>
/// Performs simple binary threshold filtering against an image.
/// </summary>
/// <typeparam name="TPixel">The pixel format.</typeparam>
internal class BinaryThresholdProcessor<TPixel> : ImageProcessor<TPixel>
where TPixel : struct, IPixel<TPixel>
public class BinaryThresholdProcessor : IImageProcessor
{
/// <summary>
/// Initializes a new instance of the <see cref="BinaryThresholdProcessor{TPixel}"/> class.
/// Initializes a new instance of the <see cref="BinaryThresholdProcessor"/> class.
/// </summary>
/// <param name="threshold">The threshold to split the image. Must be between 0 and 1.</param>
public BinaryThresholdProcessor(float threshold)
: this(threshold, NamedColors<TPixel>.White, NamedColors<TPixel>.Black)
: this(threshold, Color.White, Color.Black)
{
}
/// <summary>
/// Initializes a new instance of the <see cref="BinaryThresholdProcessor{TPixel}"/> class.
/// Initializes a new instance of the <see cref="BinaryThresholdProcessor"/> class.
/// </summary>
/// <param name="threshold">The threshold to split the image. Must be between 0 and 1.</param>
/// <param name="upperColor">The color to use for pixels that are above the threshold.</param>
/// <param name="lowerColor">The color to use for pixels that are below the threshold.</param>
public BinaryThresholdProcessor(float threshold, TPixel upperColor, TPixel lowerColor)
public BinaryThresholdProcessor(float threshold, Color upperColor, Color lowerColor)
{
Guard.MustBeBetweenOrEqualTo(threshold, 0, 1, nameof(threshold));
this.Threshold = threshold;
@ -48,54 +43,18 @@ namespace SixLabors.ImageSharp.Processing.Processors.Binarization
/// <summary>
/// Gets or sets the color to use for pixels that are above the threshold.
/// </summary>
public TPixel UpperColor { get; set; }
public Color UpperColor { get; }
/// <summary>
/// Gets or sets the color to use for pixels that fall below the threshold.
/// </summary>
public TPixel LowerColor { get; set; }
public Color LowerColor { get; }
/// <inheritdoc/>
protected override void OnFrameApply(
ImageFrame<TPixel> source,
Rectangle sourceRectangle,
Configuration configuration)
/// <inheritdoc />
public IImageProcessor<TPixel> CreatePixelSpecificProcessor<TPixel>()
where TPixel : struct, IPixel<TPixel>
{
byte threshold = (byte)MathF.Round(this.Threshold * 255F);
TPixel upper = this.UpperColor;
TPixel lower = this.LowerColor;
var interest = Rectangle.Intersect(sourceRectangle, source.Bounds());
int startY = interest.Y;
int endY = interest.Bottom;
int startX = interest.X;
int endX = interest.Right;
bool isAlphaOnly = typeof(TPixel) == typeof(Alpha8);
var workingRect = Rectangle.FromLTRB(startX, startY, endX, endY);
ParallelHelper.IterateRows(
workingRect,
configuration,
rows =>
{
Rgba32 rgba = default;
for (int y = rows.Min; y < rows.Max; y++)
{
Span<TPixel> row = source.GetPixelRowSpan(y);
for (int x = startX; x < endX; x++)
{
ref TPixel color = ref row[x];
color.ToRgba32(ref rgba);
// Convert to grayscale using ITU-R Recommendation BT.709 if required
byte luminance = isAlphaOnly ? rgba.A : ImageMaths.Get8BitBT709Luminance(rgba.R, rgba.G, rgba.B);
color = luminance >= threshold ? upper : lower;
}
}
});
return new BinaryThresholdProcessor<TPixel>(this);
}
}
}

70
src/ImageSharp/Processing/Processors/Binarization/BinaryThresholdProcessor{TPixel}.cs

@ -0,0 +1,70 @@
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
using System;
using SixLabors.ImageSharp.Advanced;
using SixLabors.ImageSharp.ParallelUtils;
using SixLabors.ImageSharp.PixelFormats;
using SixLabors.Primitives;
namespace SixLabors.ImageSharp.Processing.Processors.Binarization
{
/// <summary>
/// Performs simple binary threshold filtering against an image.
/// </summary>
/// <typeparam name="TPixel">The pixel format.</typeparam>
internal class BinaryThresholdProcessor<TPixel> : ImageProcessor<TPixel>
where TPixel : struct, IPixel<TPixel>
{
private readonly BinaryThresholdProcessor definition;
public BinaryThresholdProcessor(BinaryThresholdProcessor definition)
{
this.definition = definition;
}
/// <inheritdoc/>
protected override void OnFrameApply(
ImageFrame<TPixel> source,
Rectangle sourceRectangle,
Configuration configuration)
{
byte threshold = (byte)MathF.Round(this.definition.Threshold * 255F);
TPixel upper = this.definition.UpperColor.ToPixel<TPixel>();
TPixel lower = this.definition.LowerColor.ToPixel<TPixel>();
var interest = Rectangle.Intersect(sourceRectangle, source.Bounds());
int startY = interest.Y;
int endY = interest.Bottom;
int startX = interest.X;
int endX = interest.Right;
bool isAlphaOnly = typeof(TPixel) == typeof(Alpha8);
var workingRect = Rectangle.FromLTRB(startX, startY, endX, endY);
ParallelHelper.IterateRows(
workingRect,
configuration,
rows =>
{
Rgba32 rgba = default;
for (int y = rows.Min; y < rows.Max; y++)
{
Span<TPixel> row = source.GetPixelRowSpan(y);
for (int x = startX; x < endX; x++)
{
ref TPixel color = ref row[x];
color.ToRgba32(ref rgba);
// Convert to grayscale using ITU-R Recommendation BT.709 if required
byte luminance = isAlphaOnly ? rgba.A : ImageMaths.Get8BitBT709Luminance(rgba.R, rgba.G, rgba.B);
color = luminance >= threshold ? upper : lower;
}
}
});
}
}
}

2
src/ImageSharp/Processing/Processors/Convolution/EdgeDetector2DProcessor{TPixel}.cs

@ -50,7 +50,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Convolution
{
if (this.Grayscale)
{
new GrayscaleBt709Processor(1F).ApplyToFrame(source, sourceRectangle, configuration);
new GrayscaleBt709Processor(1F).Apply(source, sourceRectangle, configuration);
}
}
}

2
src/ImageSharp/Processing/Processors/Convolution/EdgeDetectorCompassProcessor{TPixel}.cs

@ -42,7 +42,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Convolution
{
if (this.Grayscale)
{
new GrayscaleBt709Processor(1F).ApplyToFrame(source, sourceRectangle, configuration);
new GrayscaleBt709Processor(1F).Apply(source, sourceRectangle, configuration);
}
}

2
src/ImageSharp/Processing/Processors/Convolution/EdgeDetectorProcessor{TPixel}.cs

@ -38,7 +38,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Convolution
{
if (this.Grayscale)
{
new GrayscaleBt709Processor(1F).ApplyToFrame(source, sourceRectangle, configuration);
new GrayscaleBt709Processor(1F).Apply(source, sourceRectangle, configuration);
}
}

8
src/ImageSharp/Processing/Processors/Convolution/SobelProcessor.cs

@ -26,13 +26,5 @@ namespace SixLabors.ImageSharp.Processing.Processors.Convolution
{
return new EdgeDetector2DProcessor<TPixel>(SobelKernels.SobelX, SobelKernels.SobelY, this.Grayscale);
}
// TODO: Move this to an appropriate extension method if possible.
internal void ApplyToFrame<TPixel>(ImageFrame<TPixel> frame, Rectangle sourceRectangle, Configuration configuration)
where TPixel : struct, IPixel<TPixel>
{
var processorImpl = new EdgeDetector2DProcessor<TPixel>(SobelKernels.SobelX, SobelKernels.SobelY, this.Grayscale);
processorImpl.Apply(frame, sourceRectangle, configuration);
}
}
}

8
src/ImageSharp/Processing/Processors/Filters/GrayscaleBt709Processor.cs

@ -25,13 +25,5 @@ namespace SixLabors.ImageSharp.Processing.Processors.Filters
/// Gets the proportion of the conversion.
/// </summary>
public float Amount { get; }
// TODO: Move this to an appropriate extension method if possible.
internal void ApplyToFrame<TPixel>(ImageFrame<TPixel> frame, Rectangle sourceRectangle, Configuration configuration)
where TPixel : struct, IPixel<TPixel>
{
var processorImpl = new FilterProcessor<TPixel>(new GrayscaleBt709Processor(1F));
processorImpl.Apply(frame, sourceRectangle, configuration);
}
}
}

15
src/ImageSharp/Processing/Processors/ImageProcessorExtensions.cs

@ -14,6 +14,21 @@ namespace SixLabors.ImageSharp.Processing.Processors
source.AcceptVisitor(visitor);
}
/// <summary>
/// Apply an <see cref="IImageProcessor"/> to a frame.
/// Only works from processors implemented by an <see cref="ImageProcessor{TPixel}"/> subclass.
/// </summary>
internal static void Apply<TPixel>(
this IImageProcessor processor,
ImageFrame<TPixel> frame,
Rectangle sourceRectangle,
Configuration configuration)
where TPixel : struct, IPixel<TPixel>
{
var processorImpl = (ImageProcessor<TPixel>)processor.CreatePixelSpecificProcessor<TPixel>();
processorImpl.Apply(frame, sourceRectangle, configuration);
}
private class ApplyVisitor : IImageVisitor
{
private readonly IImageProcessor processor;

4
src/ImageSharp/Processing/Processors/Transforms/EntropyCropProcessor{TPixel}.cs

@ -38,10 +38,10 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms
Configuration configuration = source.GetConfiguration();
// Detect the edges.
new SobelProcessor(false).ApplyToFrame(temp, sourceRectangle, configuration);
new SobelProcessor(false).Apply(temp, sourceRectangle, configuration);
// Apply threshold binarization filter.
new BinaryThresholdProcessor<TPixel>(this.definition.Threshold).Apply(temp, sourceRectangle, configuration);
new BinaryThresholdProcessor(this.definition.Threshold).Apply(temp, sourceRectangle, configuration);
// Search for the first white pixels
rectangle = ImageMaths.GetFilteredBoundingRectangle(temp, 0);

717
src/ImageSharp/Source/ImageSharp/Color.NamedColors.cs

@ -0,0 +1,717 @@
// // Copyright (c) Six Labors and contributors.
// // Licensed under the Apache License, Version 2.0.
namespace SixLabors.ImageSharp
{
public readonly partial struct Color
{
/// <summary>
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #F0F8FF.
/// </summary>
public static readonly Color AliceBlue = FromRgba(240, 248, 255, 255);
/// <summary>
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #FAEBD7.
/// </summary>
public static readonly Color AntiqueWhite = FromRgba(250, 235, 215, 255);
/// <summary>
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #00FFFF.
/// </summary>
public static readonly Color Aqua = FromRgba(0, 255, 255, 255);
/// <summary>
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #7FFFD4.
/// </summary>
public static readonly Color Aquamarine = FromRgba(127, 255, 212, 255);
/// <summary>
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #F0FFFF.
/// </summary>
public static readonly Color Azure = FromRgba(240, 255, 255, 255);
/// <summary>
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #F5F5DC.
/// </summary>
public static readonly Color Beige = FromRgba(245, 245, 220, 255);
/// <summary>
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #FFE4C4.
/// </summary>
public static readonly Color Bisque = FromRgba(255, 228, 196, 255);
/// <summary>
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #000000.
/// </summary>
public static readonly Color Black = FromRgba(0, 0, 0, 255);
/// <summary>
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #FFEBCD.
/// </summary>
public static readonly Color BlanchedAlmond = FromRgba(255, 235, 205, 255);
/// <summary>
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #0000FF.
/// </summary>
public static readonly Color Blue = FromRgba(0, 0, 255, 255);
/// <summary>
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #8A2BE2.
/// </summary>
public static readonly Color BlueViolet = FromRgba(138, 43, 226, 255);
/// <summary>
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #A52A2A.
/// </summary>
public static readonly Color Brown = FromRgba(165, 42, 42, 255);
/// <summary>
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #DEB887.
/// </summary>
public static readonly Color BurlyWood = FromRgba(222, 184, 135, 255);
/// <summary>
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #5F9EA0.
/// </summary>
public static readonly Color CadetBlue = FromRgba(95, 158, 160, 255);
/// <summary>
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #7FFF00.
/// </summary>
public static readonly Color Chartreuse = FromRgba(127, 255, 0, 255);
/// <summary>
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #D2691E.
/// </summary>
public static readonly Color Chocolate = FromRgba(210, 105, 30, 255);
/// <summary>
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #FF7F50.
/// </summary>
public static readonly Color Coral = FromRgba(255, 127, 80, 255);
/// <summary>
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #6495ED.
/// </summary>
public static readonly Color CornflowerBlue = FromRgba(100, 149, 237, 255);
/// <summary>
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #FFF8DC.
/// </summary>
public static readonly Color Cornsilk = FromRgba(255, 248, 220, 255);
/// <summary>
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #DC143C.
/// </summary>
public static readonly Color Crimson = FromRgba(220, 20, 60, 255);
/// <summary>
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #00FFFF.
/// </summary>
public static readonly Color Cyan = FromRgba(0, 255, 255, 255);
/// <summary>
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #00008B.
/// </summary>
public static readonly Color DarkBlue = FromRgba(0, 0, 139, 255);
/// <summary>
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #008B8B.
/// </summary>
public static readonly Color DarkCyan = FromRgba(0, 139, 139, 255);
/// <summary>
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #B8860B.
/// </summary>
public static readonly Color DarkGoldenrod = FromRgba(184, 134, 11, 255);
/// <summary>
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #A9A9A9.
/// </summary>
public static readonly Color DarkGray = FromRgba(169, 169, 169, 255);
/// <summary>
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #006400.
/// </summary>
public static readonly Color DarkGreen = FromRgba(0, 100, 0, 255);
/// <summary>
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #BDB76B.
/// </summary>
public static readonly Color DarkKhaki = FromRgba(189, 183, 107, 255);
/// <summary>
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #8B008B.
/// </summary>
public static readonly Color DarkMagenta = FromRgba(139, 0, 139, 255);
/// <summary>
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #556B2F.
/// </summary>
public static readonly Color DarkOliveGreen = FromRgba(85, 107, 47, 255);
/// <summary>
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #FF8C00.
/// </summary>
public static readonly Color DarkOrange = FromRgba(255, 140, 0, 255);
/// <summary>
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #9932CC.
/// </summary>
public static readonly Color DarkOrchid = FromRgba(153, 50, 204, 255);
/// <summary>
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #8B0000.
/// </summary>
public static readonly Color DarkRed = FromRgba(139, 0, 0, 255);
/// <summary>
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #E9967A.
/// </summary>
public static readonly Color DarkSalmon = FromRgba(233, 150, 122, 255);
/// <summary>
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #8FBC8B.
/// </summary>
public static readonly Color DarkSeaGreen = FromRgba(143, 188, 139, 255);
/// <summary>
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #483D8B.
/// </summary>
public static readonly Color DarkSlateBlue = FromRgba(72, 61, 139, 255);
/// <summary>
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #2F4F4F.
/// </summary>
public static readonly Color DarkSlateGray = FromRgba(47, 79, 79, 255);
/// <summary>
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #00CED1.
/// </summary>
public static readonly Color DarkTurquoise = FromRgba(0, 206, 209, 255);
/// <summary>
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #9400D3.
/// </summary>
public static readonly Color DarkViolet = FromRgba(148, 0, 211, 255);
/// <summary>
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #FF1493.
/// </summary>
public static readonly Color DeepPink = FromRgba(255, 20, 147, 255);
/// <summary>
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #00BFFF.
/// </summary>
public static readonly Color DeepSkyBlue = FromRgba(0, 191, 255, 255);
/// <summary>
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #696969.
/// </summary>
public static readonly Color DimGray = FromRgba(105, 105, 105, 255);
/// <summary>
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #1E90FF.
/// </summary>
public static readonly Color DodgerBlue = FromRgba(30, 144, 255, 255);
/// <summary>
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #B22222.
/// </summary>
public static readonly Color Firebrick = FromRgba(178, 34, 34, 255);
/// <summary>
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #FFFAF0.
/// </summary>
public static readonly Color FloralWhite = FromRgba(255, 250, 240, 255);
/// <summary>
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #228B22.
/// </summary>
public static readonly Color ForestGreen = FromRgba(34, 139, 34, 255);
/// <summary>
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #FF00FF.
/// </summary>
public static readonly Color Fuchsia = FromRgba(255, 0, 255, 255);
/// <summary>
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #DCDCDC.
/// </summary>
public static readonly Color Gainsboro = FromRgba(220, 220, 220, 255);
/// <summary>
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #F8F8FF.
/// </summary>
public static readonly Color GhostWhite = FromRgba(248, 248, 255, 255);
/// <summary>
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #FFD700.
/// </summary>
public static readonly Color Gold = FromRgba(255, 215, 0, 255);
/// <summary>
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #DAA520.
/// </summary>
public static readonly Color Goldenrod = FromRgba(218, 165, 32, 255);
/// <summary>
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #808080.
/// </summary>
public static readonly Color Gray = FromRgba(128, 128, 128, 255);
/// <summary>
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #008000.
/// </summary>
public static readonly Color Green = FromRgba(0, 128, 0, 255);
/// <summary>
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #ADFF2F.
/// </summary>
public static readonly Color GreenYellow = FromRgba(173, 255, 47, 255);
/// <summary>
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #F0FFF0.
/// </summary>
public static readonly Color Honeydew = FromRgba(240, 255, 240, 255);
/// <summary>
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #FF69B4.
/// </summary>
public static readonly Color HotPink = FromRgba(255, 105, 180, 255);
/// <summary>
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #CD5C5C.
/// </summary>
public static readonly Color IndianRed = FromRgba(205, 92, 92, 255);
/// <summary>
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #4B0082.
/// </summary>
public static readonly Color Indigo = FromRgba(75, 0, 130, 255);
/// <summary>
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #FFFFF0.
/// </summary>
public static readonly Color Ivory = FromRgba(255, 255, 240, 255);
/// <summary>
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #F0E68C.
/// </summary>
public static readonly Color Khaki = FromRgba(240, 230, 140, 255);
/// <summary>
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #E6E6FA.
/// </summary>
public static readonly Color Lavender = FromRgba(230, 230, 250, 255);
/// <summary>
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #FFF0F5.
/// </summary>
public static readonly Color LavenderBlush = FromRgba(255, 240, 245, 255);
/// <summary>
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #7CFC00.
/// </summary>
public static readonly Color LawnGreen = FromRgba(124, 252, 0, 255);
/// <summary>
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #FFFACD.
/// </summary>
public static readonly Color LemonChiffon = FromRgba(255, 250, 205, 255);
/// <summary>
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #ADD8E6.
/// </summary>
public static readonly Color LightBlue = FromRgba(173, 216, 230, 255);
/// <summary>
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #F08080.
/// </summary>
public static readonly Color LightCoral = FromRgba(240, 128, 128, 255);
/// <summary>
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #E0FFFF.
/// </summary>
public static readonly Color LightCyan = FromRgba(224, 255, 255, 255);
/// <summary>
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #FAFAD2.
/// </summary>
public static readonly Color LightGoldenrodYellow = FromRgba(250, 250, 210, 255);
/// <summary>
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #D3D3D3.
/// </summary>
public static readonly Color LightGray = FromRgba(211, 211, 211, 255);
/// <summary>
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #90EE90.
/// </summary>
public static readonly Color LightGreen = FromRgba(144, 238, 144, 255);
/// <summary>
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #FFB6C1.
/// </summary>
public static readonly Color LightPink = FromRgba(255, 182, 193, 255);
/// <summary>
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #FFA07A.
/// </summary>
public static readonly Color LightSalmon = FromRgba(255, 160, 122, 255);
/// <summary>
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #20B2AA.
/// </summary>
public static readonly Color LightSeaGreen = FromRgba(32, 178, 170, 255);
/// <summary>
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #87CEFA.
/// </summary>
public static readonly Color LightSkyBlue = FromRgba(135, 206, 250, 255);
/// <summary>
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #778899.
/// </summary>
public static readonly Color LightSlateGray = FromRgba(119, 136, 153, 255);
/// <summary>
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #B0C4DE.
/// </summary>
public static readonly Color LightSteelBlue = FromRgba(176, 196, 222, 255);
/// <summary>
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #FFFFE0.
/// </summary>
public static readonly Color LightYellow = FromRgba(255, 255, 224, 255);
/// <summary>
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #00FF00.
/// </summary>
public static readonly Color Lime = FromRgba(0, 255, 0, 255);
/// <summary>
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #32CD32.
/// </summary>
public static readonly Color LimeGreen = FromRgba(50, 205, 50, 255);
/// <summary>
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #FAF0E6.
/// </summary>
public static readonly Color Linen = FromRgba(250, 240, 230, 255);
/// <summary>
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #FF00FF.
/// </summary>
public static readonly Color Magenta = FromRgba(255, 0, 255, 255);
/// <summary>
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #800000.
/// </summary>
public static readonly Color Maroon = FromRgba(128, 0, 0, 255);
/// <summary>
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #66CDAA.
/// </summary>
public static readonly Color MediumAquamarine = FromRgba(102, 205, 170, 255);
/// <summary>
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #0000CD.
/// </summary>
public static readonly Color MediumBlue = FromRgba(0, 0, 205, 255);
/// <summary>
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #BA55D3.
/// </summary>
public static readonly Color MediumOrchid = FromRgba(186, 85, 211, 255);
/// <summary>
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #9370DB.
/// </summary>
public static readonly Color MediumPurple = FromRgba(147, 112, 219, 255);
/// <summary>
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #3CB371.
/// </summary>
public static readonly Color MediumSeaGreen = FromRgba(60, 179, 113, 255);
/// <summary>
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #7B68EE.
/// </summary>
public static readonly Color MediumSlateBlue = FromRgba(123, 104, 238, 255);
/// <summary>
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #00FA9A.
/// </summary>
public static readonly Color MediumSpringGreen = FromRgba(0, 250, 154, 255);
/// <summary>
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #48D1CC.
/// </summary>
public static readonly Color MediumTurquoise = FromRgba(72, 209, 204, 255);
/// <summary>
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #C71585.
/// </summary>
public static readonly Color MediumVioletRed = FromRgba(199, 21, 133, 255);
/// <summary>
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #191970.
/// </summary>
public static readonly Color MidnightBlue = FromRgba(25, 25, 112, 255);
/// <summary>
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #F5FFFA.
/// </summary>
public static readonly Color MintCream = FromRgba(245, 255, 250, 255);
/// <summary>
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #FFE4E1.
/// </summary>
public static readonly Color MistyRose = FromRgba(255, 228, 225, 255);
/// <summary>
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #FFE4B5.
/// </summary>
public static readonly Color Moccasin = FromRgba(255, 228, 181, 255);
/// <summary>
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #FFDEAD.
/// </summary>
public static readonly Color NavajoWhite = FromRgba(255, 222, 173, 255);
/// <summary>
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #000080.
/// </summary>
public static readonly Color Navy = FromRgba(0, 0, 128, 255);
/// <summary>
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #FDF5E6.
/// </summary>
public static readonly Color OldLace = FromRgba(253, 245, 230, 255);
/// <summary>
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #808000.
/// </summary>
public static readonly Color Olive = FromRgba(128, 128, 0, 255);
/// <summary>
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #6B8E23.
/// </summary>
public static readonly Color OliveDrab = FromRgba(107, 142, 35, 255);
/// <summary>
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #FFA500.
/// </summary>
public static readonly Color Orange = FromRgba(255, 165, 0, 255);
/// <summary>
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #FF4500.
/// </summary>
public static readonly Color OrangeRed = FromRgba(255, 69, 0, 255);
/// <summary>
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #DA70D6.
/// </summary>
public static readonly Color Orchid = FromRgba(218, 112, 214, 255);
/// <summary>
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #EEE8AA.
/// </summary>
public static readonly Color PaleGoldenrod = FromRgba(238, 232, 170, 255);
/// <summary>
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #98FB98.
/// </summary>
public static readonly Color PaleGreen = FromRgba(152, 251, 152, 255);
/// <summary>
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #AFEEEE.
/// </summary>
public static readonly Color PaleTurquoise = FromRgba(175, 238, 238, 255);
/// <summary>
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #DB7093.
/// </summary>
public static readonly Color PaleVioletRed = FromRgba(219, 112, 147, 255);
/// <summary>
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #FFEFD5.
/// </summary>
public static readonly Color PapayaWhip = FromRgba(255, 239, 213, 255);
/// <summary>
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #FFDAB9.
/// </summary>
public static readonly Color PeachPuff = FromRgba(255, 218, 185, 255);
/// <summary>
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #CD853F.
/// </summary>
public static readonly Color Peru = FromRgba(205, 133, 63, 255);
/// <summary>
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #FFC0CB.
/// </summary>
public static readonly Color Pink = FromRgba(255, 192, 203, 255);
/// <summary>
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #DDA0DD.
/// </summary>
public static readonly Color Plum = FromRgba(221, 160, 221, 255);
/// <summary>
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #B0E0E6.
/// </summary>
public static readonly Color PowderBlue = FromRgba(176, 224, 230, 255);
/// <summary>
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #800080.
/// </summary>
public static readonly Color Purple = FromRgba(128, 0, 128, 255);
/// <summary>
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #663399.
/// </summary>
public static readonly Color RebeccaPurple = FromRgba(102, 51, 153, 255);
/// <summary>
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #FF0000.
/// </summary>
public static readonly Color Red = FromRgba(255, 0, 0, 255);
/// <summary>
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #BC8F8F.
/// </summary>
public static readonly Color RosyBrown = FromRgba(188, 143, 143, 255);
/// <summary>
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #4169E1.
/// </summary>
public static readonly Color RoyalBlue = FromRgba(65, 105, 225, 255);
/// <summary>
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #8B4513.
/// </summary>
public static readonly Color SaddleBrown = FromRgba(139, 69, 19, 255);
/// <summary>
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #FA8072.
/// </summary>
public static readonly Color Salmon = FromRgba(250, 128, 114, 255);
/// <summary>
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #F4A460.
/// </summary>
public static readonly Color SandyBrown = FromRgba(244, 164, 96, 255);
/// <summary>
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #2E8B57.
/// </summary>
public static readonly Color SeaGreen = FromRgba(46, 139, 87, 255);
/// <summary>
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #FFF5EE.
/// </summary>
public static readonly Color SeaShell = FromRgba(255, 245, 238, 255);
/// <summary>
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #A0522D.
/// </summary>
public static readonly Color Sienna = FromRgba(160, 82, 45, 255);
/// <summary>
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #C0C0C0.
/// </summary>
public static readonly Color Silver = FromRgba(192, 192, 192, 255);
/// <summary>
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #87CEEB.
/// </summary>
public static readonly Color SkyBlue = FromRgba(135, 206, 235, 255);
/// <summary>
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #6A5ACD.
/// </summary>
public static readonly Color SlateBlue = FromRgba(106, 90, 205, 255);
/// <summary>
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #708090.
/// </summary>
public static readonly Color SlateGray = FromRgba(112, 128, 144, 255);
/// <summary>
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #FFFAFA.
/// </summary>
public static readonly Color Snow = FromRgba(255, 250, 250, 255);
/// <summary>
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #00FF7F.
/// </summary>
public static readonly Color SpringGreen = FromRgba(0, 255, 127, 255);
/// <summary>
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #4682B4.
/// </summary>
public static readonly Color SteelBlue = FromRgba(70, 130, 180, 255);
/// <summary>
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #D2B48C.
/// </summary>
public static readonly Color Tan = FromRgba(210, 180, 140, 255);
/// <summary>
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #008080.
/// </summary>
public static readonly Color Teal = FromRgba(0, 128, 128, 255);
/// <summary>
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #D8BFD8.
/// </summary>
public static readonly Color Thistle = FromRgba(216, 191, 216, 255);
/// <summary>
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #FF6347.
/// </summary>
public static readonly Color Tomato = FromRgba(255, 99, 71, 255);
/// <summary>
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #FFFFFF.
/// </summary>
public static readonly Color Transparent = FromRgba(255, 255, 255, 0);
/// <summary>
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #40E0D0.
/// </summary>
public static readonly Color Turquoise = FromRgba(64, 224, 208, 255);
/// <summary>
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #EE82EE.
/// </summary>
public static readonly Color Violet = FromRgba(238, 130, 238, 255);
/// <summary>
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #F5DEB3.
/// </summary>
public static readonly Color Wheat = FromRgba(245, 222, 179, 255);
/// <summary>
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #FFFFFF.
/// </summary>
public static readonly Color White = FromRgba(255, 255, 255, 255);
/// <summary>
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #F5F5F5.
/// </summary>
public static readonly Color WhiteSmoke = FromRgba(245, 245, 245, 255);
/// <summary>
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #FFFF00.
/// </summary>
public static readonly Color Yellow = FromRgba(255, 255, 0, 255);
/// <summary>
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #9ACD32.
/// </summary>
public static readonly Color YellowGreen = FromRgba(154, 205, 50, 255);
}
}

54
tests/ImageSharp.Tests/Processing/Binarization/BinaryDitherTest.cs

@ -25,38 +25,38 @@ namespace SixLabors.ImageSharp.Tests.Processing.Binarization
public void BinaryDither_CorrectProcessor()
{
this.operations.BinaryDither(this.orderedDither);
BinaryOrderedDitherProcessor<Rgba32> p = this.Verify<BinaryOrderedDitherProcessor<Rgba32>>();
BinaryOrderedDitherProcessor p = this.Verify<BinaryOrderedDitherProcessor>();
Assert.Equal(this.orderedDither, p.Dither);
Assert.Equal(NamedColors<Rgba32>.White, p.UpperColor);
Assert.Equal(NamedColors<Rgba32>.Black, p.LowerColor);
Assert.Equal(Color.White, p.UpperColor);
Assert.Equal(Color.Black, p.LowerColor);
}
[Fact]
public void BinaryDither_rect_CorrectProcessor()
{
this.operations.BinaryDither(this.orderedDither, this.rect);
BinaryOrderedDitherProcessor<Rgba32> p = this.Verify<BinaryOrderedDitherProcessor<Rgba32>>(this.rect);
BinaryOrderedDitherProcessor p = this.Verify<BinaryOrderedDitherProcessor>(this.rect);
Assert.Equal(this.orderedDither, p.Dither);
Assert.Equal(NamedColors<Rgba32>.White, p.UpperColor);
Assert.Equal(NamedColors<Rgba32>.Black, p.LowerColor);
Assert.Equal(Color.White, p.UpperColor);
Assert.Equal(Color.Black, p.LowerColor);
}
[Fact]
public void BinaryDither_index_CorrectProcessor()
{
this.operations.BinaryDither(this.orderedDither, NamedColors<Rgba32>.Yellow, NamedColors<Rgba32>.HotPink);
BinaryOrderedDitherProcessor<Rgba32> p = this.Verify<BinaryOrderedDitherProcessor<Rgba32>>();
this.operations.BinaryDither(this.orderedDither, Color.Yellow, Color.HotPink);
BinaryOrderedDitherProcessor p = this.Verify<BinaryOrderedDitherProcessor>();
Assert.Equal(this.orderedDither, p.Dither);
Assert.Equal(NamedColors<Rgba32>.Yellow, p.UpperColor);
Assert.Equal(NamedColors<Rgba32>.HotPink, p.LowerColor);
Assert.Equal(Color.Yellow, p.UpperColor);
Assert.Equal(Color.HotPink, p.LowerColor);
}
[Fact]
public void BinaryDither_index_rect_CorrectProcessor()
{
this.operations.BinaryDither(this.orderedDither, NamedColors<Rgba32>.Yellow, NamedColors<Rgba32>.HotPink, this.rect);
BinaryOrderedDitherProcessor<Rgba32> p = this.Verify<BinaryOrderedDitherProcessor<Rgba32>>(this.rect);
this.operations.BinaryDither(this.orderedDither, Color.Yellow, Color.HotPink, this.rect);
BinaryOrderedDitherProcessor p = this.Verify<BinaryOrderedDitherProcessor>(this.rect);
Assert.Equal(this.orderedDither, p.Dither);
Assert.Equal(NamedColors<Rgba32>.HotPink, p.LowerColor);
Assert.Equal(Color.HotPink, p.LowerColor);
}
@ -64,44 +64,44 @@ namespace SixLabors.ImageSharp.Tests.Processing.Binarization
public void BinaryDither_ErrorDiffuser_CorrectProcessor()
{
this.operations.BinaryDiffuse(this.errorDiffuser, .4F);
BinaryErrorDiffusionProcessor<Rgba32> p = this.Verify<BinaryErrorDiffusionProcessor<Rgba32>>();
BinaryErrorDiffusionProcessor p = this.Verify<BinaryErrorDiffusionProcessor>();
Assert.Equal(this.errorDiffuser, p.Diffuser);
Assert.Equal(.4F, p.Threshold);
Assert.Equal(NamedColors<Rgba32>.White, p.UpperColor);
Assert.Equal(NamedColors<Rgba32>.Black, p.LowerColor);
Assert.Equal(Color.White, p.UpperColor);
Assert.Equal(Color.Black, p.LowerColor);
}
[Fact]
public void BinaryDither_ErrorDiffuser_rect_CorrectProcessor()
{
this.operations.BinaryDiffuse(this.errorDiffuser, .3F, this.rect);
BinaryErrorDiffusionProcessor<Rgba32> p = this.Verify<BinaryErrorDiffusionProcessor<Rgba32>>(this.rect);
BinaryErrorDiffusionProcessor p = this.Verify<BinaryErrorDiffusionProcessor>(this.rect);
Assert.Equal(this.errorDiffuser, p.Diffuser);
Assert.Equal(.3F, p.Threshold);
Assert.Equal(NamedColors<Rgba32>.White, p.UpperColor);
Assert.Equal(NamedColors<Rgba32>.Black, p.LowerColor);
Assert.Equal(Color.White, p.UpperColor);
Assert.Equal(Color.Black, p.LowerColor);
}
[Fact]
public void BinaryDither_ErrorDiffuser_CorrectProcessorWithColors()
{
this.operations.BinaryDiffuse(this.errorDiffuser, .5F, NamedColors<Rgba32>.HotPink, NamedColors<Rgba32>.Yellow);
BinaryErrorDiffusionProcessor<Rgba32> p = this.Verify<BinaryErrorDiffusionProcessor<Rgba32>>();
this.operations.BinaryDiffuse(this.errorDiffuser, .5F, Color.HotPink, Color.Yellow);
BinaryErrorDiffusionProcessor p = this.Verify<BinaryErrorDiffusionProcessor>();
Assert.Equal(this.errorDiffuser, p.Diffuser);
Assert.Equal(.5F, p.Threshold);
Assert.Equal(NamedColors<Rgba32>.HotPink, p.UpperColor);
Assert.Equal(NamedColors<Rgba32>.Yellow, p.LowerColor);
Assert.Equal(Color.HotPink, p.UpperColor);
Assert.Equal(Color.Yellow, p.LowerColor);
}
[Fact]
public void BinaryDither_ErrorDiffuser_rect_CorrectProcessorWithColors()
{
this.operations.BinaryDiffuse(this.errorDiffuser, .5F, NamedColors<Rgba32>.HotPink, NamedColors<Rgba32>.Yellow, this.rect);
BinaryErrorDiffusionProcessor<Rgba32> p = this.Verify<BinaryErrorDiffusionProcessor<Rgba32>>(this.rect);
this.operations.BinaryDiffuse(this.errorDiffuser, .5F, Color.HotPink, Color.Yellow, this.rect);
BinaryErrorDiffusionProcessor p = this.Verify<BinaryErrorDiffusionProcessor>(this.rect);
Assert.Equal(this.errorDiffuser, p.Diffuser);
Assert.Equal(.5F, p.Threshold);
Assert.Equal(NamedColors<Rgba32>.HotPink, p.UpperColor);
Assert.Equal(NamedColors<Rgba32>.Yellow, p.LowerColor);
Assert.Equal(Color.HotPink, p.UpperColor);
Assert.Equal(Color.Yellow, p.LowerColor);
}
}
}

28
tests/ImageSharp.Tests/Processing/Binarization/BinaryThresholdTest.cs

@ -15,40 +15,40 @@ namespace SixLabors.ImageSharp.Tests.Processing.Binarization
public void BinaryThreshold_CorrectProcessor()
{
this.operations.BinaryThreshold(.23f);
BinaryThresholdProcessor<Rgba32> p = this.Verify<BinaryThresholdProcessor<Rgba32>>();
BinaryThresholdProcessor p = this.Verify<BinaryThresholdProcessor>();
Assert.Equal(.23f, p.Threshold);
Assert.Equal(NamedColors<Rgba32>.White, p.UpperColor);
Assert.Equal(NamedColors<Rgba32>.Black, p.LowerColor);
Assert.Equal(Color.White, p.UpperColor);
Assert.Equal(Color.Black, p.LowerColor);
}
[Fact]
public void BinaryThreshold_rect_CorrectProcessor()
{
this.operations.BinaryThreshold(.93f, this.rect);
BinaryThresholdProcessor<Rgba32> p = this.Verify<BinaryThresholdProcessor<Rgba32>>(this.rect);
BinaryThresholdProcessor p = this.Verify<BinaryThresholdProcessor>(this.rect);
Assert.Equal(.93f, p.Threshold);
Assert.Equal(NamedColors<Rgba32>.White, p.UpperColor);
Assert.Equal(NamedColors<Rgba32>.Black, p.LowerColor);
Assert.Equal(Color.White, p.UpperColor);
Assert.Equal(Color.Black, p.LowerColor);
}
[Fact]
public void BinaryThreshold_CorrectProcessorWithUpperLower()
{
this.operations.BinaryThreshold(.23f, NamedColors<Rgba32>.HotPink, NamedColors<Rgba32>.Yellow);
BinaryThresholdProcessor<Rgba32> p = this.Verify<BinaryThresholdProcessor<Rgba32>>();
this.operations.BinaryThreshold(.23f, Color.HotPink, Color.Yellow);
BinaryThresholdProcessor p = this.Verify<BinaryThresholdProcessor>();
Assert.Equal(.23f, p.Threshold);
Assert.Equal(NamedColors<Rgba32>.HotPink, p.UpperColor);
Assert.Equal(NamedColors<Rgba32>.Yellow, p.LowerColor);
Assert.Equal(Color.HotPink, p.UpperColor);
Assert.Equal(Color.Yellow, p.LowerColor);
}
[Fact]
public void BinaryThreshold_rect_CorrectProcessorWithUpperLower()
{
this.operations.BinaryThreshold(.93f, NamedColors<Rgba32>.HotPink, NamedColors<Rgba32>.Yellow, this.rect);
BinaryThresholdProcessor<Rgba32> p = this.Verify<BinaryThresholdProcessor<Rgba32>>(this.rect);
this.operations.BinaryThreshold(.93f, Color.HotPink, Color.Yellow, this.rect);
BinaryThresholdProcessor p = this.Verify<BinaryThresholdProcessor>(this.rect);
Assert.Equal(.93f, p.Threshold);
Assert.Equal(NamedColors<Rgba32>.HotPink, p.UpperColor);
Assert.Equal(NamedColors<Rgba32>.Yellow, p.LowerColor);
Assert.Equal(Color.HotPink, p.UpperColor);
Assert.Equal(Color.Yellow, p.LowerColor);
}
}
}
Loading…
Cancel
Save