123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187 |
- using System;
- using System.Collections.Generic;
- using System.Drawing;
- using System.Linq;
- using System.Text;
- using System.Threading.Tasks;
- namespace SmartCoalApplication.Core
- {
- /// <summary>
- /// Adapted from:
- /// "A Primer on Building a Color Picker User Control with GDI+ in Visual Basic .NET or C#"
- /// http://www.msdnaa.net/Resources/display.aspx?ResID=2460
- /// </summary>
- public struct HsvColor
- {
- public int Hue; // 0-360
- public int Saturation; // 0-100
- public int Value; // 0-100
- public static bool operator ==(HsvColor lhs, HsvColor rhs)
- {
- if ((lhs.Hue == rhs.Hue) &&
- (lhs.Saturation == rhs.Saturation) &&
- (lhs.Value == rhs.Value))
- {
- return true;
- }
- else
- {
- return false;
- }
- }
- public static bool operator !=(HsvColor lhs, HsvColor rhs)
- {
- return !(lhs == rhs);
- }
- public override bool Equals(object obj)
- {
- return this == (HsvColor)obj;
- }
- public override int GetHashCode()
- {
- return (Hue + (Saturation << 8) + (Value << 16)).GetHashCode(); ;
- }
- public HsvColor(int hue, int saturation, int value)
- {
- if (hue < 0 || hue > 360)
- {
- throw new ArgumentOutOfRangeException("hue", "must be in the range [0, 360]");
- }
- if (saturation < 0 || saturation > 100)
- {
- throw new ArgumentOutOfRangeException("saturation", "must be in the range [0, 100]");
- }
- if (value < 0 || value > 100)
- {
- throw new ArgumentOutOfRangeException("value", "must be in the range [0, 100]");
- }
- Hue = hue;
- Saturation = saturation;
- Value = value;
- }
- public static HsvColor FromColor(Color color)
- {
- RgbColor rgb = new RgbColor(color.R, color.G, color.B);
- return rgb.ToHsv();
- }
- public Color ToColor()
- {
- RgbColor rgb = ToRgb();
- return Color.FromArgb(rgb.Red, rgb.Green, rgb.Blue);
- }
- public RgbColor ToRgb()
- {
- // HsvColor contains values scaled as in the color wheel:
- double h;
- double s;
- double v;
- double r = 0;
- double g = 0;
- double b = 0;
- // Scale Hue to be between 0 and 360. Saturation
- // and value scale to be between 0 and 1.
- h = (double)Hue % 360;
- s = (double)Saturation / 100;
- v = (double)Value / 100;
- if (s == 0)
- {
- // If s is 0, all colors are the same.
- // This is some flavor of gray.
- r = v;
- g = v;
- b = v;
- }
- else
- {
- double p;
- double q;
- double t;
- double fractionalSector;
- int sectorNumber;
- double sectorPos;
- // The color wheel consists of 6 sectors.
- // Figure out which sector you're in.
- sectorPos = h / 60;
- sectorNumber = (int)(Math.Floor(sectorPos));
- // get the fractional part of the sector.
- // That is, how many degrees into the sector
- // are you?
- fractionalSector = sectorPos - sectorNumber;
- // Calculate values for the three axes
- // of the color.
- p = v * (1 - s);
- q = v * (1 - (s * fractionalSector));
- t = v * (1 - (s * (1 - fractionalSector)));
- // Assign the fractional colors to r, g, and b
- // based on the sector the angle is in.
- switch (sectorNumber)
- {
- 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;
- case 5:
- r = v;
- g = p;
- b = q;
- break;
- }
- }
- // return an RgbColor structure, with values scaled
- // to be between 0 and 255.
- return new RgbColor((int)(r * 255), (int)(g * 255), (int)(b * 255));
- }
- public override string ToString()
- {
- return String.Format("({0}, {1}, {2})", Hue, Saturation, Value);
- }
- }
- }
|