ColorHelper.cs 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. using PixiEditor.DrawingApi.Core.ColorsImpl;
  2. namespace PixiEditor.ChangeableDocument;
  3. public static class ColorHelper
  4. {
  5. /// <summary>
  6. /// Creates color with corrected brightness.
  7. /// </summary>
  8. /// <param name="color">Color to correct.</param>
  9. /// <param name="correctionFactor">
  10. /// The brightness correction factor. Must be between -1 and 1.
  11. /// Negative values produce darker colors.
  12. /// </param>
  13. /// <returns>
  14. /// Corrected <see cref="Color" /> structure.
  15. /// </returns>
  16. public static Color ChangeColorBrightness(Color color, float correctionFactor)
  17. {
  18. Tuple<int, float, float> hsl = RgbToHsl(color.R, color.G, color.B);
  19. int h = hsl.Item1;
  20. float s = hsl.Item2;
  21. float l = hsl.Item3;
  22. l = Math.Clamp(l + correctionFactor, 0, 100);
  23. Color rgb = HslToRgb(h, s, l);
  24. return new Color(rgb.R, rgb.G, rgb.B, color.A);
  25. }
  26. /// <summary>
  27. /// Converts RGB to HSL.
  28. /// </summary>
  29. /// <param name="r">Red value.</param>
  30. /// <param name="g">Green value.</param>
  31. /// <param name="b">Blue value.</param>
  32. /// <returns>Tuple with 3 values in order: h, s, l0.</returns>
  33. public static Tuple<int, float, float> RgbToHsl(int r, int g, int b)
  34. {
  35. int h;
  36. float s, l;
  37. float dR = r / 255.0f;
  38. float dG = g / 255.0f;
  39. float dB = b / 255.0f;
  40. float min = Math.Min(Math.Min(dR, dG), dB);
  41. float max = Math.Max(Math.Max(dR, dG), dB);
  42. float delta = max - min;
  43. l = (max + min) / 2;
  44. if (delta == 0)
  45. {
  46. h = 0;
  47. s = 0.0f;
  48. }
  49. else
  50. {
  51. s = l <= 0.5 ? delta / (max + min) : delta / (2 - max - min);
  52. float hue;
  53. if (dR == max)
  54. {
  55. hue = (dG - dB) / 6 / delta;
  56. }
  57. else if (dG == max)
  58. {
  59. hue = (1.0f / 3) + ((dB - dR) / 6 / delta);
  60. }
  61. else
  62. {
  63. hue = (2.0f / 3) + ((dR - dG) / 6 / delta);
  64. }
  65. if (hue < 0)
  66. {
  67. hue += 1;
  68. }
  69. if (hue > 1)
  70. {
  71. hue -= 1;
  72. }
  73. h = (int)(hue * 360);
  74. }
  75. return new Tuple<int, float, float>(h, s * 100, l * 100);
  76. }
  77. /// <summary>
  78. /// Converts HSL color format to RGB.
  79. /// </summary>
  80. /// <returns>RGB Color.</returns>
  81. public static Color HslToRgb(int h, float s, float l)
  82. {
  83. s /= 100;
  84. l /= 100;
  85. byte r = 0;
  86. byte g = 0;
  87. byte b = 0;
  88. if (s == 0)
  89. {
  90. r = g = b = (byte)(l * 255);
  91. }
  92. else
  93. {
  94. float v1, v2;
  95. float hue = (float)h / 360;
  96. v2 = l < 0.5 ? l * (1 + s) : l + s - (l * s);
  97. v1 = (2 * l) - v2;
  98. r = (byte)(255 * HueToRgb(v1, v2, hue + (1.0f / 3)));
  99. g = (byte)(255 * HueToRgb(v1, v2, hue));
  100. b = (byte)(255 * HueToRgb(v1, v2, hue - (1.0f / 3)));
  101. }
  102. return new Color(r, g, b);
  103. }
  104. private static float HueToRgb(float v1, float v2, float hue)
  105. {
  106. if (hue < 0)
  107. {
  108. hue += 1;
  109. }
  110. if (hue > 1)
  111. {
  112. hue -= 1;
  113. }
  114. if (6 * hue < 1)
  115. {
  116. return v1 + ((v2 - v1) * 6 * hue);
  117. }
  118. if (2 * hue < 1)
  119. {
  120. return v2;
  121. }
  122. if (3 * hue < 2)
  123. {
  124. return v1 + ((v2 - v1) * ((2.0f / 3) - hue) * 6);
  125. }
  126. return v1;
  127. }
  128. }