RgbColor.cs 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. using System;
  2. using System.Drawing;
  3. namespace PaintDotNet
  4. {
  5. /// <summary>
  6. /// Adapted from:
  7. /// "A Primer on Building a Color Picker User Control with GDI+ in Visual Basic .NET or C#"
  8. /// http://www.msdnaa.net/Resources/display.aspx?ResID=2460
  9. ///
  10. /// This class is only used by the ColorsForm and ColorWheel. Nothing else in this program
  11. /// should be using it!
  12. /// </summary>
  13. [Serializable]
  14. public struct RgbColor
  15. {
  16. // All values are between 0 and 255.
  17. public int Red;
  18. public int Green;
  19. public int Blue;
  20. public RgbColor(int R, int G, int B)
  21. {
  22. #if DEBUG
  23. if (R < 0 || R > 255)
  24. {
  25. throw new ArgumentOutOfRangeException("R", R, "R must corrospond to a byte value");
  26. }
  27. if (G < 0 || G > 255)
  28. {
  29. throw new ArgumentOutOfRangeException("G", G, "G must corrospond to a byte value");
  30. }
  31. if (B < 0 || B > 255)
  32. {
  33. throw new ArgumentOutOfRangeException("B", B, "B must corrospond to a byte value");
  34. }
  35. #endif
  36. Red = R;
  37. Green = G;
  38. Blue = B;
  39. }
  40. public static RgbColor FromHsv(HsvColor hsv)
  41. {
  42. return hsv.ToRgb();
  43. }
  44. public Color ToColor()
  45. {
  46. return Color.FromArgb(Red, Green, Blue);
  47. }
  48. public HsvColor ToHsv()
  49. {
  50. // In this function, R, G, and B values must be scaled
  51. // to be between 0 and 1.
  52. // HsvColor.Hue will be a value between 0 and 360, and
  53. // HsvColor.Saturation and value are between 0 and 1.
  54. double min;
  55. double max;
  56. double delta;
  57. double r = (double)Red / 255;
  58. double g = (double)Green / 255;
  59. double b = (double)Blue / 255;
  60. double h;
  61. double s;
  62. double v;
  63. min = Math.Min(Math.Min(r, g), b);
  64. max = Math.Max(Math.Max(r, g), b);
  65. v = max;
  66. delta = max - min;
  67. if (max == 0 || delta == 0)
  68. {
  69. // R, G, and B must be 0, or all the same.
  70. // In this case, S is 0, and H is undefined.
  71. // Using H = 0 is as good as any...
  72. s = 0;
  73. h = 0;
  74. }
  75. else
  76. {
  77. s = delta / max;
  78. if (r == max)
  79. {
  80. // Between Yellow and Magenta
  81. h = (g - b) / delta;
  82. }
  83. else if (g == max)
  84. {
  85. // Between Cyan and Yellow
  86. h = 2 + (b - r) / delta;
  87. }
  88. else
  89. {
  90. // Between Magenta and Cyan
  91. h = 4 + (r - g) / delta;
  92. }
  93. }
  94. // Scale h to be between 0 and 360.
  95. // This may require adding 360, if the value
  96. // is negative.
  97. h *= 60;
  98. if (h < 0)
  99. {
  100. h += 360;
  101. }
  102. // Scale to the requirements of this
  103. // application. All values are between 0 and 255.
  104. return new HsvColor((int)h, (int)(s * 100), (int)(v * 100));
  105. }
  106. public override string ToString()
  107. {
  108. return String.Format("({0}, {1}, {2})", Red, Green, Blue);
  109. }
  110. }
  111. }