ColorUtil.cs
上传用户:nnpulika
上传日期:2013-02-15
资源大小:597k
文件大小:15k
源码类别:

状态条

开发平台:

C#

  1. using System;
  2. using System.Drawing;
  3. using UtilityLibrary.Win32;
  4. namespace UtilityLibrary.General
  5. {
  6. /// <summary>
  7. /// Summary description for ColorConvert.
  8. /// </summary>
  9. public class ColorUtil
  10. {
  11. #region Class Variables
  12. static Color backgroundColor = Color.Empty;
  13. static Color selectionColor = Color.Empty;
  14. static Color controlColor = Color.Empty;
  15. static Color pressedColor = Color.Empty;
  16. static Color checkedColor = Color.Empty;
  17. static Color borderColor = Color.Empty;
  18. static bool useCustomColor = false;
  19. #endregion
  20. #region Constructor
  21. // No need to construct this object
  22. private ColorUtil()
  23. {
  24. }
  25. #endregion
  26. #region Properties
  27. static public bool UsingCustomColor
  28. {
  29. get { return useCustomColor;}
  30. }
  31. #endregion
  32. #region Knowncolor names
  33. static public string[] KnownColorNames = 
  34. { "Transparent", "Black", "DimGray", "Gray", "DarkGray", "Silver", "LightGray", "Gainsboro", "WhiteSmoke", "White",
  35.   "RosyBrown", "IndianRed", "Brown", "Firebrick", "LightCoral", "Maroon", "DarkRed", "Red", "Snow", "MistyRose",
  36.   "Salmon", "Tomato", "DarkSalmon", "Coral", "OrangeRed", "LightSalmon", "Sienna", "SeaShell", "Chocalate",
  37.   "SaddleBrown", "SandyBrown", "PeachPuff", "Peru", "Linen", "Bisque", "DarkOrange", "BurlyWood", "Tan", "AntiqueWhite",
  38.   "NavajoWhite", "BlanchedAlmond", "PapayaWhip", "Mocassin", "Orange", "Wheat", "OldLace", "FloralWhite", "DarkGoldenrod",
  39.   "Cornsilk", "Gold", "Khaki", "LemonChiffon", "PaleGoldenrod", "DarkKhaki", "Beige", "LightGoldenrod", "Olive",
  40.   "Yellow", "LightYellow", "Ivory", "OliveDrab", "YellowGreen", "DarkOliveGreen", "GreenYellow", "Chartreuse", "LawnGreen",
  41.   "DarkSeaGreen", "ForestGreen", "LimeGreen", "PaleGreen", "DarkGreen", "Green", "Lime", "Honeydew", "SeaGreen", "MediumSeaGreen",
  42.   "SpringGreen", "MintCream", "MediumSpringGreen", "MediumAquaMarine", "YellowAquaMarine", "Turquoise", "LightSeaGreen",
  43.   "MediumTurquoise", "DarkSlateGray", "PaleTurquoise", "Teal", "DarkCyan", "Aqua", "Cyan", "LightCyan", "Azure", "DarkTurquoise",
  44.   "CadetBlue", "PowderBlue", "LightBlue", "DeepSkyBlue", "SkyBlue", "LightSkyBlue", "SteelBlue", "AliceBlue", "DodgerBlue",
  45.   "SlateGray", "LightSlateGray", "LightSteelBlue", "CornflowerBlue", "RoyalBlue", "MidnightBlue", "Lavender", "Navy",
  46.   "DarkBlue", "MediumBlue", "Blue", "GhostWhite", "SlateBlue", "DarkSlateBlue", "MediumSlateBlue", "MediumPurple",
  47.   "BlueViolet", "Indigo", "DarkOrchid", "DarkViolet", "MediumOrchid", "Thistle", "Plum", "Violet", "Purple", "DarkMagenta",
  48.   "Magenta", "Fuchsia", "Orchid", "MediumVioletRed", "DeepPink", "HotPink", "LavenderBlush", "PaleVioletRed", "Crimson",
  49.   "Pink", "LightPink" };
  50. #endregion
  51. #region Systemcolors names
  52. static public string[] SystemColorNames = 
  53. {
  54. "ActiveBorder", "ActiveCaption", "ActiveCaptionText", "AppWorkspace", "Control", "ControlDark", "ControlDarkDark",
  55. "ControlLight", "ControlLightLight", "ControlText", "Desktop", "GrayText", "HighLight", "HighLightText", 
  56. "HotTrack", "InactiveBorder", "InactiveCaption", "InactiveCaptionText", "Info", "InfoText", "Menu", "MenuText",
  57. "ScrollBar", "Window", "WindowFrame", "WindowText" };
  58. #endregion
  59. #region Conversion between RGB and Hue, Saturation and Luminosity function helpers
  60. static public void HSLToRGB(float h, float s, float l, ref float r, ref float g, ref float b)
  61. {
  62. // given h,s,l,[240 and r,g,b [0-255]
  63. // convert h [0-360], s,l,r,g,b [0-1]
  64. h=(h/240)*360;
  65. s /= 240;
  66. l /= 240;
  67. r /= 255;
  68. g /= 255;
  69. b /= 255;
  70. // Begin Foley
  71. float m1,m2;
  72. // Calc m2
  73. if (l<=0.5f) 
  74. {
  75. //m2=(l*(l+s)); seems to be typo in Foley??, replace l for 1
  76. m2=(l*(1+s));
  77. else 
  78. {
  79. m2=(l+s-l*s);
  80. }
  81. //calc m1
  82. m1=2.0f*l-m2;
  83. //calc r,g,b in [0-1]
  84. if (s==0.0f) 
  85. { // Achromatic: There is no hue
  86. // leave out the UNDEFINED part, h will always have value
  87. r=g=b=l;
  88. else 
  89. { // Chromatic: There is a hue
  90. r= getRGBValue(m1,m2,h+120.0f);
  91. g= getRGBValue(m1,m2,h);
  92. b= getRGBValue(m1,m2,h-120.0f);
  93. }
  94. // End Foley
  95. // convert to 0-255 ranges
  96. r*=255;
  97. g*=255;
  98. b*=255;
  99.             
  100. }
  101. static private float getRGBValue(float n1, float n2, float hue)
  102. {
  103. // Helper function for the HSLToRGB function above
  104. if (hue>360.0f) 
  105. {
  106. hue-=360.0f;
  107. else if (hue<0.0f) 
  108. {
  109. hue+=360.0f;
  110. }
  111. if (hue<60.0) 
  112. {
  113. return n1+(n2-n1)*hue/60.0f;
  114. else if (hue<180.0f) 
  115. {
  116. return n2;
  117. else if (hue<240.0f) 
  118. {
  119. return n1+(n2-n1)*(240.0f-hue)/60.0f;
  120. else 
  121. {
  122. return n1;
  123. }
  124. }
  125. static public void RGBToHSL(int r, int g, int b, ref float h, ref float s, ref float l)
  126. {
  127. float delta;
  128. float fr = (float)r/255;
  129. float fg = (float)g/255;
  130. float fb = (float)b/255;
  131. float max = Math.Max(fr,Math.Max(fg,fb));
  132. float min = Math.Min(fr,Math.Min(fg,fb));
  133. //calc the lightness
  134. l = (max+min)/2;
  135. if (max==min)
  136. {
  137. //should be undefined but this works for what we need
  138. s = 0;
  139. h = 240.0f;
  140. else 
  141. {
  142. delta = max-min;
  143. //calc the Saturation
  144. if (l < 0.5) 
  145. {
  146. s = delta/(max+min);
  147. else 
  148. {
  149. s = delta/(2.0f-(max+min));
  150. }
  151. //calc the hue
  152. if (fr==max) 
  153. {
  154. h = (fg-fb)/delta;
  155. else if (fg==max) 
  156. {
  157. h = 2.0f + (fb-fr)/delta;
  158. else if (fb==max) 
  159. {
  160. h = 4.0f + (fr-fg)/delta;
  161. }
  162. //convert hue to degrees
  163. h*=60.0f;
  164. if (h<0.0f) 
  165. {
  166. h+=360.0f;
  167. }
  168. }
  169. //convert to 0-255 ranges
  170. //h [0-360], h,l [0-1]
  171. l*=240;
  172. s*=240;
  173. h=(h/360)*240;
  174.             
  175. }
  176. #endregion
  177. #region Visual Studio .NET colors calculation helpers
  178.        
  179. static public Color VSNetBackgroundColor
  180. {
  181. get 
  182. {
  183. if ( useCustomColor && backgroundColor != Color.Empty )
  184. return backgroundColor;
  185. else
  186. return CalculateColor(SystemColors.Window, SystemColors.Control, 220);
  187. }
  188. set
  189. {
  190. // Flag that we are going to use custom colors instead
  191. // of calculating the color based on the system colors
  192. // -- this is a way of hooking up into the VSNetColors that I use throughout
  193. // the UtilityLibrary
  194. useCustomColor = true;
  195. backgroundColor = value;
  196. }
  197. }
  198. static public Color VSNetSelectionColor
  199. {
  200. get 
  201. {
  202. if ( useCustomColor && selectionColor != Color.Empty )
  203. return selectionColor;
  204. else
  205. return CalculateColor(SystemColors.Highlight, SystemColors.Window, 70);
  206. }
  207. set
  208. {
  209. // Flag that we are going to use custom colors instead
  210. // of calculating the color based on the system colors
  211. // -- this is a way of hooking up into the VSNetColor that I use throughout
  212. // the UtilityLibrary
  213. useCustomColor = true;
  214. selectionColor = value;
  215. }
  216. }
  217. static public Color VSNetControlColor
  218. {
  219. get 
  220. { if ( useCustomColor && controlColor != Color.Empty )
  221. return controlColor;
  222. else
  223. return CalculateColor(SystemColors.Control, VSNetBackgroundColor, 195);
  224. }
  225. set
  226. {
  227. // Flag that we are going to use custom colors instead
  228. // of calculating the color based on the system colors
  229. // -- this is a way of hooking up into the VSNetColors that I use throughout
  230. // the UtilityLibrary
  231. useCustomColor = true;
  232. controlColor = value;
  233. }
  234. }
  235. static public Color VSNetPressedColor
  236. {
  237. get 
  238. {
  239. if ( useCustomColor && pressedColor != Color.Empty )
  240. return pressedColor;
  241. else
  242. return CalculateColor(SystemColors.Highlight, ColorUtil.VSNetSelectionColor, 70);
  243. }
  244. set
  245. {
  246. // Flag that we are going to use custom colors instead
  247. // of calculating the color based on the system colors
  248. // -- this is a way of hooking up into the VSNetColors that I use throughout
  249. // the UtilityLibrary
  250. useCustomColor = true;
  251. pressedColor = value;
  252. }
  253. }
  254. static public Color VSNetCheckedColor
  255. {
  256. get 
  257. {
  258. if ( useCustomColor && pressedColor != Color.Empty )
  259. return checkedColor;
  260. else
  261. return CalculateColor(SystemColors.Highlight,  SystemColors.Window, 30);
  262. }
  263. set
  264. {
  265. // Flag that we are going to use custom colors instead
  266. // of calculating the color based on the system colors
  267. // -- this is a way of hooking up into the VSNetColors that I use throughout
  268. // the UtilityLibrary
  269. useCustomColor = true;
  270. checkedColor = value;
  271. }
  272. }
  273. static public Color VSNetBorderColor
  274. {
  275. get 
  276. {
  277. if ( useCustomColor && borderColor != Color.Empty )
  278. return borderColor;
  279. else
  280. {
  281. // This color is the default color unless we are using 
  282. // custom colors
  283. return SystemColors.Highlight;
  284. }
  285. }
  286. set
  287. {
  288. // Flag that we are going to use custom colors instead
  289. // of calculating the color based on the system colors
  290. // -- this is a way of hooking up into the VSNetColors that I use throughout
  291. // the UtilityLibrary
  292. useCustomColor = true;
  293. borderColor = value;
  294. }
  295. }
  296. private static Color CalculateColor(Color front, Color back, int alpha)
  297. {
  298. // Use alpha blending to brigthen the colors but don't use it
  299. // directly. Instead derive an opaque color that we can use.
  300. // -- if we use a color with alpha blending directly we won't be able 
  301. // to paint over whatever color was in the background and there
  302. // would be shadows of that color showing through
  303. Color frontColor = Color.FromArgb(255, front);
  304. Color backColor = Color.FromArgb(255, back);
  305. float frontRed = frontColor.R;
  306. float frontGreen = frontColor.G;
  307. float frontBlue = frontColor.B;
  308. float backRed = backColor.R;
  309. float backGreen = backColor.G;
  310. float backBlue = backColor.B;
  311. float fRed = frontRed*alpha/255 + backRed*((float)(255-alpha)/255);
  312. byte newRed = (byte)fRed;
  313. float fGreen = frontGreen*alpha/255 + backGreen*((float)(255-alpha)/255);
  314. byte newGreen = (byte)fGreen;
  315. float fBlue = frontBlue*alpha/255 + backBlue*((float)(255-alpha)/255);
  316. byte newBlue = (byte)fBlue;
  317. return  Color.FromArgb(255, newRed, newGreen, newBlue);
  318. }
  319. #endregion
  320. #region General functions
  321. static public Color ColorFromPoint(Graphics g, int x, int y)
  322. {
  323. IntPtr hDC = g.GetHdc();
  324. // Get the color of the pixel first
  325. uint colorref = WindowsAPI.GetPixel(hDC, x, y);
  326. byte Red = GetRValue(colorref);
  327. byte Green = GetGValue(colorref);
  328. byte Blue = GetBValue(colorref);
  329. g.ReleaseHdc(hDC);
  330. return  Color.FromArgb(Red, Green, Blue);
  331. }
  332. static public bool IsKnownColor(Color color, ref Color knownColor, bool useTransparent)
  333. {
  334. // Using the Color structrure "FromKnowColor" does not work if 
  335. // we did not create the color as a known color to begin with
  336. // we need to compare the rgbs of both color 
  337. Color currentColor = Color.Empty;
  338. bool badColor = false;
  339. for (KnownColor enumValue = 0; enumValue <= KnownColor.YellowGreen; enumValue++)
  340. {
  341. currentColor = Color.FromKnownColor(enumValue);
  342. string colorName = currentColor.Name;
  343. if ( !useTransparent ) 
  344. badColor = (colorName == "Transparent");
  345. if ( color.A == currentColor.A && color.R == currentColor.R && color.G == currentColor.G 
  346. && color.B == currentColor.B && !currentColor.IsSystemColor
  347. && !badColor )
  348. {
  349. knownColor = currentColor;
  350. return true;
  351. }
  352. }
  353. return false;
  354. }
  355. static public bool IsSystemColor(Color color, ref Color knownColor)
  356. {
  357. // Using the Color structrure "FromKnowColor" does not work if 
  358. // we did not create the color as a known color to begin with
  359. // we need to compare the rgbs of both color 
  360. Color currentColor = Color.Empty;
  361. for (KnownColor enumValue = 0; enumValue <= KnownColor.YellowGreen; enumValue++)
  362. {
  363. currentColor = Color.FromKnownColor(enumValue);
  364. string colorName = currentColor.Name;
  365. if ( color.R == currentColor.R && color.G == currentColor.G 
  366. && color.B == currentColor.B && currentColor.IsSystemColor )
  367. {
  368. knownColor = currentColor;
  369. return true;
  370. }
  371. }
  372. return false;
  373. }
  374. static public uint GetCOLORREF(Color color)
  375. {
  376. return RGB(color.R, color.G, color.B);
  377. }
  378. static public Color ColorFromRGBString(string text)
  379. {
  380. Color rgbColor = Color.Empty;
  381. string[] RGBs = text.Split(','); 
  382. if ( RGBs.Length != 3 ) 
  383. {
  384. // If we don't have three pieces of information, then the
  385. // string is not properly formatted, inform the use
  386. throw new Exception("RGB color string is not well formed");
  387. }
  388. string stringR = RGBs[0];
  389. string stringG = RGBs[1];
  390. string stringB = RGBs[2];
  391. int R, G, B;
  392. try 
  393. {
  394. R = Convert.ToInt32(stringR);
  395. G = Convert.ToInt32(stringG);
  396. B = Convert.ToInt32(stringB);
  397. if ( ( R < 0 || R > 255 ) || ( G < 0 || G > 255 ) || ( B < 0 || B > 255 ) ) 
  398. {
  399. throw new Exception("Out of bounds RGB value");
  400. }
  401. else 
  402. {
  403. // Convert to color 
  404. rgbColor = Color.FromArgb(R, G, B);
  405. // See if we have either a web color or a systgem color
  406. Color knownColor = Color.Empty;
  407. bool isKnown = ColorUtil.IsKnownColor( rgbColor, ref knownColor, true);
  408. if ( !isKnown )
  409. isKnown = ColorUtil.IsSystemColor(rgbColor, ref knownColor);
  410. if ( isKnown )
  411. rgbColor = knownColor;
  412. }
  413. }
  414. catch ( InvalidCastException )
  415. {
  416. throw new Exception("Invalid RGB value");
  417. }
  418. return rgbColor;
  419. }
  420. static public Color LightColor(Color color, int inc)
  421. {
  422. int red = color.R;
  423. int green = color.G;
  424. int blue = color.B;
  425. if ( red + inc <= 255 )
  426. red += inc;
  427. if ( green + inc <= 255 )
  428. green += inc;
  429. if ( blue + inc <= 255 )
  430. blue += inc;
  431.             return Color.FromArgb(red, green, blue);
  432. }
  433. static public Color DarkColor(Color color, int inc)
  434. {
  435. int red = color.R;
  436. int green = color.G;
  437. int blue = color.B;
  438. if ( red >= inc )
  439. red -= inc;
  440. if ( green >= inc )
  441. green -= inc;
  442. if ( blue >= inc )
  443. blue -= inc;
  444.  return Color.FromArgb(red, green, blue);
  445. }
  446.         #endregion
  447. #region Windows RGB related macros
  448. static public byte GetRValue(uint color)
  449. {
  450. return (byte)color;
  451. }
  452. static public byte GetGValue(uint color)
  453. {
  454. return ((byte)(((short)(color)) >> 8));
  455. }
  456. static public byte GetBValue(uint color)
  457. {
  458. return ((byte)((color)>>16));
  459. }
  460. static public uint RGB(int r, int g, int b)
  461. {
  462. return ((uint)(((byte)(r)|((short)((byte)(g))<<8))|(((short)(byte)(b))<<16)));
  463. }
  464. #endregion
  465. }
  466. }