mirror of https://github.com/SixLabors/ImageSharp
Browse Source
Former-commit-id: ba6b2de4807dd80b08a63cf61907023954eea676 Former-commit-id: dffed09b1486af8ffd105e22c29c4d5e9907a846 Former-commit-id: f32e945c059766c57c939fbb7de94c5e61b15d0apull/17/head
65 changed files with 1791 additions and 1671 deletions
@ -1,397 +0,0 @@ |
|||||
// <copyright file="Bgra.cs" company="James South">
|
|
||||
// Copyright (c) James South and contributors.
|
|
||||
// Licensed under the Apache License, Version 2.0.
|
|
||||
// </copyright>
|
|
||||
|
|
||||
namespace ImageProcessor |
|
||||
{ |
|
||||
using System; |
|
||||
using System.ComponentModel; |
|
||||
using System.Runtime.InteropServices; |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Represents an BGRA (blue, green, red, alpha) color.
|
|
||||
/// </summary>
|
|
||||
[StructLayout(LayoutKind.Explicit)] |
|
||||
public struct Bgra : IEquatable<Bgra> |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// Represents a <see cref="Bgra"/> that has B, G, R, and A values set to zero.
|
|
||||
/// </summary>
|
|
||||
public static readonly Bgra Empty = default(Bgra); |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Represents a transparent <see cref="Bgra"/> that has B, G, R, and A values set to 255, 255, 255, 0.
|
|
||||
/// </summary>
|
|
||||
public static readonly Bgra Transparent = new Bgra(255, 255, 255, 0); |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Represents a black <see cref="Bgra"/> that has B, G, R, and A values set to 0, 0, 0, 0.
|
|
||||
/// </summary>
|
|
||||
public static readonly Bgra Black = new Bgra(0, 0, 0, 255); |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Represents a white <see cref="Bgra"/> that has B, G, R, and A values set to 255, 255, 255, 255.
|
|
||||
/// </summary>
|
|
||||
public static readonly Bgra White = new Bgra(255, 255, 255, 255); |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Holds the blue component of the color
|
|
||||
/// </summary>
|
|
||||
[FieldOffset(0)] |
|
||||
public readonly byte B; |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Holds the green component of the color
|
|
||||
/// </summary>
|
|
||||
[FieldOffset(1)] |
|
||||
public readonly byte G; |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Holds the red component of the color
|
|
||||
/// </summary>
|
|
||||
[FieldOffset(2)] |
|
||||
public readonly byte R; |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Holds the alpha component of the color
|
|
||||
/// </summary>
|
|
||||
[FieldOffset(3)] |
|
||||
public readonly byte A; |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Permits the <see cref="Bgra"/> to be treated as a 32 bit integer.
|
|
||||
/// </summary>
|
|
||||
[FieldOffset(0)] |
|
||||
public readonly int BGRA; |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// The epsilon for comparing floating point numbers.
|
|
||||
/// </summary>
|
|
||||
private const float Epsilon = 0.0001f; |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Initializes a new instance of the <see cref="Bgra"/> struct.
|
|
||||
/// </summary>
|
|
||||
/// <param name="b">
|
|
||||
/// The blue component of this <see cref="Bgra"/>.
|
|
||||
/// </param>
|
|
||||
/// <param name="g">
|
|
||||
/// The green component of this <see cref="Bgra"/>.
|
|
||||
/// </param>
|
|
||||
/// <param name="r">
|
|
||||
/// The red component of this <see cref="Bgra"/>.
|
|
||||
/// </param>
|
|
||||
public Bgra(byte b, byte g, byte r) |
|
||||
: this() |
|
||||
{ |
|
||||
this.B = b; |
|
||||
this.G = g; |
|
||||
this.R = r; |
|
||||
this.A = 255; |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Initializes a new instance of the <see cref="Bgra"/> struct.
|
|
||||
/// </summary>
|
|
||||
/// <param name="b">
|
|
||||
/// The blue component of this <see cref="Bgra"/>.
|
|
||||
/// </param>
|
|
||||
/// <param name="g">
|
|
||||
/// The green component of this <see cref="Bgra"/>.
|
|
||||
/// </param>
|
|
||||
/// <param name="r">
|
|
||||
/// The red component of this <see cref="Bgra"/>.
|
|
||||
/// </param>
|
|
||||
/// <param name="a">
|
|
||||
/// The alpha component of this <see cref="Bgra"/>.
|
|
||||
/// </param>
|
|
||||
public Bgra(byte b, byte g, byte r, byte a) |
|
||||
: this() |
|
||||
{ |
|
||||
this.B = b; |
|
||||
this.G = g; |
|
||||
this.R = r; |
|
||||
this.A = a; |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Initializes a new instance of the <see cref="Bgra"/> struct.
|
|
||||
/// </summary>
|
|
||||
/// <param name="bgra">
|
|
||||
/// The combined color components.
|
|
||||
/// </param>
|
|
||||
public Bgra(int bgra) |
|
||||
: this() |
|
||||
{ |
|
||||
this.BGRA = bgra; |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Initializes a new instance of the <see cref="Bgra"/> struct.
|
|
||||
/// </summary>
|
|
||||
/// <param name="hex">
|
|
||||
/// The hexadecimal representation of the combined color components arranged
|
|
||||
/// in rgb, rrggbb, or aarrggbb format to match web syntax.
|
|
||||
/// </param>
|
|
||||
public Bgra(string hex) |
|
||||
: this() |
|
||||
{ |
|
||||
// Hexadecimal representations are layed out AARRGGBB to we need to do some reordering.
|
|
||||
hex = hex.StartsWith("#") ? hex.Substring(1) : hex; |
|
||||
|
|
||||
if (hex.Length != 8 && hex.Length != 6 && hex.Length != 3) |
|
||||
{ |
|
||||
throw new ArgumentException("Hexadecimal string is not in the correct format.", nameof(hex)); |
|
||||
} |
|
||||
|
|
||||
if (hex.Length == 8) |
|
||||
{ |
|
||||
this.B = Convert.ToByte(hex.Substring(6, 2), 16); |
|
||||
this.G = Convert.ToByte(hex.Substring(4, 2), 16); |
|
||||
this.R = Convert.ToByte(hex.Substring(2, 2), 16); |
|
||||
this.A = Convert.ToByte(hex.Substring(0, 2), 16); |
|
||||
} |
|
||||
else if (hex.Length == 6) |
|
||||
{ |
|
||||
this.B = Convert.ToByte(hex.Substring(4, 2), 16); |
|
||||
this.G = Convert.ToByte(hex.Substring(2, 2), 16); |
|
||||
this.R = Convert.ToByte(hex.Substring(0, 2), 16); |
|
||||
this.A = 255; |
|
||||
} |
|
||||
else |
|
||||
{ |
|
||||
string b = char.ToString(hex[2]); |
|
||||
string g = char.ToString(hex[1]); |
|
||||
string r = char.ToString(hex[0]); |
|
||||
|
|
||||
this.B = Convert.ToByte(b + b, 16); |
|
||||
this.G = Convert.ToByte(g + g, 16); |
|
||||
this.R = Convert.ToByte(r + r, 16); |
|
||||
this.A = 255; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Gets a value indicating whether this <see cref="Bgra"/> is empty.
|
|
||||
/// </summary>
|
|
||||
[EditorBrowsable(EditorBrowsableState.Never)] |
|
||||
public bool IsEmpty => this.B == 0 && this.G == 0 && this.R == 0 && this.A == 0; |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Allows the implicit conversion of an instance of <see cref="Hsv"/> to a
|
|
||||
/// <see cref="Bgra"/>.
|
|
||||
/// </summary>
|
|
||||
/// <param name="color">
|
|
||||
/// The instance of <see cref="Hsv"/> to convert.
|
|
||||
/// </param>
|
|
||||
/// <returns>
|
|
||||
/// An instance of <see cref="Bgra"/>.
|
|
||||
/// </returns>
|
|
||||
public static implicit operator Bgra(Hsv color) |
|
||||
{ |
|
||||
float s = color.S / 100; |
|
||||
float v = color.V / 100; |
|
||||
|
|
||||
if (Math.Abs(s) < Epsilon) |
|
||||
{ |
|
||||
byte component = (byte)(v * 255); |
|
||||
return new Bgra(component, component, component, 255); |
|
||||
} |
|
||||
|
|
||||
float h = (Math.Abs(color.H - 360) < Epsilon) ? 0 : color.H / 60; |
|
||||
int i = (int)Math.Truncate(h); |
|
||||
float f = h - i; |
|
||||
|
|
||||
float p = v * (1.0f - s); |
|
||||
float q = v * (1.0f - (s * f)); |
|
||||
float t = v * (1.0f - (s * (1.0f - f))); |
|
||||
|
|
||||
float r, g, b; |
|
||||
switch (i) |
|
||||
{ |
|
||||
case 0: |
|
||||
r = v; |
|
||||
g = t; |
|
||||
b = p; |
|
||||
break; |
|
||||
|
|
||||
case 1: |
|
||||
r = q; |
|
||||
g = v; |
|
||||
b = p; |
|
||||
break; |
|
||||
|
|
||||
case 2: |
|
||||
r = p; |
|
||||
g = v; |
|
||||
b = t; |
|
||||
break; |
|
||||
|
|
||||
case 3: |
|
||||
r = p; |
|
||||
g = q; |
|
||||
b = v; |
|
||||
break; |
|
||||
|
|
||||
case 4: |
|
||||
r = t; |
|
||||
g = p; |
|
||||
b = v; |
|
||||
break; |
|
||||
|
|
||||
default: |
|
||||
r = v; |
|
||||
g = p; |
|
||||
b = q; |
|
||||
break; |
|
||||
} |
|
||||
|
|
||||
return new Bgra((byte)Math.Round(b * 255), (byte)Math.Round(g * 255), (byte)Math.Round(r * 255)); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Allows the implicit conversion of an instance of <see cref="YCbCr"/> to a
|
|
||||
/// <see cref="Bgra"/>.
|
|
||||
/// </summary>
|
|
||||
/// <param name="color">
|
|
||||
/// The instance of <see cref="YCbCr"/> to convert.
|
|
||||
/// </param>
|
|
||||
/// <returns>
|
|
||||
/// An instance of <see cref="Bgra"/>.
|
|
||||
/// </returns>
|
|
||||
public static implicit operator Bgra(YCbCr color) |
|
||||
{ |
|
||||
float y = color.Y; |
|
||||
float cb = color.Cb - 128; |
|
||||
float cr = color.Cr - 128; |
|
||||
|
|
||||
byte b = (y + (1.772 * cb)).ToByte(); |
|
||||
byte g = (y - (0.34414 * cb) - (0.71414 * cr)).ToByte(); |
|
||||
byte r = (y + (1.402 * cr)).ToByte(); |
|
||||
|
|
||||
return new Bgra(b, g, r, 255); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Allows the implicit conversion of an instance of <see cref="Cmyk"/> to a
|
|
||||
/// <see cref="Bgra"/>.
|
|
||||
/// </summary>
|
|
||||
/// <param name="cmykColor">
|
|
||||
/// The instance of <see cref="Cmyk"/> to convert.
|
|
||||
/// </param>
|
|
||||
/// <returns>
|
|
||||
/// An instance of <see cref="Bgra"/>.
|
|
||||
/// </returns>
|
|
||||
public static implicit operator Bgra(Cmyk cmykColor) |
|
||||
{ |
|
||||
int red = Convert.ToInt32((1 - (cmykColor.C / 100)) * (1 - (cmykColor.K / 100)) * 255.0); |
|
||||
int green = Convert.ToInt32((1 - (cmykColor.M / 100)) * (1 - (cmykColor.K / 100)) * 255.0); |
|
||||
int blue = Convert.ToInt32((1 - (cmykColor.Y / 100)) * (1 - (cmykColor.K / 100)) * 255.0); |
|
||||
return new Bgra(blue.ToByte(), green.ToByte(), red.ToByte()); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Compares two <see cref="Bgra"/> objects. The result specifies whether the values
|
|
||||
/// of the <see cref="Bgra.B"/>, <see cref="Bgra.G"/>, <see cref="Bgra.R"/>, and <see cref="Bgra.A"/>
|
|
||||
/// properties of the two <see cref="Bgra"/> objects are equal.
|
|
||||
/// </summary>
|
|
||||
/// <param name="left">
|
|
||||
/// The <see cref="Bgra"/> on the left side of the operand.
|
|
||||
/// </param>
|
|
||||
/// <param name="right">
|
|
||||
/// The <see cref="Bgra"/> on the right side of the operand.
|
|
||||
/// </param>
|
|
||||
/// <returns>
|
|
||||
/// True if the current left is equal to the <paramref name="right"/> parameter; otherwise, false.
|
|
||||
/// </returns>
|
|
||||
public static bool operator ==(Bgra left, Bgra right) |
|
||||
{ |
|
||||
return left.Equals(right); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Compares two <see cref="Bgra"/> objects. The result specifies whether the values
|
|
||||
/// of the <see cref="Bgra.B"/>, <see cref="Bgra.G"/>, <see cref="Bgra.R"/>, and <see cref="Bgra.A"/>
|
|
||||
/// properties of the two <see cref="Bgra"/> objects are unequal.
|
|
||||
/// </summary>
|
|
||||
/// <param name="left">
|
|
||||
/// The <see cref="Bgra"/> on the left side of the operand.
|
|
||||
/// </param>
|
|
||||
/// <param name="right">
|
|
||||
/// The <see cref="Bgra"/> on the right side of the operand.
|
|
||||
/// </param>
|
|
||||
/// <returns>
|
|
||||
/// True if the current left is unequal to the <paramref name="right"/> parameter; otherwise, false.
|
|
||||
/// </returns>
|
|
||||
public static bool operator !=(Bgra left, Bgra right) |
|
||||
{ |
|
||||
return !left.Equals(right); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Indicates whether this instance and a specified object are equal.
|
|
||||
/// </summary>
|
|
||||
/// <returns>
|
|
||||
/// true if <paramref name="obj"/> and this instance are the same type and represent the same value; otherwise, false.
|
|
||||
/// </returns>
|
|
||||
/// <param name="obj">Another object to compare to. </param>
|
|
||||
public override bool Equals(object obj) |
|
||||
{ |
|
||||
if (obj is Bgra) |
|
||||
{ |
|
||||
Bgra color = (Bgra)obj; |
|
||||
|
|
||||
return this.BGRA == color.BGRA; |
|
||||
} |
|
||||
|
|
||||
return false; |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Returns the hash code for this instance.
|
|
||||
/// </summary>
|
|
||||
/// <returns>
|
|
||||
/// A 32-bit signed integer that is the hash code for this instance.
|
|
||||
/// </returns>
|
|
||||
public override int GetHashCode() |
|
||||
{ |
|
||||
unchecked |
|
||||
{ |
|
||||
int hashCode = this.B.GetHashCode(); |
|
||||
hashCode = (hashCode * 397) ^ this.G.GetHashCode(); |
|
||||
hashCode = (hashCode * 397) ^ this.R.GetHashCode(); |
|
||||
hashCode = (hashCode * 397) ^ this.A.GetHashCode(); |
|
||||
return hashCode; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Returns the fully qualified type name of this instance.
|
|
||||
/// </summary>
|
|
||||
/// <returns>
|
|
||||
/// A <see cref="T:System.String"/> containing a fully qualified type name.
|
|
||||
/// </returns>
|
|
||||
public override string ToString() |
|
||||
{ |
|
||||
if (this.IsEmpty) |
|
||||
{ |
|
||||
return "Color [ Empty ]"; |
|
||||
} |
|
||||
|
|
||||
return $"Color [ B={this.B}, G={this.G}, R={this.R}, A={this.A} ]"; |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Indicates whether the current object is equal to another object of the same type.
|
|
||||
/// </summary>
|
|
||||
/// <returns>
|
|
||||
/// True if the current object is equal to the <paramref name="other"/> parameter; otherwise, false.
|
|
||||
/// </returns>
|
|
||||
/// <param name="other">An object to compare with this object.</param>
|
|
||||
public bool Equals(Bgra other) |
|
||||
{ |
|
||||
return this.BGRA == other.BGRA; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -0,0 +1,541 @@ |
|||||
|
// <copyright file="Color.cs" company="James South">
|
||||
|
// Copyright (c) James South and contributors.
|
||||
|
// Licensed under the Apache License, Version 2.0.
|
||||
|
// </copyright>
|
||||
|
|
||||
|
namespace ImageProcessor |
||||
|
{ |
||||
|
using System; |
||||
|
using System.ComponentModel; |
||||
|
using System.Numerics; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents a four-component color using red, green, blue, and alpha data.
|
||||
|
/// </summary>
|
||||
|
/// <remarks>
|
||||
|
/// This struct is fully mutable. This is done (against the guidelines) for the sake of performance,
|
||||
|
/// as it avoids the need to create new values for modification operations.
|
||||
|
/// </remarks>
|
||||
|
public struct Color : IEquatable<Color> |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Represents a <see cref="Color"/> that has R, G, B, and A values set to zero.
|
||||
|
/// </summary>
|
||||
|
public static readonly Color Empty = default(Color); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// The epsilon for comparing floating point numbers.
|
||||
|
/// </summary>
|
||||
|
private const float Epsilon = 0.0001f; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// The backing vector for SIMD support.
|
||||
|
/// </summary>
|
||||
|
private Vector4 backingVector; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Initializes a new instance of the <see cref="Color"/> struct with the alpha component set to 1.
|
||||
|
/// </summary>
|
||||
|
/// <param name="r">The red component of this <see cref="Color"/>.</param>
|
||||
|
/// <param name="g">The green component of this <see cref="Color"/>.</param>
|
||||
|
/// <param name="b">The blue component of this <see cref="Color"/>.</param>
|
||||
|
public Color(float r, float g, float b) |
||||
|
: this(r, g, b, 1) |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Initializes a new instance of the <see cref="Color"/> struct.
|
||||
|
/// </summary>
|
||||
|
/// <param name="r">The red component of this <see cref="Color"/>.</param>
|
||||
|
/// <param name="g">The green component of this <see cref="Color"/>.</param>
|
||||
|
/// <param name="b">The blue component of this <see cref="Color"/>.</param>
|
||||
|
/// <param name="a">The alpha component of this <see cref="Color"/>.</param>
|
||||
|
public Color(float r, float g, float b, float a) |
||||
|
: this() |
||||
|
{ |
||||
|
this.backingVector.X = r; |
||||
|
this.backingVector.Y = g; |
||||
|
this.backingVector.Z = b; |
||||
|
this.backingVector.W = a; |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Initializes a new instance of the <see cref="Color"/> struct.
|
||||
|
/// </summary>
|
||||
|
/// <param name="hex">
|
||||
|
/// The hexadecimal representation of the combined color components arranged
|
||||
|
/// in rgb, rrggbb, or aarrggbb format to match web syntax.
|
||||
|
/// </param>
|
||||
|
public Color(string hex) |
||||
|
: this() |
||||
|
{ |
||||
|
// Hexadecimal representations are layed out AARRGGBB to we need to do some reordering.
|
||||
|
hex = hex.StartsWith("#") ? hex.Substring(1) : hex; |
||||
|
|
||||
|
if (hex.Length != 8 && hex.Length != 6 && hex.Length != 3) |
||||
|
{ |
||||
|
throw new ArgumentException("Hexadecimal string is not in the correct format.", nameof(hex)); |
||||
|
} |
||||
|
|
||||
|
if (hex.Length == 8) |
||||
|
{ |
||||
|
this.R = Convert.ToByte(hex.Substring(2, 2), 16) / 255f; |
||||
|
this.G = Convert.ToByte(hex.Substring(4, 2), 16) / 255f; |
||||
|
this.B = Convert.ToByte(hex.Substring(6, 2), 16) / 255f; |
||||
|
this.A = Convert.ToByte(hex.Substring(0, 2), 16) / 255f; |
||||
|
} |
||||
|
else if (hex.Length == 6) |
||||
|
{ |
||||
|
this.R = Convert.ToByte(hex.Substring(0, 2), 16) / 255f; |
||||
|
this.G = Convert.ToByte(hex.Substring(2, 2), 16) / 255f; |
||||
|
this.B = Convert.ToByte(hex.Substring(4, 2), 16) / 255f; |
||||
|
this.A = 1; |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
string r = char.ToString(hex[0]); |
||||
|
string g = char.ToString(hex[1]); |
||||
|
string b = char.ToString(hex[2]); |
||||
|
|
||||
|
this.B = Convert.ToByte(b + b, 16) / 255f; |
||||
|
this.G = Convert.ToByte(g + g, 16) / 255f; |
||||
|
this.R = Convert.ToByte(r + r, 16) / 255f; |
||||
|
this.A = 1; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Initializes a new instance of the <see cref="Color"/> struct.
|
||||
|
/// </summary>
|
||||
|
/// <param name="vector">
|
||||
|
/// The vector.
|
||||
|
/// </param>
|
||||
|
public Color(Vector4 vector) |
||||
|
{ |
||||
|
this.backingVector = vector; |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Initializes a new instance of the <see cref="Color"/> struct.
|
||||
|
/// </summary>
|
||||
|
/// <param name="vector">
|
||||
|
/// The vector representing the red, green, and blue componenets.
|
||||
|
/// </param>
|
||||
|
public Color(Vector3 vector) |
||||
|
{ |
||||
|
this.backingVector = new Vector4(vector.X, vector.Y, vector.Z, 1); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Initializes a new instance of the <see cref="Color"/> struct.
|
||||
|
/// </summary>
|
||||
|
/// <param name="vector">
|
||||
|
/// The vector representing the red, green, and blue componenets.
|
||||
|
/// </param>
|
||||
|
/// <param name="alpha">The alpha component.</param>
|
||||
|
public Color(Vector3 vector, float alpha) |
||||
|
{ |
||||
|
this.backingVector = new Vector4(vector.X, vector.Y, vector.Z, alpha); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets or sets the red component of the color.
|
||||
|
/// </summary>
|
||||
|
public float R |
||||
|
{ |
||||
|
get |
||||
|
{ |
||||
|
return this.backingVector.X; |
||||
|
} |
||||
|
|
||||
|
set |
||||
|
{ |
||||
|
this.backingVector.X = value; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets or sets the green component of the color.
|
||||
|
/// </summary>
|
||||
|
public float G |
||||
|
{ |
||||
|
get |
||||
|
{ |
||||
|
return this.backingVector.Y; |
||||
|
} |
||||
|
|
||||
|
set |
||||
|
{ |
||||
|
this.backingVector.Y = value; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets or sets the blue component of the color.
|
||||
|
/// </summary>
|
||||
|
public float B |
||||
|
{ |
||||
|
get |
||||
|
{ |
||||
|
return this.backingVector.Z; |
||||
|
} |
||||
|
|
||||
|
set |
||||
|
{ |
||||
|
this.backingVector.Z = value; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets or sets the alpha component of the color.
|
||||
|
/// </summary>
|
||||
|
public float A |
||||
|
{ |
||||
|
get |
||||
|
{ |
||||
|
return this.backingVector.W; |
||||
|
} |
||||
|
|
||||
|
set |
||||
|
{ |
||||
|
this.backingVector.W = value; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets a value indicating whether this <see cref="Color"/> is empty.
|
||||
|
/// </summary>
|
||||
|
[EditorBrowsable(EditorBrowsableState.Never)] |
||||
|
public bool IsEmpty => this.backingVector.Equals(default(Vector4)); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets this color with the component values clamped from 0 to 1.
|
||||
|
/// </summary>
|
||||
|
public Color Limited |
||||
|
{ |
||||
|
get |
||||
|
{ |
||||
|
float r = this.R.Clamp(0, 1); |
||||
|
float g = this.G.Clamp(0, 1); |
||||
|
float b = this.B.Clamp(0, 1); |
||||
|
float a = this.A.Clamp(0, 1); |
||||
|
return new Color(r, g, b, a); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Allows the implicit conversion of an instance of <see cref="Color"/> to a
|
||||
|
/// <see cref="Bgra32"/>.
|
||||
|
/// </summary>
|
||||
|
/// <param name="color">The instance of <see cref="Color"/> to convert.</param>
|
||||
|
/// <returns>
|
||||
|
/// An instance of <see cref="Bgra32"/>.
|
||||
|
/// </returns>
|
||||
|
public static implicit operator Color(Bgra32 color) |
||||
|
{ |
||||
|
return new Color(color.R / 255f, color.G / 255f, color.B / 255f, color.A / 255f); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Allows the implicit conversion of an instance of <see cref="Cmyk"/> to a
|
||||
|
/// <see cref="Color"/>.
|
||||
|
/// </summary>
|
||||
|
/// <param name="cmykColor">The instance of <see cref="Cmyk"/> to convert.</param>
|
||||
|
/// <returns>
|
||||
|
/// An instance of <see cref="Color"/>.
|
||||
|
/// </returns>
|
||||
|
public static implicit operator Color(Cmyk cmykColor) |
||||
|
{ |
||||
|
float r = (1 - cmykColor.C) * (1 - cmykColor.K); |
||||
|
float g = (1 - cmykColor.M) * (1 - cmykColor.K); |
||||
|
float b = (1 - cmykColor.Y) * (1 - cmykColor.K); |
||||
|
return new Color(r, g, b); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Allows the implicit conversion of an instance of <see cref="YCbCr"/> to a
|
||||
|
/// <see cref="Color"/>.
|
||||
|
/// </summary>
|
||||
|
/// <param name="color">The instance of <see cref="YCbCr"/> to convert.</param>
|
||||
|
/// <returns>
|
||||
|
/// An instance of <see cref="Color"/>.
|
||||
|
/// </returns>
|
||||
|
public static implicit operator Color(YCbCr color) |
||||
|
{ |
||||
|
float y = color.Y; |
||||
|
float cb = color.Cb - 128; |
||||
|
float cr = color.Cr - 128; |
||||
|
|
||||
|
float r = (float)(y + (1.402 * cr)) / 255f; |
||||
|
float g = (float)(y - (0.34414 * cb) - (0.71414 * cr)) / 255f; |
||||
|
float b = (float)(y + (1.772 * cb)) / 255f; |
||||
|
|
||||
|
return new Color(r, g, b); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Allows the implicit conversion of an instance of <see cref="Hsv"/> to a
|
||||
|
/// <see cref="Color"/>.
|
||||
|
/// </summary>
|
||||
|
/// <param name="color">The instance of <see cref="Hsv"/> to convert.</param>
|
||||
|
/// <returns>
|
||||
|
/// An instance of <see cref="Color"/>.
|
||||
|
/// </returns>
|
||||
|
public static implicit operator Color(Hsv color) |
||||
|
{ |
||||
|
float s = color.S; |
||||
|
float v = color.V; |
||||
|
|
||||
|
if (Math.Abs(s) < Epsilon) |
||||
|
{ |
||||
|
return new Color(v, v, v, 1); |
||||
|
} |
||||
|
|
||||
|
float h = (Math.Abs(color.H - 360) < Epsilon) ? 0 : color.H / 60; |
||||
|
int i = (int)Math.Truncate(h); |
||||
|
float f = h - i; |
||||
|
|
||||
|
float p = v * (1.0f - s); |
||||
|
float q = v * (1.0f - (s * f)); |
||||
|
float t = v * (1.0f - (s * (1.0f - f))); |
||||
|
|
||||
|
float r, g, b; |
||||
|
switch (i) |
||||
|
{ |
||||
|
case 0: |
||||
|
r = v; |
||||
|
g = t; |
||||
|
b = p; |
||||
|
break; |
||||
|
|
||||
|
case 1: |
||||
|
r = q; |
||||
|
g = v; |
||||
|
b = p; |
||||
|
break; |
||||
|
|
||||
|
case 2: |
||||
|
r = p; |
||||
|
g = v; |
||||
|
b = t; |
||||
|
break; |
||||
|
|
||||
|
case 3: |
||||
|
r = p; |
||||
|
g = q; |
||||
|
b = v; |
||||
|
break; |
||||
|
|
||||
|
case 4: |
||||
|
r = t; |
||||
|
g = p; |
||||
|
b = v; |
||||
|
break; |
||||
|
|
||||
|
default: |
||||
|
r = v; |
||||
|
g = p; |
||||
|
b = q; |
||||
|
break; |
||||
|
} |
||||
|
|
||||
|
return new Color(r, g, b); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Computes the product of multiplying a color by a given factor.
|
||||
|
/// </summary>
|
||||
|
/// <param name="color">The color.</param>
|
||||
|
/// <param name="factor">The multiplication factor.</param>
|
||||
|
/// <returns>
|
||||
|
/// The <see cref="Color"/>
|
||||
|
/// </returns>
|
||||
|
public static Color operator *(Color color, float factor) |
||||
|
{ |
||||
|
return new Color(color.backingVector * factor); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Computes the product of multiplying a color by a given factor.
|
||||
|
/// </summary>
|
||||
|
/// <param name="factor">The multiplication factor.</param>
|
||||
|
/// <param name="color">The color.</param>
|
||||
|
/// <returns>
|
||||
|
/// The <see cref="Color"/>
|
||||
|
/// </returns>
|
||||
|
public static Color operator *(float factor, Color color) |
||||
|
{ |
||||
|
return new Color(color.backingVector * factor); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Computes the product of multiplying two colors.
|
||||
|
/// </summary>
|
||||
|
/// <param name="left">The color on the left hand of the operand.</param>
|
||||
|
/// <param name="right">The color on the right hand of the operand.</param>
|
||||
|
/// <returns>
|
||||
|
/// The <see cref="Color"/>
|
||||
|
/// </returns>
|
||||
|
public static Color operator *(Color left, Color right) |
||||
|
{ |
||||
|
return new Color(left.backingVector * right.backingVector); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Computes the sum of adding two colors.
|
||||
|
/// </summary>
|
||||
|
/// <param name="left">The color on the left hand of the operand.</param>
|
||||
|
/// <param name="right">The color on the right hand of the operand.</param>
|
||||
|
/// <returns>
|
||||
|
/// The <see cref="Color"/>
|
||||
|
/// </returns>
|
||||
|
public static Color operator +(Color left, Color right) |
||||
|
{ |
||||
|
return new Color(left.R + right.R, left.G + right.G, left.B + right.B, left.A + right.A); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Computes the difference left by subtracting one color from another.
|
||||
|
/// </summary>
|
||||
|
/// <param name="left">The color on the left hand of the operand.</param>
|
||||
|
/// <param name="right">The color on the right hand of the operand.</param>
|
||||
|
/// <returns>
|
||||
|
/// The <see cref="Color"/>
|
||||
|
/// </returns>
|
||||
|
public static Color operator -(Color left, Color right) |
||||
|
{ |
||||
|
return new Color(left.R - right.R, left.G - right.G, left.B - right.B, left.A - right.A); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Compares two <see cref="Color"/> objects for equality.
|
||||
|
/// </summary>
|
||||
|
/// <param name="left">
|
||||
|
/// The <see cref="Color"/> on the left side of the operand.
|
||||
|
/// </param>
|
||||
|
/// <param name="right">
|
||||
|
/// The <see cref="Color"/> on the right side of the operand.
|
||||
|
/// </param>
|
||||
|
/// <returns>
|
||||
|
/// True if the current left is equal to the <paramref name="right"/> parameter; otherwise, false.
|
||||
|
/// </returns>
|
||||
|
public static bool operator ==(Color left, Color right) |
||||
|
{ |
||||
|
return left.Equals(right); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Compares two <see cref="Hsv"/> objects for inequality.
|
||||
|
/// </summary>
|
||||
|
/// <param name="left">
|
||||
|
/// The <see cref="Color"/> on the left side of the operand.
|
||||
|
/// </param>
|
||||
|
/// <param name="right">
|
||||
|
/// The <see cref="Color"/> on the right side of the operand.
|
||||
|
/// </param>
|
||||
|
/// <returns>
|
||||
|
/// True if the current left is unequal to the <paramref name="right"/> parameter; otherwise, false.
|
||||
|
/// </returns>
|
||||
|
public static bool operator !=(Color left, Color right) |
||||
|
{ |
||||
|
return !left.Equals(right); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Returns a new color whose components are the average of the components of first and second.
|
||||
|
/// </summary>
|
||||
|
/// <param name="first">The first color.</param>
|
||||
|
/// <param name="second">The second color.</param>
|
||||
|
/// <returns>
|
||||
|
/// The <see cref="Color"/>
|
||||
|
/// </returns>
|
||||
|
public static Color Average(Color first, Color second) |
||||
|
{ |
||||
|
return new Color((first.backingVector + second.backingVector) * .5f); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Linearly interpolates from one color to another based on the given amount.
|
||||
|
/// </summary>
|
||||
|
/// <param name="from">The first color value.</param>
|
||||
|
/// <param name="to">The second color value.</param>
|
||||
|
/// <param name="amount">
|
||||
|
/// The weight value. At amount = 0, "from" is returned, at amount = 1, "to" is returned.
|
||||
|
/// </param>
|
||||
|
/// <returns>
|
||||
|
/// The <see cref="Color"/>
|
||||
|
/// </returns>
|
||||
|
public static Color Lerp(Color from, Color to, float amount) |
||||
|
{ |
||||
|
amount = amount.Clamp(0f, 1f); |
||||
|
|
||||
|
return (from * (1 - amount)) + (to * amount); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets a <see cref="Vector4"/> representation for this <see cref="Color"/>.
|
||||
|
/// </summary>
|
||||
|
/// <returns>A <see cref="Vector4"/> representation for this object.</returns>
|
||||
|
public Vector4 ToVector4() |
||||
|
{ |
||||
|
return new Vector4(this.R, this.G, this.B, this.A); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets a <see cref="Vector3"/> representation for this <see cref="Color"/>.
|
||||
|
/// </summary>
|
||||
|
/// <returns>A <see cref="Vector3"/> representation for this object.</returns>
|
||||
|
public Vector3 ToVector3() |
||||
|
{ |
||||
|
return new Vector3(this.R, this.G, this.B); |
||||
|
} |
||||
|
|
||||
|
/// <inheritdoc/>
|
||||
|
public override bool Equals(object obj) |
||||
|
{ |
||||
|
if (obj is Color) |
||||
|
{ |
||||
|
Color color = (Color)obj; |
||||
|
|
||||
|
return this.backingVector == color.backingVector; |
||||
|
} |
||||
|
|
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
/// <inheritdoc/>
|
||||
|
public override int GetHashCode() |
||||
|
{ |
||||
|
return GetHashCode(this); |
||||
|
} |
||||
|
|
||||
|
/// <inheritdoc/>
|
||||
|
public override string ToString() |
||||
|
{ |
||||
|
if (this.IsEmpty) |
||||
|
{ |
||||
|
return "Color [ Empty ]"; |
||||
|
} |
||||
|
|
||||
|
return $"Color [ R={this.R:#0.##}, G={this.G:#0.##}, B={this.B:#0.##}, A={this.A:#0.##} ]"; |
||||
|
} |
||||
|
|
||||
|
/// <inheritdoc/>
|
||||
|
public bool Equals(Color other) |
||||
|
{ |
||||
|
return this.backingVector.Equals(other.backingVector); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Returns the hash code for this instance.
|
||||
|
/// </summary>
|
||||
|
/// <param name="color">
|
||||
|
/// The instance of <see cref="Color"/> to return the hash code for.
|
||||
|
/// </param>
|
||||
|
/// <returns>
|
||||
|
/// A 32-bit signed integer that is the hash code for this instance.
|
||||
|
/// </returns>
|
||||
|
private static int GetHashCode(Color color) => color.backingVector.GetHashCode(); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,204 @@ |
|||||
|
// <copyright file="Bgra32.cs" company="James South">
|
||||
|
// Copyright (c) James South and contributors.
|
||||
|
// Licensed under the Apache License, Version 2.0.
|
||||
|
// </copyright>
|
||||
|
|
||||
|
namespace ImageProcessor |
||||
|
{ |
||||
|
using System; |
||||
|
using System.ComponentModel; |
||||
|
using System.Numerics; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents an BGRA (blue, green, red, alpha) color.
|
||||
|
/// </summary>
|
||||
|
public struct Bgra32 : IEquatable<Bgra32> |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Represents a <see cref="Bgra32"/> that has B, G, R, and A values set to zero.
|
||||
|
/// </summary>
|
||||
|
public static readonly Bgra32 Empty = default(Bgra32); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// The backing vector for SIMD support.
|
||||
|
/// </summary>
|
||||
|
private Vector4 backingVector; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Initializes a new instance of the <see cref="Bgra32"/> struct.
|
||||
|
/// </summary>
|
||||
|
/// <param name="b">The blue component of this <see cref="Bgra32"/>.</param>
|
||||
|
/// <param name="g">The green component of this <see cref="Bgra32"/>.</param>
|
||||
|
/// <param name="r">The red component of this <see cref="Bgra32"/>.</param>
|
||||
|
public Bgra32(byte b, byte g, byte r) |
||||
|
: this(b, g, r, 255) |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Initializes a new instance of the <see cref="Bgra32"/> struct.
|
||||
|
/// </summary>
|
||||
|
/// <param name="b">The blue component of this <see cref="Bgra32"/>.</param>
|
||||
|
/// <param name="g">The green component of this <see cref="Bgra32"/>.</param>
|
||||
|
/// <param name="r">The red component of this <see cref="Bgra32"/>.</param>
|
||||
|
/// <param name="a">The alpha component of this <see cref="Bgra32"/>.</param>
|
||||
|
public Bgra32(byte b, byte g, byte r, byte a) |
||||
|
: this() |
||||
|
{ |
||||
|
this.backingVector.X = b.Clamp(0, 255); |
||||
|
this.backingVector.Y = g.Clamp(0, 255); |
||||
|
this.backingVector.Z = r.Clamp(0, 255); |
||||
|
this.backingVector.W = a.Clamp(0, 255); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets the blue component of the color
|
||||
|
/// </summary>
|
||||
|
public byte B => (byte)this.backingVector.X; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets the green component of the color
|
||||
|
/// </summary>
|
||||
|
public byte G => (byte)this.backingVector.Y; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets the red component of the color
|
||||
|
/// </summary>
|
||||
|
public byte R => (byte)this.backingVector.Z; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets the alpha component of the color
|
||||
|
/// </summary>
|
||||
|
public byte A => (byte)this.backingVector.W; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets the <see cref="Bgra32"/> integer representation of the color.
|
||||
|
/// </summary>
|
||||
|
public int Bgra => (this.R << 16) | (this.G << 8) | (this.B << 0) | (this.A << 24); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets a value indicating whether this <see cref="Bgra32"/> is empty.
|
||||
|
/// </summary>
|
||||
|
[EditorBrowsable(EditorBrowsableState.Never)] |
||||
|
public bool IsEmpty => this.backingVector.Equals(default(Vector4)); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Allows the implicit conversion of an instance of <see cref="Color"/> to a
|
||||
|
/// <see cref="Bgra32"/>.
|
||||
|
/// </summary>
|
||||
|
/// <param name="color">
|
||||
|
/// The instance of <see cref="Color"/> to convert.
|
||||
|
/// </param>
|
||||
|
/// <returns>
|
||||
|
/// An instance of <see cref="Bgra32"/>.
|
||||
|
/// </returns>
|
||||
|
public static implicit operator Bgra32(Color color) |
||||
|
{ |
||||
|
color = color.Limited; |
||||
|
return new Bgra32((255f * color.B).ToByte(), (255f * color.G).ToByte(), (255f * color.R).ToByte(), (255f * color.A).ToByte()); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Compares two <see cref="Bgra32"/> objects for equality.
|
||||
|
/// </summary>
|
||||
|
/// <param name="left">
|
||||
|
/// The <see cref="Bgra32"/> on the left side of the operand.
|
||||
|
/// </param>
|
||||
|
/// <param name="right">
|
||||
|
/// The <see cref="Bgra32"/> on the right side of the operand.
|
||||
|
/// </param>
|
||||
|
/// <returns>
|
||||
|
/// True if the current left is equal to the <paramref name="right"/> parameter; otherwise, false.
|
||||
|
/// </returns>
|
||||
|
public static bool operator ==(Bgra32 left, Bgra32 right) |
||||
|
{ |
||||
|
return left.Equals(right); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Compares two <see cref="Bgra32"/> objects for inequality.
|
||||
|
/// </summary>
|
||||
|
/// <param name="left">
|
||||
|
/// The <see cref="Bgra32"/> on the left side of the operand.
|
||||
|
/// </param>
|
||||
|
/// <param name="right">
|
||||
|
/// The <see cref="Bgra32"/> on the right side of the operand.
|
||||
|
/// </param>
|
||||
|
/// <returns>
|
||||
|
/// True if the current left is unequal to the <paramref name="right"/> parameter; otherwise, false.
|
||||
|
/// </returns>
|
||||
|
public static bool operator !=(Bgra32 left, Bgra32 right) |
||||
|
{ |
||||
|
return !left.Equals(right); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Indicates whether this instance and a specified object are equal.
|
||||
|
/// </summary>
|
||||
|
/// <returns>
|
||||
|
/// true if <paramref name="obj"/> and this instance are the same type and represent the same value; otherwise, false.
|
||||
|
/// </returns>
|
||||
|
/// <param name="obj">Another object to compare to. </param>
|
||||
|
public override bool Equals(object obj) |
||||
|
{ |
||||
|
if (obj is Bgra32) |
||||
|
{ |
||||
|
Bgra32 color = (Bgra32)obj; |
||||
|
|
||||
|
return this.backingVector == color.backingVector; |
||||
|
} |
||||
|
|
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Returns the hash code for this instance.
|
||||
|
/// </summary>
|
||||
|
/// <returns>
|
||||
|
/// A 32-bit signed integer that is the hash code for this instance.
|
||||
|
/// </returns>
|
||||
|
public override int GetHashCode() |
||||
|
{ |
||||
|
return GetHashCode(this); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Returns the fully qualified type name of this instance.
|
||||
|
/// </summary>
|
||||
|
/// <returns>
|
||||
|
/// A <see cref="T:System.String"/> containing a fully qualified type name.
|
||||
|
/// </returns>
|
||||
|
public override string ToString() |
||||
|
{ |
||||
|
if (this.IsEmpty) |
||||
|
{ |
||||
|
return "Color [ Empty ]"; |
||||
|
} |
||||
|
|
||||
|
return $"Color [ B={this.B}, G={this.G}, R={this.R}, A={this.A} ]"; |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Indicates whether the current object is equal to another object of the same type.
|
||||
|
/// </summary>
|
||||
|
/// <returns>
|
||||
|
/// True if the current object is equal to the <paramref name="other"/> parameter; otherwise, false.
|
||||
|
/// </returns>
|
||||
|
/// <param name="other">An object to compare with this object.</param>
|
||||
|
public bool Equals(Bgra32 other) |
||||
|
{ |
||||
|
return this.backingVector.Equals(other.backingVector); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Returns the hash code for this instance.
|
||||
|
/// </summary>
|
||||
|
/// <param name="color">
|
||||
|
/// The instance of <see cref="Cmyk"/> to return the hash code for.
|
||||
|
/// </param>
|
||||
|
/// <returns>
|
||||
|
/// A 32-bit signed integer that is the hash code for this instance.
|
||||
|
/// </returns>
|
||||
|
private static int GetHashCode(Bgra32 color) => color.backingVector.GetHashCode(); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,88 @@ |
|||||
|
// <copyright file="EnumerableExtensions.cs" company="James South">
|
||||
|
// Copyright (c) James South and contributors.
|
||||
|
// Licensed under the Apache License, Version 2.0.
|
||||
|
// </copyright>
|
||||
|
|
||||
|
namespace ImageProcessor |
||||
|
{ |
||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Encapsulates a series of time saving extension methods to the <see cref="T:System.Collections.IEnumerable"/> interface.
|
||||
|
/// </summary>
|
||||
|
public static class EnumerableExtensions |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Generates a sequence of integral numbers within a specified range.
|
||||
|
/// </summary>
|
||||
|
/// <param name="fromInclusive">
|
||||
|
/// The start index, inclusive.
|
||||
|
/// </param>
|
||||
|
/// <param name="toExclusive">
|
||||
|
/// The end index, exclusive.
|
||||
|
/// </param>
|
||||
|
/// <param name="step">
|
||||
|
/// The incremental step.
|
||||
|
/// </param>
|
||||
|
/// <returns>
|
||||
|
/// The <see cref="IEnumerable{Int32}"/> that contains a range of sequential integral numbers.
|
||||
|
/// </returns>
|
||||
|
public static IEnumerable<int> SteppedRange(int fromInclusive, int toExclusive, int step) |
||||
|
{ |
||||
|
// Borrowed from Enumerable.Range
|
||||
|
long num = (fromInclusive + toExclusive) - 1L; |
||||
|
if ((toExclusive < 0) || (num > 0x7fffffffL)) |
||||
|
{ |
||||
|
throw new ArgumentOutOfRangeException(nameof(toExclusive)); |
||||
|
} |
||||
|
|
||||
|
return RangeIterator(fromInclusive, i => i < toExclusive, step); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Generates a sequence of integral numbers within a specified range.
|
||||
|
/// </summary>
|
||||
|
/// <param name="fromInclusive">
|
||||
|
/// The start index, inclusive.
|
||||
|
/// </param>
|
||||
|
/// <param name="toDelegate">
|
||||
|
/// A method that has one parameter and returns a <see cref="bool"/> calculating the end index
|
||||
|
/// </param>
|
||||
|
/// <param name="step">
|
||||
|
/// The incremental step.
|
||||
|
/// </param>
|
||||
|
/// <returns>
|
||||
|
/// The <see cref="IEnumerable{Int32}"/> that contains a range of sequential integral numbers.
|
||||
|
/// </returns>
|
||||
|
public static IEnumerable<int> SteppedRange(int fromInclusive, Func<int, bool> toDelegate, int step) |
||||
|
{ |
||||
|
return RangeIterator(fromInclusive, toDelegate, step); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Generates a sequence of integral numbers within a specified range.
|
||||
|
/// </summary>
|
||||
|
/// <param name="fromInclusive">
|
||||
|
/// The start index, inclusive.
|
||||
|
/// </param>
|
||||
|
/// <param name="toDelegate">
|
||||
|
/// A method that has one parameter and returns a <see cref="bool"/> calculating the end index
|
||||
|
/// </param>
|
||||
|
/// <param name="step">
|
||||
|
/// The incremental step.
|
||||
|
/// </param>
|
||||
|
/// <returns>
|
||||
|
/// The <see cref="IEnumerable{Int32}"/> that contains a range of sequential integral numbers.
|
||||
|
/// </returns>
|
||||
|
private static IEnumerable<int> RangeIterator(int fromInclusive, Func<int, bool> toDelegate, int step) |
||||
|
{ |
||||
|
int i = fromInclusive; |
||||
|
while (toDelegate(i)) |
||||
|
{ |
||||
|
yield return i; |
||||
|
i += step; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -1,35 +0,0 @@ |
|||||
// <copyright file="Invert.cs" company="James South">
|
|
||||
// Copyright © James South and contributors.
|
|
||||
// Licensed under the Apache License, Version 2.0.
|
|
||||
// </copyright>
|
|
||||
|
|
||||
namespace ImageProcessor.Filters |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// Inverts the colors of the image.
|
|
||||
/// </summary>
|
|
||||
public class Invert : ColorMatrixFilter |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// The inversion matrix.
|
|
||||
/// TODO: With gamma adjustment enabled this leaves the image too bright.
|
|
||||
/// </summary>
|
|
||||
private static readonly ColorMatrix Matrix = new ColorMatrix( |
|
||||
new[] |
|
||||
{ |
|
||||
new float[] { -1, 0, 0, 0, 0 }, |
|
||||
new float[] { 0, -1, 0, 0, 0 }, |
|
||||
new float[] { 0, 0, -1, 0, 0 }, |
|
||||
new float[] { 0, 0, 0, 1, 0 }, |
|
||||
new float[] { 1, 1, 1, 0, 1 } |
|
||||
}); |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Initializes a new instance of the <see cref="Invert"/> class.
|
|
||||
/// </summary>
|
|
||||
public Invert() |
|
||||
: base(Matrix, false) |
|
||||
{ |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,22 +1,27 @@ |
|||||
namespace ImageProcessor.Samplers |
// <copyright file="IResampler.cs" company="James South">
|
||||
|
// Copyright (c) James South and contributors.
|
||||
|
// Licensed under the Apache License, Version 2.0.
|
||||
|
// </copyright>
|
||||
|
|
||||
|
namespace ImageProcessor.Samplers |
||||
{ |
{ |
||||
/// <summary>
|
/// <summary>
|
||||
/// Encasulates an interpolation algorithm for resampling images.
|
/// Encapsulates an interpolation algorithm for resampling images.
|
||||
/// </summary>
|
/// </summary>
|
||||
public interface IResampler |
public interface IResampler |
||||
{ |
{ |
||||
/// <summary>
|
/// <summary>
|
||||
/// Gets the radius in which to sample pixels.
|
/// Gets the radius in which to sample pixels.
|
||||
/// </summary>
|
/// </summary>
|
||||
double Radius { get; } |
float Radius { get; } |
||||
|
|
||||
/// <summary>
|
/// <summary>
|
||||
/// Gets the result of the interpolation algorithm.
|
/// Gets the result of the interpolation algorithm.
|
||||
/// </summary>
|
/// </summary>
|
||||
/// <param name="x">The value to process.</param>
|
/// <param name="x">The value to process.</param>
|
||||
/// <returns>
|
/// <returns>
|
||||
/// The <see cref="double"/>
|
/// The <see cref="float"/>
|
||||
/// </returns>
|
/// </returns>
|
||||
double GetValue(double x); |
float GetValue(float x); |
||||
} |
} |
||||
} |
} |
||||
|
|||||
@ -0,0 +1,13 @@ |
|||||
|
{ |
||||
|
"$schema": "https://raw.githubusercontent.com/DotNetAnalyzers/StyleCopAnalyzers/master/StyleCop.Analyzers/StyleCop.Analyzers/Settings/stylecop.schema.json", |
||||
|
"settings": { |
||||
|
"documentationRules": { |
||||
|
"companyName": "James South", |
||||
|
"copyrightText": "Copyright (c) {companyName} and contributors.\nLicensed under the {licenseName}.", |
||||
|
"variables": { |
||||
|
"licenseName": "Apache License, Version 2.0" |
||||
|
}, |
||||
|
"documentPrivateFields": true |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -1 +0,0 @@ |
|||||
a0cc93222effb5feec0d1a1dc45efd0c5af77450 |
|
||||
@ -0,0 +1 @@ |
|||||
|
e37d569208ff9490b77b4131330feb323e367fd3 |
||||
Loading…
Reference in new issue