123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325 |
- using System;
- using System.Drawing;
- using System.Text;
- namespace Optimizer
- {
- public static class ColorHelper
- {
- public static void HSVFromRGB(Color color, out double hue, out double saturation, out double value)
- {
- double min, max, delta, r, g, b;
- r = (double)color.R / 255d;
- g = (double)color.G / 255d;
- b = (double)color.B / 255d;
- min = Math.Min(r, Math.Min(g, b));
- max = Math.Max(r, Math.Max(g, b));
- value = max;
- delta = max - min;
- if (max != 0)
- saturation = delta / max;
- else
- {
- saturation = 0;
- hue = -1;
- return;
- }
- if (r == max)
- hue = (g - b) / delta;
- else if (g == max)
- hue = 2 + (b - r) / delta;
- else
- hue = 4 + (r - g) / delta;
- hue *= 60;
- if (hue < 0)
- hue += 360;
- }
- public static Color ColorFromHSV(double hue, double saturation, double value)
- {
- try
- {
- int i;
- double f, p, q, t, r, g, b;
- if (saturation == 0)
- {
- r = g = b = value;
- return Color.FromArgb((int)(255 * r), (int)(255 * g), (int)(255 * b));
- }
- hue /= 60;
- i = (int)Math.Floor(hue);
- f = hue - i;
- p = value * (1 - saturation);
- q = value * (1 - saturation * f);
- t = value * (1 - saturation * (1 - f));
- switch (i)
- {
- case 0:
- r = value;
- g = t;
- b = p;
- break;
- case 1:
- r = q;
- g = value;
- b = p;
- break;
- case 2:
- r = p;
- g = value;
- b = t;
- break;
- case 3:
- r = p;
- g = q;
- b = value;
- break;
- case 4:
- r = t;
- g = p;
- b = value;
- break;
- default:
- r = value;
- g = p;
- b = q;
- break;
- }
- return Color.FromArgb((int)(255 * r), (int)(255 * g), (int)(255 * b));
- }
- catch
- {
- }
- return Color.Empty;
- }
- public static Color ChangeColorBrightness(Color color, double darkenAmount)
- {
- HslColor hslColor = new HslColor(color);
- hslColor.L *= darkenAmount;
- return hslColor;
- }
- }
- [Serializable]
- public struct HslColor
- {
- #region Constants
- public static readonly HslColor Empty;
- #endregion
- #region Fields
- private double hue;
- private double saturation;
- private double luminance;
- private int alpha;
- private bool isEmpty;
- #endregion
- #region Static Constructors
- static HslColor()
- {
- Empty = new HslColor
- {
- IsEmpty = true
- };
- }
- #endregion
- #region Public Constructors
- public HslColor(double h, double s, double l)
- : this(255, h, s, l) { }
- public HslColor(int a, double h, double s, double l)
- {
- this.alpha = a;
- this.hue = Math.Min(359, h);
- this.saturation = Math.Min(1, s);
- this.luminance = Math.Min(1, l);
- isEmpty = false;
- }
- public HslColor(Color color)
- {
- this.alpha = color.A;
- this.hue = color.GetHue();
- this.saturation = color.GetSaturation();
- this.luminance = color.GetBrightness();
- isEmpty = false;
- }
- #endregion
- #region Operators
- public static bool operator ==(HslColor left, HslColor right)
- {
- return (((left.A == right.A) && (left.H == right.H)) && ((left.S == right.S) && (left.L == right.L)));
- }
- public static bool operator !=(HslColor left, HslColor right)
- {
- return !(left == right);
- }
- public static implicit operator HslColor(Color color)
- {
- return new HslColor(color);
- }
- public static implicit operator Color(HslColor color)
- {
- return color.ToRgbColor();
- }
- #endregion
- #region Overridden Methods
- public override bool Equals(object obj)
- {
- if (obj is HslColor color)
- {
- if (((this.A == color.A) && (this.H == color.H)) && ((this.S == color.S) && (this.L == color.L)))
- {
- return true;
- }
- }
- return false;
- }
- public override int GetHashCode()
- {
- return (((this.alpha.GetHashCode() ^ this.hue.GetHashCode()) ^ this.saturation.GetHashCode()) ^ this.luminance.GetHashCode());
- }
- public override string ToString()
- {
- StringBuilder builder;
- builder = new StringBuilder();
- builder.Append(this.GetType().Name);
- builder.Append(" [");
- builder.Append("H=");
- builder.Append(this.H);
- builder.Append(", S=");
- builder.Append(this.S);
- builder.Append(", L=");
- builder.Append(this.L);
- builder.Append("]");
- return builder.ToString();
- }
- #endregion
- #region Public Members
- public double H
- {
- get { return this.hue; }
- set
- {
- this.hue = value;
- this.hue = (this.hue > 359.0) ? 0 : ((this.hue < 0.0) ? 359 : this.hue);
- }
- }
- public double S
- {
- get { return this.saturation; }
- set { this.saturation = Math.Min(1, Math.Max(0, value)); }
- }
- public double L
- {
- get { return this.luminance; }
- set { this.luminance = Math.Min(1, Math.Max(0, value)); }
- }
- public int A
- {
- get { return this.alpha; }
- set { this.alpha = Math.Min(0, Math.Max(255, value)); }
- }
- public bool IsEmpty
- {
- get { return isEmpty; }
- internal set { isEmpty = value; }
- }
- public Color ToRgbColor()
- {
- return this.ToRgbColor(this.A);
- }
- public Color ToRgbColor(int alpha)
- {
- double q;
- if (this.L < 0.5)
- {
- q = this.L * (1 + this.S);
- }
- else
- {
- q = this.L + this.S - (this.L * this.S);
- }
- double p = 2 * this.L - q;
- double hk = this.H / 360;
- // r,g,b colors
- double[] tc = new[]
- {
- hk + (1d / 3d), hk, hk - (1d / 3d)
- };
- double[] colors = new[]
- {
- 0.0, 0.0, 0.0
- };
- for (int color = 0; color < colors.Length; color++)
- {
- if (tc[color] < 0)
- {
- tc[color] += 1;
- }
- if (tc[color] > 1)
- {
- tc[color] -= 1;
- }
- if (tc[color] < (1d / 6d))
- {
- colors[color] = p + ((q - p) * 6 * tc[color]);
- }
- else if (tc[color] >= (1d / 6d) && tc[color] < (1d / 2d))
- {
- colors[color] = q;
- }
- else if (tc[color] >= (1d / 2d) && tc[color] < (2d / 3d))
- {
- colors[color] = p + ((q - p) * 6 * (2d / 3d - tc[color]));
- }
- else
- {
- colors[color] = p;
- }
- colors[color] *= 255;
- }
- return Color.FromArgb(alpha, (int)colors[0], (int)colors[1], (int)colors[2]);
- }
- #endregion
- }
- }
|