mirror of https://github.com/SixLabors/ImageSharp
committed by
GitHub
140 changed files with 4306 additions and 1539 deletions
@ -0,0 +1,83 @@ |
|||
// Copyright (c) Six Labors and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
|
|||
using System.Numerics; |
|||
using System.Runtime.CompilerServices; |
|||
|
|||
using SixLabors.ImageSharp.PixelFormats; |
|||
|
|||
namespace SixLabors.ImageSharp |
|||
{ |
|||
/// <content>
|
|||
/// Contains constructors and implicit conversion methods.
|
|||
/// </content>
|
|||
public readonly partial struct Color |
|||
{ |
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="Color"/> struct.
|
|||
/// </summary>
|
|||
/// <param name="pixel">The <see cref="Rgba64"/> containing the color information.</param>
|
|||
[MethodImpl(InliningOptions.ShortMethod)] |
|||
public Color(Rgba64 pixel) => this.data = pixel; |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="Color"/> struct.
|
|||
/// </summary>
|
|||
/// <param name="pixel">The <see cref="Rgba32"/> containing the color information.</param>
|
|||
[MethodImpl(InliningOptions.ShortMethod)] |
|||
public Color(Rgba32 pixel) => this.data = new Rgba64(pixel); |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="Color"/> struct.
|
|||
/// </summary>
|
|||
/// <param name="pixel">The <see cref="Argb32"/> containing the color information.</param>
|
|||
[MethodImpl(InliningOptions.ShortMethod)] |
|||
public Color(Argb32 pixel) => this.data = new Rgba64(pixel); |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="Color"/> struct.
|
|||
/// </summary>
|
|||
/// <param name="pixel">The <see cref="Bgra32"/> containing the color information.</param>
|
|||
[MethodImpl(InliningOptions.ShortMethod)] |
|||
public Color(Bgra32 pixel) => this.data = new Rgba64(pixel); |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="Color"/> struct.
|
|||
/// </summary>
|
|||
/// <param name="pixel">The <see cref="Rgb24"/> containing the color information.</param>
|
|||
[MethodImpl(InliningOptions.ShortMethod)] |
|||
public Color(Rgb24 pixel) => this.data = new Rgba64(pixel); |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="Color"/> struct.
|
|||
/// </summary>
|
|||
/// <param name="pixel">The <see cref="Bgr24"/> containing the color information.</param>
|
|||
[MethodImpl(InliningOptions.ShortMethod)] |
|||
public Color(Bgr24 pixel) => this.data = new Rgba64(pixel); |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="Color"/> struct.
|
|||
/// </summary>
|
|||
/// <param name="vector">The <see cref="Vector4"/> containing the color information.</param>
|
|||
[MethodImpl(InliningOptions.ShortMethod)] |
|||
public Color(Vector4 vector) => this.data = new Rgba64(vector); |
|||
|
|||
[MethodImpl(InliningOptions.ShortMethod)] |
|||
internal Rgba64 ToRgba64() => this.data; |
|||
|
|||
[MethodImpl(InliningOptions.ShortMethod)] |
|||
internal Rgba32 ToRgba32() => this.data.ToRgba32(); |
|||
|
|||
[MethodImpl(InliningOptions.ShortMethod)] |
|||
internal Bgra32 ToBgra32() => this.data.ToBgra32(); |
|||
|
|||
[MethodImpl(InliningOptions.ShortMethod)] |
|||
internal Argb32 ToArgb32() => this.data.ToArgb32(); |
|||
|
|||
[MethodImpl(InliningOptions.ShortMethod)] |
|||
internal Rgb24 ToRgb24() => this.data.ToRgb24(); |
|||
|
|||
[MethodImpl(InliningOptions.ShortMethod)] |
|||
internal Bgr24 ToBgr24() => this.data.ToBgr24(); |
|||
} |
|||
} |
|||
@ -0,0 +1,721 @@ |
|||
// Copyright (c) Six Labors and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
|
|||
namespace SixLabors.ImageSharp |
|||
{ |
|||
/// <content>
|
|||
/// Contains static named color values.
|
|||
/// </content>
|
|||
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); |
|||
} |
|||
} |
|||
@ -0,0 +1,166 @@ |
|||
// Copyright (c) Six Labors and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
|
|||
using System; |
|||
|
|||
namespace SixLabors.ImageSharp |
|||
{ |
|||
/// <content>
|
|||
/// Contains the definition of <see cref="WebSafePalette"/>.
|
|||
/// </content>
|
|||
public partial struct Color |
|||
{ |
|||
private static readonly Lazy<Color[]> WebSafePaletteLazy = new Lazy<Color[]>(CreateWebSafePalette, true); |
|||
|
|||
/// <summary>
|
|||
/// Gets a collection of named, web safe colors as defined in the CSS Color Module Level 4.
|
|||
/// </summary>
|
|||
public static ReadOnlyMemory<Color> WebSafePalette => WebSafePaletteLazy.Value; |
|||
|
|||
private static Color[] CreateWebSafePalette() => new[] |
|||
{ |
|||
AliceBlue, |
|||
AntiqueWhite, |
|||
Aqua, |
|||
Aquamarine, |
|||
Azure, |
|||
Beige, |
|||
Bisque, |
|||
Black, |
|||
BlanchedAlmond, |
|||
Blue, |
|||
BlueViolet, |
|||
Brown, |
|||
BurlyWood, |
|||
CadetBlue, |
|||
Chartreuse, |
|||
Chocolate, |
|||
Coral, |
|||
CornflowerBlue, |
|||
Cornsilk, |
|||
Crimson, |
|||
Cyan, |
|||
DarkBlue, |
|||
DarkCyan, |
|||
DarkGoldenrod, |
|||
DarkGray, |
|||
DarkGreen, |
|||
DarkKhaki, |
|||
DarkMagenta, |
|||
DarkOliveGreen, |
|||
DarkOrange, |
|||
DarkOrchid, |
|||
DarkRed, |
|||
DarkSalmon, |
|||
DarkSeaGreen, |
|||
DarkSlateBlue, |
|||
DarkSlateGray, |
|||
DarkTurquoise, |
|||
DarkViolet, |
|||
DeepPink, |
|||
DeepSkyBlue, |
|||
DimGray, |
|||
DodgerBlue, |
|||
Firebrick, |
|||
FloralWhite, |
|||
ForestGreen, |
|||
Fuchsia, |
|||
Gainsboro, |
|||
GhostWhite, |
|||
Gold, |
|||
Goldenrod, |
|||
Gray, |
|||
Green, |
|||
GreenYellow, |
|||
Honeydew, |
|||
HotPink, |
|||
IndianRed, |
|||
Indigo, |
|||
Ivory, |
|||
Khaki, |
|||
Lavender, |
|||
LavenderBlush, |
|||
LawnGreen, |
|||
LemonChiffon, |
|||
LightBlue, |
|||
LightCoral, |
|||
LightCyan, |
|||
LightGoldenrodYellow, |
|||
LightGray, |
|||
LightGreen, |
|||
LightPink, |
|||
LightSalmon, |
|||
LightSeaGreen, |
|||
LightSkyBlue, |
|||
LightSlateGray, |
|||
LightSteelBlue, |
|||
LightYellow, |
|||
Lime, |
|||
LimeGreen, |
|||
Linen, |
|||
Magenta, |
|||
Maroon, |
|||
MediumAquamarine, |
|||
MediumBlue, |
|||
MediumOrchid, |
|||
MediumPurple, |
|||
MediumSeaGreen, |
|||
MediumSlateBlue, |
|||
MediumSpringGreen, |
|||
MediumTurquoise, |
|||
MediumVioletRed, |
|||
MidnightBlue, |
|||
MintCream, |
|||
MistyRose, |
|||
Moccasin, |
|||
NavajoWhite, |
|||
Navy, |
|||
OldLace, |
|||
Olive, |
|||
OliveDrab, |
|||
Orange, |
|||
OrangeRed, |
|||
Orchid, |
|||
PaleGoldenrod, |
|||
PaleGreen, |
|||
PaleTurquoise, |
|||
PaleVioletRed, |
|||
PapayaWhip, |
|||
PeachPuff, |
|||
Peru, |
|||
Pink, |
|||
Plum, |
|||
PowderBlue, |
|||
Purple, |
|||
RebeccaPurple, |
|||
Red, |
|||
RosyBrown, |
|||
RoyalBlue, |
|||
SaddleBrown, |
|||
Salmon, |
|||
SandyBrown, |
|||
SeaGreen, |
|||
SeaShell, |
|||
Sienna, |
|||
Silver, |
|||
SkyBlue, |
|||
SlateBlue, |
|||
SlateGray, |
|||
Snow, |
|||
SpringGreen, |
|||
SteelBlue, |
|||
Tan, |
|||
Teal, |
|||
Thistle, |
|||
Tomato, |
|||
Transparent, |
|||
Turquoise, |
|||
Violet, |
|||
Wheat, |
|||
White, |
|||
WhiteSmoke, |
|||
Yellow, |
|||
YellowGreen |
|||
}; |
|||
} |
|||
} |
|||
@ -0,0 +1,135 @@ |
|||
// Copyright (c) Six Labors and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
|
|||
using System; |
|||
|
|||
namespace SixLabors.ImageSharp |
|||
{ |
|||
/// <content>
|
|||
/// Contains the definition of <see cref="WernerPalette"/>.
|
|||
/// </content>
|
|||
public partial struct Color |
|||
{ |
|||
private static readonly Lazy<Color[]> WernerPaletteLazy = new Lazy<Color[]>(CreateWernerPalette, true); |
|||
|
|||
/// <summary>
|
|||
/// Gets a collection of colors as defined in the original second edition of Werner’s Nomenclature of Colours 1821.
|
|||
/// The hex codes were collected and defined by Nicholas Rougeux <see href="https://www.c82.net/werner"/>.
|
|||
/// </summary>
|
|||
public static ReadOnlyMemory<Color> WernerPalette => WernerPaletteLazy.Value; |
|||
|
|||
private static Color[] CreateWernerPalette() => new[] |
|||
{ |
|||
FromHex("#f1e9cd"), |
|||
FromHex("#f2e7cf"), |
|||
FromHex("#ece6d0"), |
|||
FromHex("#f2eacc"), |
|||
FromHex("#f3e9ca"), |
|||
FromHex("#f2ebcd"), |
|||
FromHex("#e6e1c9"), |
|||
FromHex("#e2ddc6"), |
|||
FromHex("#cbc8b7"), |
|||
FromHex("#bfbbb0"), |
|||
FromHex("#bebeb3"), |
|||
FromHex("#b7b5ac"), |
|||
FromHex("#bab191"), |
|||
FromHex("#9c9d9a"), |
|||
FromHex("#8a8d84"), |
|||
FromHex("#5b5c61"), |
|||
FromHex("#555152"), |
|||
FromHex("#413f44"), |
|||
FromHex("#454445"), |
|||
FromHex("#423937"), |
|||
FromHex("#433635"), |
|||
FromHex("#252024"), |
|||
FromHex("#241f20"), |
|||
FromHex("#281f3f"), |
|||
FromHex("#1c1949"), |
|||
FromHex("#4f638d"), |
|||
FromHex("#383867"), |
|||
FromHex("#5c6b8f"), |
|||
FromHex("#657abb"), |
|||
FromHex("#6f88af"), |
|||
FromHex("#7994b5"), |
|||
FromHex("#6fb5a8"), |
|||
FromHex("#719ba2"), |
|||
FromHex("#8aa1a6"), |
|||
FromHex("#d0d5d3"), |
|||
FromHex("#8590ae"), |
|||
FromHex("#3a2f52"), |
|||
FromHex("#39334a"), |
|||
FromHex("#6c6d94"), |
|||
FromHex("#584c77"), |
|||
FromHex("#533552"), |
|||
FromHex("#463759"), |
|||
FromHex("#bfbac0"), |
|||
FromHex("#77747f"), |
|||
FromHex("#4a475c"), |
|||
FromHex("#b8bfaf"), |
|||
FromHex("#b2b599"), |
|||
FromHex("#979c84"), |
|||
FromHex("#5d6161"), |
|||
FromHex("#61ac86"), |
|||
FromHex("#a4b6a7"), |
|||
FromHex("#adba98"), |
|||
FromHex("#93b778"), |
|||
FromHex("#7d8c55"), |
|||
FromHex("#33431e"), |
|||
FromHex("#7c8635"), |
|||
FromHex("#8e9849"), |
|||
FromHex("#c2c190"), |
|||
FromHex("#67765b"), |
|||
FromHex("#ab924b"), |
|||
FromHex("#c8c76f"), |
|||
FromHex("#ccc050"), |
|||
FromHex("#ebdd99"), |
|||
FromHex("#ab9649"), |
|||
FromHex("#dbc364"), |
|||
FromHex("#e6d058"), |
|||
FromHex("#ead665"), |
|||
FromHex("#d09b2c"), |
|||
FromHex("#a36629"), |
|||
FromHex("#a77d35"), |
|||
FromHex("#f0d696"), |
|||
FromHex("#d7c485"), |
|||
FromHex("#f1d28c"), |
|||
FromHex("#efcc83"), |
|||
FromHex("#f3daa7"), |
|||
FromHex("#dfa837"), |
|||
FromHex("#ebbc71"), |
|||
FromHex("#d17c3f"), |
|||
FromHex("#92462f"), |
|||
FromHex("#be7249"), |
|||
FromHex("#bb603c"), |
|||
FromHex("#c76b4a"), |
|||
FromHex("#a75536"), |
|||
FromHex("#b63e36"), |
|||
FromHex("#b5493a"), |
|||
FromHex("#cd6d57"), |
|||
FromHex("#711518"), |
|||
FromHex("#e9c49d"), |
|||
FromHex("#eedac3"), |
|||
FromHex("#eecfbf"), |
|||
FromHex("#ce536b"), |
|||
FromHex("#b74a70"), |
|||
FromHex("#b7757c"), |
|||
FromHex("#612741"), |
|||
FromHex("#7a4848"), |
|||
FromHex("#3f3033"), |
|||
FromHex("#8d746f"), |
|||
FromHex("#4d3635"), |
|||
FromHex("#6e3b31"), |
|||
FromHex("#864735"), |
|||
FromHex("#553d3a"), |
|||
FromHex("#613936"), |
|||
FromHex("#7a4b3a"), |
|||
FromHex("#946943"), |
|||
FromHex("#c39e6d"), |
|||
FromHex("#513e32"), |
|||
FromHex("#8b7859"), |
|||
FromHex("#9b856b"), |
|||
FromHex("#766051"), |
|||
FromHex("#453b32") |
|||
}; |
|||
} |
|||
} |
|||
@ -0,0 +1,218 @@ |
|||
// Copyright (c) Six Labors and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
|
|||
using System; |
|||
using System.Buffers.Binary; |
|||
using System.Globalization; |
|||
using System.Numerics; |
|||
using System.Runtime.CompilerServices; |
|||
using System.Runtime.InteropServices; |
|||
|
|||
using SixLabors.ImageSharp.PixelFormats; |
|||
|
|||
namespace SixLabors.ImageSharp |
|||
{ |
|||
/// <summary>
|
|||
/// Represents a color value that is convertible to any <see cref="IPixel{TSelf}"/> type.
|
|||
/// </summary>
|
|||
/// <remarks>
|
|||
/// The internal representation and layout of this structure is hidden by intention.
|
|||
/// It's not serializable, and it should not be considered as part of a contract.
|
|||
/// Unlike System.Drawing.Color, <see cref="Color"/> has to be converted to a specific pixel value
|
|||
/// to query the color components.
|
|||
/// </remarks>
|
|||
public readonly partial struct Color : IEquatable<Color> |
|||
{ |
|||
private readonly Rgba64 data; |
|||
|
|||
[MethodImpl(InliningOptions.ShortMethod)] |
|||
private Color(byte r, byte g, byte b, byte a) |
|||
{ |
|||
this.data = new Rgba64( |
|||
ImageMaths.UpscaleFrom8BitTo16Bit(r), |
|||
ImageMaths.UpscaleFrom8BitTo16Bit(g), |
|||
ImageMaths.UpscaleFrom8BitTo16Bit(b), |
|||
ImageMaths.UpscaleFrom8BitTo16Bit(a)); |
|||
} |
|||
|
|||
[MethodImpl(InliningOptions.ShortMethod)] |
|||
private Color(byte r, byte g, byte b) |
|||
{ |
|||
this.data = new Rgba64( |
|||
ImageMaths.UpscaleFrom8BitTo16Bit(r), |
|||
ImageMaths.UpscaleFrom8BitTo16Bit(g), |
|||
ImageMaths.UpscaleFrom8BitTo16Bit(b), |
|||
ushort.MaxValue); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Checks whether two <see cref="Color"/> structures are equal.
|
|||
/// </summary>
|
|||
/// <param name="left">The left hand <see cref="Color"/> operand.</param>
|
|||
/// <param name="right">The right hand <see cref="Color"/> operand.</param>
|
|||
/// <returns>
|
|||
/// True if the <paramref name="left"/> parameter is equal to the <paramref name="right"/> parameter;
|
|||
/// otherwise, false.
|
|||
/// </returns>
|
|||
[MethodImpl(InliningOptions.ShortMethod)] |
|||
public static bool operator ==(Color left, Color right) |
|||
{ |
|||
return left.Equals(right); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Checks whether two <see cref="Color"/> structures are equal.
|
|||
/// </summary>
|
|||
/// <param name="left">The left hand <see cref="Color"/> operand.</param>
|
|||
/// <param name="right">The right hand <see cref="Color"/> operand.</param>
|
|||
/// <returns>
|
|||
/// True if the <paramref name="left"/> parameter is not equal to the <paramref name="right"/> parameter;
|
|||
/// otherwise, false.
|
|||
/// </returns>
|
|||
[MethodImpl(InliningOptions.ShortMethod)] |
|||
public static bool operator !=(Color left, Color right) |
|||
{ |
|||
return !left.Equals(right); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Creates a <see cref="Color"/> from RGBA bytes.
|
|||
/// </summary>
|
|||
/// <param name="r">The red component (0-255).</param>
|
|||
/// <param name="g">The green component (0-255).</param>
|
|||
/// <param name="b">The blue component (0-255).</param>
|
|||
/// <param name="a">The alpha component (0-255).</param>
|
|||
/// <returns>The <see cref="Color"/>.</returns>
|
|||
[MethodImpl(InliningOptions.ShortMethod)] |
|||
public static Color FromRgba(byte r, byte g, byte b, byte a) => new Color(r, g, b, a); |
|||
|
|||
/// <summary>
|
|||
/// Creates a <see cref="Color"/> from RGB bytes.
|
|||
/// </summary>
|
|||
/// <param name="r">The red component (0-255).</param>
|
|||
/// <param name="g">The green component (0-255).</param>
|
|||
/// <param name="b">The blue component (0-255).</param>
|
|||
/// <returns>The <see cref="Color"/>.</returns>
|
|||
[MethodImpl(InliningOptions.ShortMethod)] |
|||
public static Color FromRgb(byte r, byte g, byte b) => new Color(r, g, b); |
|||
|
|||
/// <summary>
|
|||
/// Creates a new <see cref="Color"/> instance from the string representing a color in hexadecimal form.
|
|||
/// </summary>
|
|||
/// <param name="hex">
|
|||
/// The hexadecimal representation of the combined color components arranged
|
|||
/// in rgb, rgba, rrggbb, or rrggbbaa format to match web syntax.
|
|||
/// </param>
|
|||
/// <returns>Returns a <see cref="Color"/> that represents the color defined by the provided RGBA hex string.</returns>
|
|||
public static Color FromHex(string hex) |
|||
{ |
|||
Guard.NotNullOrWhiteSpace(hex, nameof(hex)); |
|||
|
|||
hex = ToRgbaHex(hex); |
|||
|
|||
if (hex is null || !uint.TryParse(hex, NumberStyles.HexNumber, CultureInfo.InvariantCulture, out uint packedValue)) |
|||
{ |
|||
throw new ArgumentException("Hexadecimal string is not in the correct format.", nameof(hex)); |
|||
} |
|||
|
|||
var rgba = new Rgba32(BinaryPrimitives.ReverseEndianness(packedValue)); |
|||
return new Color(rgba); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets the hexadecimal representation of the color instance in rrggbbaa form.
|
|||
/// </summary>
|
|||
/// <returns>A hexadecimal string representation of the value.</returns>
|
|||
[MethodImpl(InliningOptions.ShortMethod)] |
|||
public string ToHex() => this.data.ToRgba32().ToHex(); |
|||
|
|||
/// <inheritdoc />
|
|||
public override string ToString() => this.ToHex(); |
|||
|
|||
/// <summary>
|
|||
/// Converts the color instance to an <see cref="IPixel{TSelf}"/>
|
|||
/// implementation defined by <typeparamref name="TPixel"/>.
|
|||
/// </summary>
|
|||
/// <typeparam name="TPixel">The pixel type to convert to.</typeparam>
|
|||
/// <returns>The pixel value.</returns>
|
|||
[MethodImpl(InliningOptions.ShortMethod)] |
|||
public TPixel ToPixel<TPixel>() |
|||
where TPixel : struct, IPixel<TPixel> |
|||
{ |
|||
TPixel pixel = default; |
|||
pixel.FromRgba64(this.data); |
|||
return pixel; |
|||
} |
|||
|
|||
/// <inheritdoc />
|
|||
[MethodImpl(InliningOptions.ShortMethod)] |
|||
public bool Equals(Color other) |
|||
{ |
|||
return this.data.PackedValue == other.data.PackedValue; |
|||
} |
|||
|
|||
/// <inheritdoc />
|
|||
public override bool Equals(object obj) |
|||
{ |
|||
return obj is Color other && this.Equals(other); |
|||
} |
|||
|
|||
/// <inheritdoc />
|
|||
[MethodImpl(InliningOptions.ShortMethod)] |
|||
public override int GetHashCode() |
|||
{ |
|||
return this.data.PackedValue.GetHashCode(); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Bulk convert a span of <see cref="Color"/> to a span of a specified pixel type.
|
|||
/// </summary>
|
|||
[MethodImpl(InliningOptions.ShortMethod)] |
|||
internal static void ToPixel<TPixel>( |
|||
Configuration configuration, |
|||
ReadOnlySpan<Color> source, |
|||
Span<TPixel> destination) |
|||
where TPixel : struct, IPixel<TPixel> |
|||
{ |
|||
ReadOnlySpan<Rgba64> rgba64Span = MemoryMarshal.Cast<Color, Rgba64>(source); |
|||
PixelOperations<TPixel>.Instance.FromRgba64(Configuration.Default, rgba64Span, destination); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Converts the specified hex value to an rrggbbaa hex value.
|
|||
/// </summary>
|
|||
/// <param name="hex">The hex value to convert.</param>
|
|||
/// <returns>
|
|||
/// A rrggbbaa hex value.
|
|||
/// </returns>
|
|||
private static string ToRgbaHex(string hex) |
|||
{ |
|||
if (hex[0] == '#') |
|||
{ |
|||
hex = hex.Substring(1); |
|||
} |
|||
|
|||
if (hex.Length == 8) |
|||
{ |
|||
return hex; |
|||
} |
|||
|
|||
if (hex.Length == 6) |
|||
{ |
|||
return hex + "FF"; |
|||
} |
|||
|
|||
if (hex.Length < 3 || hex.Length > 4) |
|||
{ |
|||
return null; |
|||
} |
|||
|
|||
char r = hex[0]; |
|||
char g = hex[1]; |
|||
char b = hex[2]; |
|||
char a = hex.Length == 3 ? 'F' : hex[3]; |
|||
|
|||
return new string(new[] { r, r, g, g, b, b, a, a }); |
|||
} |
|||
} |
|||
} |
|||
@ -1,78 +0,0 @@ |
|||
// Copyright (c) Six Labors and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
|
|||
using SixLabors.ImageSharp.PixelFormats; |
|||
using SixLabors.ImageSharp.Processing.Processors.Dithering; |
|||
using SixLabors.Primitives; |
|||
|
|||
namespace SixLabors.ImageSharp.Processing |
|||
{ |
|||
/// <summary>
|
|||
/// Defines dithering extensions to apply on an <see cref="Image{TPixel}"/>
|
|||
/// using Mutate/Clone.
|
|||
/// </summary>
|
|||
public static class DitherExtensions |
|||
{ |
|||
/// <summary>
|
|||
/// Dithers the image reducing it to a web-safe palette using Bayer4x4 ordered dithering.
|
|||
/// </summary>
|
|||
/// <typeparam name="TPixel">The pixel format.</typeparam>
|
|||
/// <param name="source">The image this method extends.</param>
|
|||
/// <returns>The <see cref="IImageProcessingContext{TPixel}"/> to allow chaining of operations.</returns>
|
|||
public static IImageProcessingContext<TPixel> Dither<TPixel>(this IImageProcessingContext<TPixel> source) |
|||
where TPixel : struct, IPixel<TPixel> |
|||
=> Dither(source, KnownDitherers.BayerDither4x4); |
|||
|
|||
/// <summary>
|
|||
/// Dithers the image reducing it to a web-safe palette 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> Dither<TPixel>(this IImageProcessingContext<TPixel> source, IOrderedDither dither) |
|||
where TPixel : struct, IPixel<TPixel> |
|||
=> source.ApplyProcessor(new OrderedDitherPaletteProcessor<TPixel>(dither)); |
|||
|
|||
/// <summary>
|
|||
/// Dithers the image reducing it to the given palette 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="palette">The palette to select substitute colors from.</param>
|
|||
/// <returns>The <see cref="IImageProcessingContext{TPixel}"/> to allow chaining of operations.</returns>
|
|||
public static IImageProcessingContext<TPixel> Dither<TPixel>(this IImageProcessingContext<TPixel> source, IOrderedDither dither, TPixel[] palette) |
|||
where TPixel : struct, IPixel<TPixel> |
|||
=> source.ApplyProcessor(new OrderedDitherPaletteProcessor<TPixel>(dither, palette)); |
|||
|
|||
/// <summary>
|
|||
/// Dithers the image reducing it to a web-safe palette 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> Dither<TPixel>(this IImageProcessingContext<TPixel> source, IOrderedDither dither, Rectangle rectangle) |
|||
where TPixel : struct, IPixel<TPixel> |
|||
=> source.ApplyProcessor(new OrderedDitherPaletteProcessor<TPixel>(dither), rectangle); |
|||
|
|||
/// <summary>
|
|||
/// Dithers the image reducing it to the given palette 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="palette">The palette to select substitute colors from.</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> Dither<TPixel>(this IImageProcessingContext<TPixel> source, IOrderedDither dither, TPixel[] palette, Rectangle rectangle) |
|||
where TPixel : struct, IPixel<TPixel> |
|||
=> source.ApplyProcessor(new OrderedDitherPaletteProcessor<TPixel>(dither, palette), rectangle); |
|||
} |
|||
} |
|||
@ -0,0 +1,79 @@ |
|||
// Copyright (c) Six Labors and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
|
|||
using System; |
|||
|
|||
using SixLabors.ImageSharp.Processing.Processors.Dithering; |
|||
using SixLabors.Primitives; |
|||
|
|||
namespace SixLabors.ImageSharp.Processing |
|||
{ |
|||
/// <summary>
|
|||
/// Defines dithering extensions to apply on an <see cref="Image"/>
|
|||
/// using Mutate/Clone.
|
|||
/// </summary>
|
|||
public static class DitherExtensions |
|||
{ |
|||
/// <summary>
|
|||
/// Dithers the image reducing it to a web-safe palette using Bayer4x4 ordered dithering.
|
|||
/// </summary>
|
|||
/// <param name="source">The image this method extends.</param>
|
|||
/// <returns>The <see cref="IImageProcessingContext"/> to allow chaining of operations.</returns>
|
|||
public static IImageProcessingContext Dither(this IImageProcessingContext source) => |
|||
Dither(source, KnownDitherers.BayerDither4x4); |
|||
|
|||
/// <summary>
|
|||
/// Dithers the image reducing it to a web-safe palette using ordered dithering.
|
|||
/// </summary>
|
|||
/// <param name="source">The image this method extends.</param>
|
|||
/// <param name="dither">The ordered ditherer.</param>
|
|||
/// <returns>The <see cref="IImageProcessingContext"/> to allow chaining of operations.</returns>
|
|||
public static IImageProcessingContext Dither(this IImageProcessingContext source, IOrderedDither dither) => |
|||
source.ApplyProcessor(new OrderedDitherPaletteProcessor(dither)); |
|||
|
|||
/// <summary>
|
|||
/// Dithers the image reducing it to the given palette using ordered dithering.
|
|||
/// </summary>
|
|||
/// <param name="source">The image this method extends.</param>
|
|||
/// <param name="dither">The ordered ditherer.</param>
|
|||
/// <param name="palette">The palette to select substitute colors from.</param>
|
|||
/// <returns>The <see cref="IImageProcessingContext"/> to allow chaining of operations.</returns>
|
|||
public static IImageProcessingContext Dither( |
|||
this IImageProcessingContext source, |
|||
IOrderedDither dither, |
|||
ReadOnlyMemory<Color> palette) => |
|||
source.ApplyProcessor(new OrderedDitherPaletteProcessor(dither, palette)); |
|||
|
|||
/// <summary>
|
|||
/// Dithers the image reducing it to a web-safe palette using ordered dithering.
|
|||
/// </summary>
|
|||
/// <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"/> to allow chaining of operations.</returns>
|
|||
public static IImageProcessingContext Dither( |
|||
this IImageProcessingContext source, |
|||
IOrderedDither dither, |
|||
Rectangle rectangle) => |
|||
source.ApplyProcessor(new OrderedDitherPaletteProcessor(dither), rectangle); |
|||
|
|||
/// <summary>
|
|||
/// Dithers the image reducing it to the given palette using ordered dithering.
|
|||
/// </summary>
|
|||
/// <param name="source">The image this method extends.</param>
|
|||
/// <param name="dither">The ordered ditherer.</param>
|
|||
/// <param name="palette">The palette to select substitute colors from.</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"/> to allow chaining of operations.</returns>
|
|||
public static IImageProcessingContext Dither( |
|||
this IImageProcessingContext source, |
|||
IOrderedDither dither, |
|||
ReadOnlyMemory<Color> palette, |
|||
Rectangle rectangle) => |
|||
source.ApplyProcessor(new OrderedDitherPaletteProcessor(dither, palette), rectangle); |
|||
} |
|||
} |
|||
@ -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); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -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); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -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; |
|||
} |
|||
} |
|||
}); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,81 @@ |
|||
// 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.Primitives; |
|||
|
|||
namespace SixLabors.ImageSharp.Processing.Processors.Dithering |
|||
{ |
|||
/// <summary>
|
|||
/// An <see cref="IImageProcessor{TPixel}"/> that dithers an image using error diffusion.
|
|||
/// </summary>
|
|||
/// <typeparam name="TPixel">The pixel format.</typeparam>
|
|||
internal class ErrorDiffusionPaletteProcessor<TPixel> : PaletteDitherProcessor<TPixel> |
|||
where TPixel : struct, IPixel<TPixel> |
|||
{ |
|||
public ErrorDiffusionPaletteProcessor(ErrorDiffusionPaletteProcessor definition) |
|||
: base(definition) |
|||
{ |
|||
} |
|||
|
|||
private new ErrorDiffusionPaletteProcessor Definition => (ErrorDiffusionPaletteProcessor)base.Definition; |
|||
|
|||
/// <inheritdoc/>
|
|||
protected override void OnFrameApply(ImageFrame<TPixel> source, Rectangle sourceRectangle, Configuration configuration) |
|||
{ |
|||
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; |
|||
PixelPair<TPixel> pair = this.GetClosestPixelPair(ref 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)) |
|||
{ |
|||
pair = this.GetClosestPixelPair(ref sourcePixel); |
|||
|
|||
// No error to spread, exact match.
|
|||
if (sourcePixel.Equals(pair.First)) |
|||
{ |
|||
continue; |
|||
} |
|||
|
|||
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 ? pair.Second : pair.First; |
|||
this.Definition.Diffuser.Dither(source, sourcePixel, transformedPixel, x, y, startX, startY, endX, endY); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,79 @@ |
|||
// 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.Primitives; |
|||
|
|||
namespace SixLabors.ImageSharp.Processing.Processors.Dithering |
|||
{ |
|||
/// <summary>
|
|||
/// An <see cref="IImageProcessor{TPixel}"/> that dithers an image using error diffusion.
|
|||
/// </summary>
|
|||
/// <typeparam name="TPixel">The pixel format.</typeparam>
|
|||
internal class OrderedDitherPaletteProcessor<TPixel> : PaletteDitherProcessor<TPixel> |
|||
where TPixel : struct, IPixel<TPixel> |
|||
{ |
|||
public OrderedDitherPaletteProcessor(OrderedDitherPaletteProcessor definition) |
|||
: base(definition) |
|||
{ |
|||
} |
|||
|
|||
private new OrderedDitherPaletteProcessor Definition => (OrderedDitherPaletteProcessor)base.Definition; |
|||
|
|||
/// <inheritdoc/>
|
|||
protected override void OnFrameApply(ImageFrame<TPixel> source, Rectangle sourceRectangle, Configuration configuration) |
|||
{ |
|||
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; |
|||
PixelPair<TPixel> pair = this.GetClosestPixelPair(ref 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)) |
|||
{ |
|||
pair = this.GetClosestPixelPair(ref sourcePixel); |
|||
|
|||
// No error to spread, exact match.
|
|||
if (sourcePixel.Equals(pair.First)) |
|||
{ |
|||
continue; |
|||
} |
|||
|
|||
sourcePixel.ToRgba32(ref rgba); |
|||
luminance = isAlphaOnly ? rgba.A : ImageMaths.Get8BitBT709Luminance(rgba.R, rgba.G, rgba.B); |
|||
|
|||
// Setup the previous pointer
|
|||
previousPixel = sourcePixel; |
|||
} |
|||
|
|||
this.Definition.Dither.Dither(source, sourcePixel, pair.Second, pair.First, luminance, x, y); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,33 @@ |
|||
// Copyright (c) Six Labors and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
|
|||
using System; |
|||
|
|||
using SixLabors.ImageSharp.PixelFormats; |
|||
|
|||
namespace SixLabors.ImageSharp.Processing.Processors.Dithering |
|||
{ |
|||
/// <summary>
|
|||
/// The base class for dither and diffusion processors that consume a palette.
|
|||
/// </summary>
|
|||
public abstract class PaletteDitherProcessor : IImageProcessor |
|||
{ |
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="PaletteDitherProcessor"/> class.
|
|||
/// </summary>
|
|||
/// <param name="palette">The palette to select substitute colors from.</param>
|
|||
protected PaletteDitherProcessor(ReadOnlyMemory<Color> palette) |
|||
{ |
|||
this.Palette = palette; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets the palette to select substitute colors from.
|
|||
/// </summary>
|
|||
public ReadOnlyMemory<Color> Palette { get; } |
|||
|
|||
/// <inheritdoc />
|
|||
public abstract IImageProcessor<TPixel> CreatePixelSpecificProcessor<TPixel>() |
|||
where TPixel : struct, IPixel<TPixel>; |
|||
} |
|||
} |
|||
@ -0,0 +1,101 @@ |
|||
// Copyright (c) Six Labors and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
|
|||
using System; |
|||
using System.Buffers; |
|||
|
|||
using SixLabors.ImageSharp.Advanced; |
|||
using SixLabors.ImageSharp.Memory; |
|||
using SixLabors.ImageSharp.ParallelUtils; |
|||
using SixLabors.ImageSharp.PixelFormats; |
|||
using SixLabors.Primitives; |
|||
|
|||
namespace SixLabors.ImageSharp.Processing.Processors.Overlays |
|||
{ |
|||
/// <summary>
|
|||
/// Sets the background color of the image.
|
|||
/// </summary>
|
|||
/// <typeparam name="TPixel">The pixel format.</typeparam>
|
|||
internal class BackgroundColorProcessor<TPixel> : ImageProcessor<TPixel> |
|||
where TPixel : struct, IPixel<TPixel> |
|||
{ |
|||
private readonly BackgroundColorProcessor definition; |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="BackgroundColorProcessor{TPixel}"/> class.
|
|||
/// </summary>
|
|||
public BackgroundColorProcessor(BackgroundColorProcessor definition) |
|||
{ |
|||
this.definition = definition; |
|||
} |
|||
|
|||
/// <inheritdoc/>
|
|||
protected override void OnFrameApply( |
|||
ImageFrame<TPixel> source, |
|||
Rectangle sourceRectangle, |
|||
Configuration configuration) |
|||
{ |
|||
TPixel color = this.definition.Color.ToPixel<TPixel>(); |
|||
GraphicsOptions graphicsOptions = this.definition.GraphicsOptions; |
|||
|
|||
int startY = sourceRectangle.Y; |
|||
int endY = sourceRectangle.Bottom; |
|||
int startX = sourceRectangle.X; |
|||
int endX = sourceRectangle.Right; |
|||
|
|||
// Align start/end positions.
|
|||
int minX = Math.Max(0, startX); |
|||
int maxX = Math.Min(source.Width, endX); |
|||
int minY = Math.Max(0, startY); |
|||
int maxY = Math.Min(source.Height, endY); |
|||
|
|||
// Reset offset if necessary.
|
|||
if (minX > 0) |
|||
{ |
|||
startX = 0; |
|||
} |
|||
|
|||
if (minY > 0) |
|||
{ |
|||
startY = 0; |
|||
} |
|||
|
|||
int width = maxX - minX; |
|||
|
|||
var workingRect = Rectangle.FromLTRB(minX, minY, maxX, maxY); |
|||
|
|||
using (IMemoryOwner<TPixel> colors = source.MemoryAllocator.Allocate<TPixel>(width)) |
|||
using (IMemoryOwner<float> amount = source.MemoryAllocator.Allocate<float>(width)) |
|||
{ |
|||
// Be careful! Do not capture colorSpan & amountSpan in the lambda below!
|
|||
Span<TPixel> colorSpan = colors.GetSpan(); |
|||
Span<float> amountSpan = amount.GetSpan(); |
|||
|
|||
colorSpan.Fill(color); |
|||
amountSpan.Fill(graphicsOptions.BlendPercentage); |
|||
|
|||
PixelBlender<TPixel> blender = PixelOperations<TPixel>.Instance.GetPixelBlender(graphicsOptions); |
|||
|
|||
ParallelHelper.IterateRows( |
|||
workingRect, |
|||
configuration, |
|||
rows => |
|||
{ |
|||
for (int y = rows.Min; y < rows.Max; y++) |
|||
{ |
|||
Span<TPixel> destination = |
|||
source.GetPixelRowSpan(y - startY).Slice(minX - startX, width); |
|||
|
|||
// This switched color & destination in the 2nd and 3rd places because we are applying the target color under the current one
|
|||
blender.Blend( |
|||
source.Configuration, |
|||
destination, |
|||
colors.GetSpan(), |
|||
destination, |
|||
amount.GetSpan()); |
|||
} |
|||
}); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -1,158 +1,78 @@ |
|||
// Copyright (c) Six Labors and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
|
|||
using System; |
|||
using System.Buffers; |
|||
using System.Numerics; |
|||
using System.Threading.Tasks; |
|||
using SixLabors.ImageSharp.Advanced; |
|||
using SixLabors.ImageSharp.Memory; |
|||
using SixLabors.ImageSharp.ParallelUtils; |
|||
using SixLabors.ImageSharp.PixelFormats; |
|||
using SixLabors.ImageSharp.Primitives; |
|||
using SixLabors.Memory; |
|||
using SixLabors.Primitives; |
|||
|
|||
namespace SixLabors.ImageSharp.Processing.Processors.Overlays |
|||
{ |
|||
/// <summary>
|
|||
/// An <see cref="IImageProcessor{TPixel}"/> that applies a radial glow effect an <see cref="Image{TPixel}"/>.
|
|||
/// Defines a radial glow effect applicable to an <see cref="Image"/>.
|
|||
/// </summary>
|
|||
/// <typeparam name="TPixel">The pixel format.</typeparam>
|
|||
internal class GlowProcessor<TPixel> : ImageProcessor<TPixel> |
|||
where TPixel : struct, IPixel<TPixel> |
|||
public sealed class GlowProcessor : IImageProcessor |
|||
{ |
|||
private readonly PixelBlender<TPixel> blender; |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="GlowProcessor{TPixel}" /> class.
|
|||
/// Initializes a new instance of the <see cref="GlowProcessor" /> class.
|
|||
/// </summary>
|
|||
/// <param name="color">The color or the glow.</param>
|
|||
public GlowProcessor(TPixel color) |
|||
public GlowProcessor(Color color) |
|||
: this(color, 0) |
|||
{ |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="GlowProcessor{TPixel}" /> class.
|
|||
/// Initializes a new instance of the <see cref="GlowProcessor" /> class.
|
|||
/// </summary>
|
|||
/// <param name="color">The color or the glow.</param>
|
|||
/// <param name="radius">The radius of the glow.</param>
|
|||
public GlowProcessor(TPixel color, ValueSize radius) |
|||
: this(color, radius, GraphicsOptions.Default) |
|||
/// <param name="options">The options effecting blending and composition.</param>
|
|||
public GlowProcessor(Color color, GraphicsOptions options) |
|||
: this(color, 0, options) |
|||
{ |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="GlowProcessor{TPixel}" /> class.
|
|||
/// Initializes a new instance of the <see cref="GlowProcessor" /> class.
|
|||
/// </summary>
|
|||
/// <param name="color">The color or the glow.</param>
|
|||
/// <param name="options">The options effecting blending and composition.</param>
|
|||
public GlowProcessor(TPixel color, GraphicsOptions options) |
|||
: this(color, 0, options) |
|||
/// <param name="radius">The radius of the glow.</param>
|
|||
internal GlowProcessor(Color color, ValueSize radius) |
|||
: this(color, radius, GraphicsOptions.Default) |
|||
{ |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="GlowProcessor{TPixel}" /> class.
|
|||
/// Initializes a new instance of the <see cref="GlowProcessor" /> class.
|
|||
/// </summary>
|
|||
/// <param name="color">The color or the glow.</param>
|
|||
/// <param name="radius">The radius of the glow.</param>
|
|||
/// <param name="options">The options effecting blending and composition.</param>
|
|||
public GlowProcessor(TPixel color, ValueSize radius, GraphicsOptions options) |
|||
internal GlowProcessor(Color color, ValueSize radius, GraphicsOptions options) |
|||
{ |
|||
this.GlowColor = color; |
|||
this.Radius = radius; |
|||
this.blender = PixelOperations<TPixel>.Instance.GetPixelBlender(options); |
|||
this.GraphicsOptions = options; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets the options effecting blending and composition
|
|||
/// Gets the options effecting blending and composition.
|
|||
/// </summary>
|
|||
public GraphicsOptions GraphicsOptions { get; } |
|||
|
|||
/// <summary>
|
|||
/// Gets or sets the glow color to apply.
|
|||
/// Gets the glow color to apply.
|
|||
/// </summary>
|
|||
public TPixel GlowColor { get; set; } |
|||
public Color GlowColor { get; } |
|||
|
|||
/// <summary>
|
|||
/// Gets or sets the the radius.
|
|||
/// Gets the the radius.
|
|||
/// </summary>
|
|||
public ValueSize Radius { get; set; } |
|||
internal ValueSize Radius { get; } |
|||
|
|||
/// <inheritdoc/>
|
|||
protected override void OnFrameApply(ImageFrame<TPixel> source, Rectangle sourceRectangle, Configuration configuration) |
|||
/// <inheritdoc />
|
|||
public IImageProcessor<TPixel> CreatePixelSpecificProcessor<TPixel>() |
|||
where TPixel : struct, IPixel<TPixel> |
|||
{ |
|||
// TODO: can we simplify the rectangle calculation?
|
|||
int startY = sourceRectangle.Y; |
|||
int endY = sourceRectangle.Bottom; |
|||
int startX = sourceRectangle.X; |
|||
int endX = sourceRectangle.Right; |
|||
TPixel glowColor = this.GlowColor; |
|||
Vector2 center = Rectangle.Center(sourceRectangle); |
|||
|
|||
float finalRadius = this.Radius.Calculate(source.Size()); |
|||
|
|||
float maxDistance = finalRadius > 0 ? MathF.Min(finalRadius, sourceRectangle.Width * .5F) : sourceRectangle.Width * .5F; |
|||
|
|||
// Align start/end positions.
|
|||
int minX = Math.Max(0, startX); |
|||
int maxX = Math.Min(source.Width, endX); |
|||
int minY = Math.Max(0, startY); |
|||
int maxY = Math.Min(source.Height, endY); |
|||
|
|||
// Reset offset if necessary.
|
|||
if (minX > 0) |
|||
{ |
|||
startX = 0; |
|||
} |
|||
|
|||
if (minY > 0) |
|||
{ |
|||
startY = 0; |
|||
} |
|||
|
|||
int width = maxX - minX; |
|||
int offsetX = minX - startX; |
|||
|
|||
var workingRect = Rectangle.FromLTRB(minX, minY, maxX, maxY); |
|||
|
|||
using (IMemoryOwner<TPixel> rowColors = source.MemoryAllocator.Allocate<TPixel>(width)) |
|||
{ |
|||
rowColors.GetSpan().Fill(glowColor); |
|||
|
|||
ParallelHelper.IterateRowsWithTempBuffer<float>( |
|||
workingRect, |
|||
configuration, |
|||
(rows, amounts) => |
|||
{ |
|||
Span<float> amountsSpan = amounts.Span; |
|||
|
|||
for (int y = rows.Min; y < rows.Max; y++) |
|||
{ |
|||
int offsetY = y - startY; |
|||
|
|||
for (int i = 0; i < width; i++) |
|||
{ |
|||
float distance = Vector2.Distance(center, new Vector2(i + offsetX, offsetY)); |
|||
amountsSpan[i] = |
|||
(this.GraphicsOptions.BlendPercentage * (1 - (.95F * (distance / maxDistance)))) |
|||
.Clamp(0, 1); |
|||
} |
|||
|
|||
Span<TPixel> destination = source.GetPixelRowSpan(offsetY).Slice(offsetX, width); |
|||
|
|||
this.blender.Blend( |
|||
source.Configuration, |
|||
destination, |
|||
destination, |
|||
rowColors.GetSpan(), |
|||
amountsSpan); |
|||
} |
|||
}); |
|||
} |
|||
return new GlowProcessor<TPixel>(this); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,112 @@ |
|||
// Copyright (c) Six Labors and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
|
|||
using System; |
|||
using System.Buffers; |
|||
using System.Numerics; |
|||
|
|||
using SixLabors.ImageSharp.Advanced; |
|||
using SixLabors.ImageSharp.Memory; |
|||
using SixLabors.ImageSharp.ParallelUtils; |
|||
using SixLabors.ImageSharp.PixelFormats; |
|||
using SixLabors.Primitives; |
|||
|
|||
namespace SixLabors.ImageSharp.Processing.Processors.Overlays |
|||
{ |
|||
/// <summary>
|
|||
/// An <see cref="IImageProcessor{TPixel}"/> that applies a radial glow effect an <see cref="Image{TPixel}"/>.
|
|||
/// </summary>
|
|||
/// <typeparam name="TPixel">The pixel format.</typeparam>
|
|||
internal class GlowProcessor<TPixel> : ImageProcessor<TPixel> |
|||
where TPixel : struct, IPixel<TPixel> |
|||
{ |
|||
private readonly PixelBlender<TPixel> blender; |
|||
|
|||
private readonly GlowProcessor definition; |
|||
|
|||
public GlowProcessor(GlowProcessor definition) |
|||
{ |
|||
this.definition = definition; |
|||
this.blender = PixelOperations<TPixel>.Instance.GetPixelBlender(definition.GraphicsOptions); |
|||
} |
|||
|
|||
/// <inheritdoc/>
|
|||
protected override void OnFrameApply( |
|||
ImageFrame<TPixel> source, |
|||
Rectangle sourceRectangle, |
|||
Configuration configuration) |
|||
{ |
|||
// TODO: can we simplify the rectangle calculation?
|
|||
int startY = sourceRectangle.Y; |
|||
int endY = sourceRectangle.Bottom; |
|||
int startX = sourceRectangle.X; |
|||
int endX = sourceRectangle.Right; |
|||
TPixel glowColor = this.definition.GlowColor.ToPixel<TPixel>(); |
|||
Vector2 center = Rectangle.Center(sourceRectangle); |
|||
|
|||
float finalRadius = this.definition.Radius.Calculate(source.Size()); |
|||
|
|||
float maxDistance = finalRadius > 0 |
|||
? MathF.Min(finalRadius, sourceRectangle.Width * .5F) |
|||
: sourceRectangle.Width * .5F; |
|||
|
|||
// Align start/end positions.
|
|||
int minX = Math.Max(0, startX); |
|||
int maxX = Math.Min(source.Width, endX); |
|||
int minY = Math.Max(0, startY); |
|||
int maxY = Math.Min(source.Height, endY); |
|||
|
|||
// Reset offset if necessary.
|
|||
if (minX > 0) |
|||
{ |
|||
startX = 0; |
|||
} |
|||
|
|||
if (minY > 0) |
|||
{ |
|||
startY = 0; |
|||
} |
|||
|
|||
int width = maxX - minX; |
|||
int offsetX = minX - startX; |
|||
|
|||
var workingRect = Rectangle.FromLTRB(minX, minY, maxX, maxY); |
|||
|
|||
float blendPercentage = this.definition.GraphicsOptions.BlendPercentage; |
|||
|
|||
using (IMemoryOwner<TPixel> rowColors = source.MemoryAllocator.Allocate<TPixel>(width)) |
|||
{ |
|||
rowColors.GetSpan().Fill(glowColor); |
|||
|
|||
ParallelHelper.IterateRowsWithTempBuffer<float>( |
|||
workingRect, |
|||
configuration, |
|||
(rows, amounts) => |
|||
{ |
|||
Span<float> amountsSpan = amounts.Span; |
|||
|
|||
for (int y = rows.Min; y < rows.Max; y++) |
|||
{ |
|||
int offsetY = y - startY; |
|||
|
|||
for (int i = 0; i < width; i++) |
|||
{ |
|||
float distance = Vector2.Distance(center, new Vector2(i + offsetX, offsetY)); |
|||
amountsSpan[i] = |
|||
(blendPercentage * (1 - (.95F * (distance / maxDistance)))).Clamp(0, 1); |
|||
} |
|||
|
|||
Span<TPixel> destination = source.GetPixelRowSpan(offsetY).Slice(offsetX, width); |
|||
|
|||
this.blender.Blend( |
|||
source.Configuration, |
|||
destination, |
|||
destination, |
|||
rowColors.GetSpan(), |
|||
amountsSpan); |
|||
} |
|||
}); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,114 @@ |
|||
// Copyright (c) Six Labors and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
|
|||
using System; |
|||
using System.Buffers; |
|||
using System.Numerics; |
|||
|
|||
using SixLabors.ImageSharp.Advanced; |
|||
using SixLabors.ImageSharp.Memory; |
|||
using SixLabors.ImageSharp.ParallelUtils; |
|||
using SixLabors.ImageSharp.PixelFormats; |
|||
using SixLabors.Primitives; |
|||
|
|||
namespace SixLabors.ImageSharp.Processing.Processors.Overlays |
|||
{ |
|||
/// <summary>
|
|||
/// An <see cref="IImageProcessor{TPixel}"/> that applies a radial vignette effect to an <see cref="Image{TPixel}"/>.
|
|||
/// </summary>
|
|||
/// <typeparam name="TPixel">The pixel format.</typeparam>
|
|||
internal class VignetteProcessor<TPixel> : ImageProcessor<TPixel> |
|||
where TPixel : struct, IPixel<TPixel> |
|||
{ |
|||
private readonly PixelBlender<TPixel> blender; |
|||
|
|||
private readonly VignetteProcessor definition; |
|||
|
|||
public VignetteProcessor(VignetteProcessor definition) |
|||
{ |
|||
this.definition = definition; |
|||
this.blender = PixelOperations<TPixel>.Instance.GetPixelBlender(definition.GraphicsOptions); |
|||
} |
|||
|
|||
/// <inheritdoc/>
|
|||
protected override void OnFrameApply( |
|||
ImageFrame<TPixel> source, |
|||
Rectangle sourceRectangle, |
|||
Configuration configuration) |
|||
{ |
|||
int startY = sourceRectangle.Y; |
|||
int endY = sourceRectangle.Bottom; |
|||
int startX = sourceRectangle.X; |
|||
int endX = sourceRectangle.Right; |
|||
TPixel vignetteColor = this.definition.VignetteColor.ToPixel<TPixel>(); |
|||
Vector2 centre = Rectangle.Center(sourceRectangle); |
|||
|
|||
Size sourceSize = source.Size(); |
|||
float finalRadiusX = this.definition.RadiusX.Calculate(sourceSize); |
|||
float finalRadiusY = this.definition.RadiusY.Calculate(sourceSize); |
|||
float rX = finalRadiusX > 0 |
|||
? MathF.Min(finalRadiusX, sourceRectangle.Width * .5F) |
|||
: sourceRectangle.Width * .5F; |
|||
float rY = finalRadiusY > 0 |
|||
? MathF.Min(finalRadiusY, sourceRectangle.Height * .5F) |
|||
: sourceRectangle.Height * .5F; |
|||
float maxDistance = MathF.Sqrt((rX * rX) + (rY * rY)); |
|||
|
|||
// Align start/end positions.
|
|||
int minX = Math.Max(0, startX); |
|||
int maxX = Math.Min(source.Width, endX); |
|||
int minY = Math.Max(0, startY); |
|||
int maxY = Math.Min(source.Height, endY); |
|||
|
|||
// Reset offset if necessary.
|
|||
if (minX > 0) |
|||
{ |
|||
startX = 0; |
|||
} |
|||
|
|||
if (minY > 0) |
|||
{ |
|||
startY = 0; |
|||
} |
|||
|
|||
int width = maxX - minX; |
|||
int offsetX = minX - startX; |
|||
|
|||
var workingRect = Rectangle.FromLTRB(minX, minY, maxX, maxY); |
|||
float blendPercentage = this.definition.GraphicsOptions.BlendPercentage; |
|||
|
|||
using (IMemoryOwner<TPixel> rowColors = source.MemoryAllocator.Allocate<TPixel>(width)) |
|||
{ |
|||
rowColors.GetSpan().Fill(vignetteColor); |
|||
|
|||
ParallelHelper.IterateRowsWithTempBuffer<float>( |
|||
workingRect, |
|||
configuration, |
|||
(rows, amounts) => |
|||
{ |
|||
Span<float> amountsSpan = amounts.Span; |
|||
|
|||
for (int y = rows.Min; y < rows.Max; y++) |
|||
{ |
|||
int offsetY = y - startY; |
|||
|
|||
for (int i = 0; i < width; i++) |
|||
{ |
|||
float distance = Vector2.Distance(centre, new Vector2(i + offsetX, offsetY)); |
|||
amountsSpan[i] = (blendPercentage * (.9F * (distance / maxDistance))).Clamp(0, 1); |
|||
} |
|||
|
|||
Span<TPixel> destination = source.GetPixelRowSpan(offsetY).Slice(offsetX, width); |
|||
|
|||
this.blender.Blend( |
|||
source.Configuration, |
|||
destination, |
|||
destination, |
|||
rowColors.GetSpan(), |
|||
amountsSpan); |
|||
} |
|||
}); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,38 @@ |
|||
// Copyright (c) Six Labors and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
|
|||
using System; |
|||
|
|||
using SixLabors.ImageSharp.PixelFormats; |
|||
|
|||
namespace SixLabors.ImageSharp.Processing.Processors.Quantization |
|||
{ |
|||
/// <summary>
|
|||
/// Defines an abstraction to represent a quantized image frame where the pixels indexed by a color palette.
|
|||
/// </summary>
|
|||
/// <typeparam name="TPixel">The pixel format.</typeparam>
|
|||
public interface IQuantizedFrame<TPixel> : IDisposable |
|||
where TPixel : struct, IPixel<TPixel> |
|||
{ |
|||
/// <summary>
|
|||
/// Gets the width of this <see cref="QuantizedFrame{TPixel}"/>.
|
|||
/// </summary>
|
|||
int Width { get; } |
|||
|
|||
/// <summary>
|
|||
/// Gets the height of this <see cref="QuantizedFrame{TPixel}"/>.
|
|||
/// </summary>
|
|||
int Height { get; } |
|||
|
|||
/// <summary>
|
|||
/// Gets the color palette of this <see cref="QuantizedFrame{TPixel}"/>.
|
|||
/// </summary>
|
|||
ReadOnlyMemory<TPixel> Palette { get; } |
|||
|
|||
/// <summary>
|
|||
/// Gets the pixels of this <see cref="QuantizedFrame{TPixel}"/>.
|
|||
/// </summary>
|
|||
/// <returns>The <see cref="Span{T}"/>The pixel span.</returns>
|
|||
ReadOnlySpan<byte> GetPixelSpan(); |
|||
} |
|||
} |
|||
@ -1,110 +0,0 @@ |
|||
// Copyright (c) Six Labors and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
|
|||
using System; |
|||
using System.Runtime.CompilerServices; |
|||
using SixLabors.ImageSharp.PixelFormats; |
|||
using SixLabors.ImageSharp.Processing.Processors.Dithering; |
|||
|
|||
namespace SixLabors.ImageSharp.Processing.Processors.Quantization |
|||
{ |
|||
/// <summary>
|
|||
/// A generic palette quantizer.
|
|||
/// </summary>
|
|||
/// <typeparam name="TPixel">The pixel format.</typeparam>
|
|||
public class PaletteQuantizer<TPixel> : IQuantizer |
|||
where TPixel : struct, IPixel<TPixel> |
|||
{ |
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="PaletteQuantizer{TPixel}"/> class.
|
|||
/// </summary>
|
|||
/// <param name="palette">The color palette to use.</param>
|
|||
public PaletteQuantizer(TPixel[] palette) |
|||
: this(palette, true) |
|||
{ |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="PaletteQuantizer{TPixel}"/> class.
|
|||
/// </summary>
|
|||
/// <param name="palette">The color palette to use.</param>
|
|||
/// <param name="dither">Whether to apply dithering to the output image</param>
|
|||
public PaletteQuantizer(TPixel[] palette, bool dither) |
|||
: this(palette, GetDiffuser(dither)) |
|||
{ |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="PaletteQuantizer{TPixel}"/> class.
|
|||
/// </summary>
|
|||
/// <param name="palette">The color palette to use.</param>
|
|||
/// <param name="diffuser">The error diffusion algorithm, if any, to apply to the output image</param>
|
|||
public PaletteQuantizer(TPixel[] palette, IErrorDiffuser diffuser) |
|||
{ |
|||
Guard.MustBeBetweenOrEqualTo(palette.Length, QuantizerConstants.MinColors, QuantizerConstants.MaxColors, nameof(palette)); |
|||
this.Palette = palette; |
|||
this.Diffuser = diffuser; |
|||
} |
|||
|
|||
/// <inheritdoc/>
|
|||
public IErrorDiffuser Diffuser { get; } |
|||
|
|||
/// <summary>
|
|||
/// Gets the palette.
|
|||
/// </summary>
|
|||
public TPixel[] Palette { get; } |
|||
|
|||
/// <summary>
|
|||
/// Creates the generic frame quantizer.
|
|||
/// </summary>
|
|||
/// <param name="configuration">The <see cref="Configuration"/> to configure internal operations.</param>
|
|||
/// <returns>The <see cref="IFrameQuantizer{TPixel}"/>.</returns>
|
|||
public IFrameQuantizer<TPixel> CreateFrameQuantizer(Configuration configuration) |
|||
=> ((IQuantizer)this).CreateFrameQuantizer<TPixel>(configuration); |
|||
|
|||
/// <summary>
|
|||
/// Creates the generic frame quantizer.
|
|||
/// </summary>
|
|||
/// <param name="configuration">The <see cref="Configuration"/> to configure internal operations.</param>
|
|||
/// <param name="maxColors">The maximum number of colors to hold in the color palette.</param>
|
|||
/// <returns>The <see cref="IFrameQuantizer{TPixel}"/>.</returns>
|
|||
public IFrameQuantizer<TPixel> CreateFrameQuantizer(Configuration configuration, int maxColors) |
|||
=> ((IQuantizer)this).CreateFrameQuantizer<TPixel>(configuration, maxColors); |
|||
|
|||
/// <inheritdoc/>
|
|||
IFrameQuantizer<TPixel1> IQuantizer.CreateFrameQuantizer<TPixel1>(Configuration configuration) |
|||
{ |
|||
if (!typeof(TPixel).Equals(typeof(TPixel1))) |
|||
{ |
|||
throw new InvalidOperationException("Generic method type must be the same as class type."); |
|||
} |
|||
|
|||
TPixel[] paletteRef = this.Palette; |
|||
return new PaletteFrameQuantizer<TPixel1>(this, Unsafe.As<TPixel[], TPixel1[]>(ref paletteRef)); |
|||
} |
|||
|
|||
/// <inheritdoc/>
|
|||
IFrameQuantizer<TPixel1> IQuantizer.CreateFrameQuantizer<TPixel1>(Configuration configuration, int maxColors) |
|||
{ |
|||
if (!typeof(TPixel).Equals(typeof(TPixel1))) |
|||
{ |
|||
throw new InvalidOperationException("Generic method type must be the same as class type."); |
|||
} |
|||
|
|||
TPixel[] paletteRef = this.Palette; |
|||
TPixel1[] castPalette = Unsafe.As<TPixel[], TPixel1[]>(ref paletteRef); |
|||
|
|||
maxColors = maxColors.Clamp(QuantizerConstants.MinColors, QuantizerConstants.MaxColors); |
|||
int max = Math.Min(maxColors, castPalette.Length); |
|||
|
|||
if (max != castPalette.Length) |
|||
{ |
|||
return new PaletteFrameQuantizer<TPixel1>(this, castPalette.AsSpan(0, max).ToArray()); |
|||
} |
|||
|
|||
return new PaletteFrameQuantizer<TPixel1>(this, castPalette); |
|||
} |
|||
|
|||
private static IErrorDiffuser GetDiffuser(bool dither) => dither ? KnownDiffusers.FloydSteinberg : null; |
|||
} |
|||
} |
|||
@ -0,0 +1,29 @@ |
|||
// Copyright (c) Six Labors and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
|
|||
using System; |
|||
using System.Runtime.CompilerServices; |
|||
|
|||
using SixLabors.ImageSharp.PixelFormats; |
|||
|
|||
namespace SixLabors.ImageSharp.Processing.Processors.Quantization |
|||
{ |
|||
/// <summary>
|
|||
/// Contains extension methods for <see cref="IQuantizedFrame{TPixel}"/>.
|
|||
/// </summary>
|
|||
public static class QuantizedFrameExtensions |
|||
{ |
|||
/// <summary>
|
|||
/// Gets the representation of the pixels as a <see cref="Span{T}"/> of contiguous memory
|
|||
/// at row <paramref name="rowIndex"/> beginning from the the first pixel on that row.
|
|||
/// </summary>
|
|||
/// <param name="frame">The <see cref="IQuantizedFrame{TPixel}"/>.</param>
|
|||
/// <param name="rowIndex">The row.</param>
|
|||
/// <typeparam name="TPixel">The pixel type.</typeparam>
|
|||
/// <returns>The pixel row as a <see cref="ReadOnlySpan{T}"/>.</returns>
|
|||
[MethodImpl(InliningOptions.ShortMethod)] |
|||
public static ReadOnlySpan<byte> GetRowSpan<TPixel>(this IQuantizedFrame<TPixel> frame, int rowIndex) |
|||
where TPixel : struct, IPixel<TPixel> |
|||
=> frame.GetPixelSpan().Slice(rowIndex * frame.Width, frame.Width); |
|||
} |
|||
} |
|||
Some files were not shown because too many files changed in this diff
Loading…
Reference in new issue