ColorHelper.cs 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Drawing;
  4. using System.Text;
  5. namespace TEAMModelOS.Test.PPTX.ColorLibrary
  6. {
  7. /// <summary>
  8. /// 类 名:ColorHelper
  9. /// 功 能:提供从RGB到HSV/HSL色彩空间的相互转换
  10. /// </summary>
  11. public static class ColorHelper
  12. {
  13. /// <summary>
  14. /// RGB转换HSV
  15. /// </summary>
  16. /// <param name="rgb"></param>
  17. /// <returns></returns>
  18. public static ColorHSV RgbToHsv(ColorRGB rgb)
  19. {
  20. float min, max, tmp, H, S, V;
  21. float R = rgb.R * 1.0f / 255, G = rgb.G * 1.0f / 255, B = rgb.B * 1.0f / 255;
  22. tmp = Math.Min(R, G);
  23. min = Math.Min(tmp, B);
  24. tmp = Math.Max(R, G);
  25. max = Math.Max(tmp, B);
  26. // H
  27. H = 0;
  28. if (max == min)
  29. {
  30. H = 0;
  31. }
  32. else if (max == R && G > B)
  33. {
  34. H = 60 * (G - B) * 1.0f / (max - min) + 0;
  35. }
  36. else if (max == R && G < B)
  37. {
  38. H = 60 * (G - B) * 1.0f / (max - min) + 360;
  39. }
  40. else if (max == G)
  41. {
  42. H = H = 60 * (B - R) * 1.0f / (max - min) + 120;
  43. }
  44. else if (max == B)
  45. {
  46. H = H = 60 * (R - G) * 1.0f / (max - min) + 240;
  47. }
  48. // S
  49. if (max == 0)
  50. {
  51. S = 0;
  52. }
  53. else
  54. {
  55. S = (max - min) * 1.0f / max;
  56. }
  57. // V
  58. V = max;
  59. return new ColorHSV((int)H, (int)(S * 255), (int)(V * 255));
  60. }
  61. /// <summary>
  62. /// HSV转换RGB
  63. /// </summary>
  64. /// <param name="hsv"></param>
  65. /// <returns></returns>
  66. public static ColorRGB HsvToRgb(ColorHSV hsv)
  67. {
  68. if (hsv.H == 360) hsv.H = 359; // 360为全黑,原因不明
  69. float R = 0f, G = 0f, B = 0f;
  70. if (hsv.S == 0)
  71. {
  72. return new ColorRGB(hsv.V, hsv.V, hsv.V);
  73. }
  74. float S = hsv.S * 1.0f / 255, V = hsv.V * 1.0f / 255;
  75. int H1 = (int)(hsv.H * 1.0f / 60), H = hsv.H;
  76. float F = H * 1.0f / 60 - H1;
  77. float P = V * (1.0f - S);
  78. float Q = V * (1.0f - F * S);
  79. float T = V * (1.0f - (1.0f - F) * S);
  80. switch (H1)
  81. {
  82. case 0: R = V; G = T; B = P; break;
  83. case 1: R = Q; G = V; B = P; break;
  84. case 2: R = P; G = V; B = T; break;
  85. case 3: R = P; G = Q; B = V; break;
  86. case 4: R = T; G = P; B = V; break;
  87. case 5: R = V; G = P; B = Q; break;
  88. }
  89. R = R * 255;
  90. G = G * 255;
  91. B = B * 255;
  92. while (R > 255) R -= 255;
  93. while (R < 0) R += 255;
  94. while (G > 255) G -= 255;
  95. while (G < 0) G += 255;
  96. while (B > 255) B -= 255;
  97. while (B < 0) B += 255;
  98. return new ColorRGB((int)R, (int)G, (int)B);
  99. }
  100. /// <summary>
  101. /// RGB转换HSL
  102. /// </summary>
  103. /// <param name="rgb"></param>
  104. /// <returns></returns>
  105. public static ColorHSL RgbToHsl(ColorRGB rgb)
  106. {
  107. float min, max, tmp, H, S, L;
  108. float R = rgb.R * 1.0f / 255, G = rgb.G * 1.0f / 255, B = rgb.B * 1.0f / 255;
  109. tmp = Math.Min(R, G);
  110. min = Math.Min(tmp, B);
  111. tmp = Math.Max(R, G);
  112. max = Math.Max(tmp, B);
  113. // H
  114. H = 0;
  115. if (max == min)
  116. {
  117. H = 0; // 此时H应为未定义,通常写为0
  118. }
  119. else if (max == R && G > B)
  120. {
  121. H = 60 * (G - B) * 1.0f / (max - min) + 0;
  122. }
  123. else if (max == R && G < B)
  124. {
  125. H = 60 * (G - B) * 1.0f / (max - min) + 360;
  126. }
  127. else if (max == G)
  128. {
  129. H = H = 60 * (B - R) * 1.0f / (max - min) + 120;
  130. }
  131. else if (max == B)
  132. {
  133. H = H = 60 * (R - G) * 1.0f / (max - min) + 240;
  134. }
  135. // L
  136. L = 0.5f * (max + min);
  137. // S
  138. S = 0;
  139. if (L == 0 || max == min)
  140. {
  141. S = 0;
  142. }
  143. else if (0 < L && L < 0.5)
  144. {
  145. S = (max - min) / (L * 2);
  146. }
  147. else if (L > 0.5)
  148. {
  149. S = (max - min) / (2 - 2 * L);
  150. }
  151. return new ColorHSL((int)H, (int)(S * 255), (int)(L * 255));
  152. }
  153. /// <summary>
  154. /// HSL转换RGB
  155. /// </summary>
  156. /// <param name="hsl"></param>
  157. /// <returns></returns>
  158. public static ColorRGB HslToRgb(ColorHSL hsl)
  159. {
  160. float R = 0f, G = 0f, B = 0f;
  161. float S = hsl.S * 1.0f / 255, L = hsl.L * 1.0f / 255;
  162. float temp1, temp2, temp3;
  163. if (S == 0f) // 灰色
  164. {
  165. R = L;
  166. G = L;
  167. B = L;
  168. }
  169. else
  170. {
  171. if (L < 0.5f)
  172. {
  173. temp2 = L * (1.0f + S);
  174. }
  175. else
  176. {
  177. temp2 = L + S - L * S;
  178. }
  179. temp1 = 2.0f * L - temp2;
  180. float H = hsl.H * 1.0f / 360;
  181. // R
  182. temp3 = H + 1.0f / 3.0f;
  183. if (temp3 < 0) temp3 += 1.0f;
  184. if (temp3 > 1) temp3 -= 1.0f;
  185. R = temp3;
  186. // G
  187. temp3 = H;
  188. if (temp3 < 0) temp3 += 1.0f;
  189. if (temp3 > 1) temp3 -= 1.0f;
  190. G = temp3;
  191. // B
  192. temp3 = H - 1.0f / 3.0f;
  193. if (temp3 < 0) temp3 += 1.0f;
  194. if (temp3 > 1) temp3 -= 1.0f;
  195. B = temp3;
  196. }
  197. R = R * 255;
  198. G = G * 255;
  199. B = B * 255;
  200. return new ColorRGB((int)R, (int)G, (int)B);
  201. }
  202. private static float HueToRGB(float p, float q, float h)
  203. {
  204. if (h < 0) h += 1;
  205. if (h > 1) h -= 1;
  206. if (6 * h < 1)
  207. {
  208. return p + ((q - p) * 6 * h);
  209. }
  210. if (2 * h < 1)
  211. {
  212. return q;
  213. }
  214. if (3 * h < 2)
  215. {
  216. return p + ((q - p) * 6 * ((2.0f / 3.0f) - h));
  217. }
  218. return p;
  219. }
  220. private static Color getColorLumModandOff(Color color, int lumMod=0, int lumOff=0)
  221. {
  222. float[] rgb = { color.R, color.G, color.B };
  223. float r = rgb[0];
  224. float g = rgb[1];
  225. float b = rgb[2];
  226. float min = Math.Min(r, Math.Min(g, b));
  227. float max = Math.Max(r, Math.Max(g, b));
  228. float h = 0;
  229. if (max == min) h = 0;
  230. else if (max == r) h = ((60 * (g - b) / (max - min)) + 360) % 360;
  231. else if (max == g) h = (60 * (b - r) / (max - min)) + 120;
  232. else if (max == b) h = (60 * (r - g) / (max - min)) + 240;
  233. float l = (max + min) / 2;
  234. l = l * (float)lumMod / 100000f + (float)lumOff / 100000f;
  235. float s = 0;
  236. if (max == min) s = 0;
  237. else if (l <= .5f) s = (max - min) / (max + min);
  238. else s = (max - min) / (2 - max - min);
  239. h = h % 360.0f;
  240. h /= 360f;
  241. float q = 0;
  242. if (l < 0.5) q = l * (1 + s);
  243. else q = (l + s) - (s * l);
  244. float p = 2 * l - q;
  245. r = Math.Max(0, HueToRGB(p, q, h + (1.0f / 3.0f)));
  246. g = Math.Max(0, HueToRGB(p, q, h));
  247. b = Math.Max(0, HueToRGB(p, q, h - (1.0f / 3.0f)));
  248. //r = Math.Min(r, 1.0f);
  249. //g = Math.Min(g, 1.0f);
  250. //b = Math.Min(b, 1.0f);
  251. return Color.FromArgb((int)r, (int)g, (int)b);
  252. }
  253. }
  254. }