ColorVector.cs 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486
  1. using System;
  2. using System.ComponentModel;
  3. using System.Drawing;
  4. using System.Runtime.InteropServices;
  5. using System.Text;
  6. namespace Microsoft.Drawing
  7. {
  8. /// <summary>
  9. /// 颜色向量,只支持加减操作,不支持乘除操作
  10. /// Copyright (c) JajaSoft
  11. /// </summary>
  12. [Serializable, StructLayout(LayoutKind.Sequential), ComVisible(true), TypeConverter(typeof(ColorVectorConverter))]
  13. public struct ColorVector
  14. {
  15. #region 静态
  16. /// <summary>
  17. /// A=0,R=0,G=0,B=0
  18. /// </summary>
  19. public static readonly ColorVector Empty;
  20. /// <summary>
  21. /// 静态构造
  22. /// </summary>
  23. static ColorVector()
  24. {
  25. Empty = new ColorVector();
  26. }
  27. /// <summary>
  28. /// 生成Long,各占16位共64位
  29. /// </summary>
  30. /// <param name="alpha">A</param>
  31. /// <param name="red">R</param>
  32. /// <param name="green">G</param>
  33. /// <param name="blue">B</param>
  34. /// <returns>长整型数值</returns>
  35. private static long MakeLong(int alpha, int red, int green, int blue)
  36. {
  37. ulong ulA = (ulong)(alpha & ushort.MaxValue);
  38. ulong ulR = (ulong)(red & ushort.MaxValue);
  39. ulong ulG = (ulong)(green & ushort.MaxValue);
  40. ulong ulB = (ulong)(blue & ushort.MaxValue);
  41. return (long)((ulA << 0x30) | (ulR << 0x20) | (ulG << 0x10) | ulB);
  42. }
  43. /// <summary>
  44. /// 从一个64位整数创建ColorVector结构
  45. /// </summary>
  46. /// <param name="value">64位整数</param>
  47. /// <returns>ColorVector结构</returns>
  48. public static ColorVector FromArgb(long value)
  49. {
  50. return new ColorVector(value);
  51. }
  52. /// <summary>
  53. /// 从一个Color结构创建ColorVector结构
  54. /// </summary>
  55. /// <param name="color">Color结构</param>
  56. /// <returns>ColorVector结构</returns>
  57. public static ColorVector FromArgb(Color color)
  58. {
  59. return new ColorVector(color.A, color.R, color.G, color.B);
  60. }
  61. /// <summary>
  62. /// 从一个Color结构创建ColorVector结构,但Alpha使用指定的值
  63. /// </summary>
  64. /// <param name="alpha">Alpha指定值</param>
  65. /// <param name="color">Color结构</param>
  66. /// <returns>ColorVector结构</returns>
  67. public static ColorVector FromArgb(int alpha, Color color)
  68. {
  69. return new ColorVector(alpha, color.R, color.G, color.B);
  70. }
  71. /// <summary>
  72. /// 从一个ColorVector结构创建ColorVector结构,但Alpha使用指定值
  73. /// </summary>
  74. /// <param name="alpha">Alpha指定值</param>
  75. /// <param name="vector">ColorVector结构</param>
  76. /// <returns>ColorVector结构</returns>
  77. public static ColorVector FromArgb(int alpha, ColorVector vector)
  78. {
  79. return new ColorVector(alpha, vector.R, vector.G, vector.B);
  80. }
  81. /// <summary>
  82. /// 从三个16位整数创建ColorVector结构,Alpha使用0
  83. /// </summary>
  84. /// <param name="red">Red值</param>
  85. /// <param name="green">Green值</param>
  86. /// <param name="blue">Blue值</param>
  87. /// <returns>ColorVector结构</returns>
  88. public static ColorVector FromArgb(int red, int green, int blue)
  89. {
  90. return new ColorVector(0, red, green, blue);
  91. }
  92. /// <summary>
  93. /// 从四个16位整数创建ColorVector结构
  94. /// </summary>
  95. /// <param name="alpha">Alpha值</param>
  96. /// <param name="red">Red值</param>
  97. /// <param name="green">Green值</param>
  98. /// <param name="blue">Blue值</param>
  99. /// <returns>ColorVector结构</returns>
  100. public static ColorVector FromArgb(int alpha, int red, int green, int blue)
  101. {
  102. return new ColorVector(alpha, red, green, blue);
  103. }
  104. #endregion
  105. #region 字段属性
  106. //64位值
  107. private long Value;
  108. /// <summary>
  109. /// Alpha分量上的偏移量
  110. /// </summary>
  111. public short A
  112. {
  113. get
  114. {
  115. return (short)((this.Value >> 0x30) & ushort.MaxValue);
  116. }
  117. }
  118. /// <summary>
  119. /// 红色分量上的偏移量
  120. /// </summary>
  121. public short R
  122. {
  123. get
  124. {
  125. return (short)((this.Value >> 0x20) & ushort.MaxValue);
  126. }
  127. }
  128. /// <summary>
  129. /// 绿色分量上的偏移量
  130. /// </summary>
  131. public short G
  132. {
  133. get
  134. {
  135. return (short)((this.Value >> 0x10) & ushort.MaxValue);
  136. }
  137. }
  138. /// <summary>
  139. /// 蓝色分量上的偏移量
  140. /// </summary>
  141. public short B
  142. {
  143. get
  144. {
  145. return (short)(this.Value & ushort.MaxValue);
  146. }
  147. }
  148. #endregion
  149. #region 构造函数
  150. /// <summary>
  151. /// 构造函数
  152. /// </summary>
  153. /// <param name="value">长整型数值</param>
  154. private ColorVector(long value)
  155. {
  156. this.Value = value;
  157. }
  158. /// <summary>
  159. /// 构造函数,各占16位.short(-32768,32767)
  160. /// </summary>
  161. /// <param name="alpha">A</param>
  162. /// <param name="red">R</param>
  163. /// <param name="green">G</param>
  164. /// <param name="blue">B</param>
  165. private ColorVector(int alpha, int red, int green, int blue)
  166. : this(MakeLong(alpha, red, green, blue))
  167. {
  168. }
  169. #endregion
  170. #region 公共方法
  171. /// <summary>
  172. /// 获取Hash值
  173. /// </summary>
  174. /// <returns>返回</returns>
  175. public override int GetHashCode()
  176. {
  177. return this.Value.GetHashCode();
  178. }
  179. /// <summary>
  180. /// 转换为字符串
  181. /// </summary>
  182. /// <returns>字符串</returns>
  183. public override string ToString()
  184. {
  185. StringBuilder builder = new StringBuilder(0x20);
  186. builder.Append(base.GetType().Name);
  187. builder.Append(" [");
  188. if (this == ColorVector.Empty)
  189. {
  190. builder.Append("Empty");
  191. }
  192. else
  193. {
  194. builder.Append("A=");
  195. builder.Append(this.A);
  196. builder.Append(", R=");
  197. builder.Append(this.R);
  198. builder.Append(", G=");
  199. builder.Append(this.G);
  200. builder.Append(", B=");
  201. builder.Append(this.B);
  202. }
  203. builder.Append("]");
  204. return builder.ToString();
  205. }
  206. /// <summary>
  207. /// 判断两个是否相等
  208. /// </summary>
  209. /// <param name="obj">目标对象</param>
  210. /// <returns>相等返回true,否则返回false</returns>
  211. public override bool Equals(object obj)
  212. {
  213. if (obj is ColorVector)
  214. {
  215. ColorVector vector = (ColorVector)obj;
  216. return this == vector;
  217. }
  218. return false;
  219. }
  220. /// <summary>
  221. /// 转换为颜色
  222. /// </summary>
  223. /// <returns>颜色</returns>
  224. public Color ToColor()
  225. {
  226. return Color.FromArgb(MathEx.Clamp(this.A, (byte)0, (byte)255),
  227. MathEx.Clamp(this.R, (byte)0, (byte)255),
  228. MathEx.Clamp(this.G, (byte)0, (byte)255),
  229. MathEx.Clamp(this.B, (byte)0, (byte)255));
  230. }
  231. #endregion
  232. #region 操作符
  233. /// <summary>
  234. /// 等于
  235. /// </summary>
  236. /// <param name="left">左值</param>
  237. /// <param name="right">右值</param>
  238. /// <returns>相等返回true,否则返回false</returns>
  239. public static bool operator ==(ColorVector left, ColorVector right)
  240. {
  241. return left.Value == right.Value;
  242. }
  243. /// <summary>
  244. /// 等于
  245. /// </summary>
  246. /// <param name="left">左值</param>
  247. /// <param name="right">右值</param>
  248. /// <returns>不等返回true,否则返回false</returns>
  249. public static bool operator !=(ColorVector left, ColorVector right)
  250. {
  251. return !(left == right);
  252. }
  253. /// <summary>
  254. /// 大于
  255. /// </summary>
  256. /// <param name="left">左值</param>
  257. /// <param name="right">右值</param>
  258. /// <returns>A,R,G,B全部大于返回true,否则返回false</returns>
  259. public static bool operator >(ColorVector left, ColorVector right)
  260. {
  261. return left.A > right.A
  262. && left.R > right.R
  263. && left.G > right.G
  264. && left.B > right.B;
  265. }
  266. /// <summary>
  267. /// 大于等于
  268. /// </summary>
  269. /// <param name="left">左值</param>
  270. /// <param name="right">右值</param>
  271. /// <returns>A,R,G,B全部大于等于返回true,否则返回false</returns>
  272. public static bool operator >=(ColorVector left, ColorVector right)
  273. {
  274. return left.A >= right.A
  275. && left.R >= right.R
  276. && left.G >= right.G
  277. && left.B >= right.B;
  278. }
  279. /// <summary>
  280. /// 小于
  281. /// </summary>
  282. /// <param name="left">左值</param>
  283. /// <param name="right">右值</param>
  284. /// <returns>A,R,G,B全部小于返回true,否则返回false</returns>
  285. public static bool operator <(ColorVector left, ColorVector right)
  286. {
  287. return left.A < right.A
  288. && left.R < right.R
  289. && left.G < right.G
  290. && left.B < right.B;
  291. }
  292. /// <summary>
  293. /// 小于等于
  294. /// </summary>
  295. /// <param name="left">左值</param>
  296. /// <param name="right">右值</param>
  297. /// <returns>A,R,G,B全部小于等于返回true,否则返回false</returns>
  298. public static bool operator <=(ColorVector left, ColorVector right)
  299. {
  300. return left.A <= right.A
  301. && left.R <= right.R
  302. && left.G <= right.G
  303. && left.B <= right.B;
  304. }
  305. /// <summary>
  306. /// 两个颜色向量相加
  307. /// </summary>
  308. /// <param name="left">左值</param>
  309. /// <param name="right">右值</param>
  310. /// <returns>返回新颜色向量</returns>
  311. public static ColorVector operator +(ColorVector left, ColorVector right)
  312. {
  313. return new ColorVector(left.A + right.A, left.R + right.R, left.G + right.G, left.B + right.B);
  314. }
  315. /// <summary>
  316. /// 颜色加上颜色向量
  317. /// </summary>
  318. /// <param name="left">颜色</param>
  319. /// <param name="right">颜色向量</param>
  320. /// <returns>返回新颜色</returns>
  321. public static Color operator +(Color left, ColorVector right)
  322. {
  323. return Color.FromArgb(MathEx.Clamp(left.A + right.A, (byte)0, (byte)255),
  324. MathEx.Clamp(left.R + right.R, (byte)0, (byte)255),
  325. MathEx.Clamp(left.G + right.G, (byte)0, (byte)255),
  326. MathEx.Clamp(left.B + right.B, (byte)0, (byte)255));
  327. }
  328. /// <summary>
  329. /// 两个颜色向量相减
  330. /// </summary>
  331. /// <param name="left">左值</param>
  332. /// <param name="right">右值</param>
  333. /// <returns>返回新颜色向量</returns>
  334. public static ColorVector operator -(ColorVector left, ColorVector right)
  335. {
  336. return new ColorVector(left.A - right.A, left.R - right.R, left.G - right.G, left.B - right.B);
  337. }
  338. /// <summary>
  339. /// 颜色减去颜色向量
  340. /// </summary>
  341. /// <param name="left">颜色</param>
  342. /// <param name="right">颜色向量</param>
  343. /// <returns>返回新颜色</returns>
  344. public static Color operator -(Color left, ColorVector right)
  345. {
  346. return Color.FromArgb(MathEx.Clamp(left.A - right.A, (byte)0, (byte)255),
  347. MathEx.Clamp(left.R - right.R, (byte)0, (byte)255),
  348. MathEx.Clamp(left.G - right.G, (byte)0, (byte)255),
  349. MathEx.Clamp(left.B - right.B, (byte)0, (byte)255));
  350. }
  351. /// <summary>
  352. /// 颜色向量乘以浮点数
  353. /// </summary>
  354. /// <param name="left">颜色向量</param>
  355. /// <param name="right">浮点数</param>
  356. /// <returns>返回新颜色向量</returns>
  357. public static ColorVector operator *(ColorVector left, float right)
  358. {
  359. return new ColorVector((int)(left.A * right), (int)(left.R * right), (int)(left.G * right), (int)(left.B * right));
  360. }
  361. /// <summary>
  362. /// 浮点数乘以颜色向量
  363. /// </summary>
  364. /// <param name="left">浮点数</param>
  365. /// <param name="right">颜色向量</param>
  366. /// <returns>返回新颜色向量</returns>
  367. public static ColorVector operator *(float left, ColorVector right)
  368. {
  369. return new ColorVector((int)(left * right.A), (int)(left * right.R), (int)(left * right.G), (int)(left * right.B));
  370. }
  371. /// <summary>
  372. /// 颜色向量乘以整数
  373. /// </summary>
  374. /// <param name="left">颜色向量</param>
  375. /// <param name="right">浮点数</param>
  376. /// <returns>返回新颜色向量</returns>
  377. public static ColorVector operator *(ColorVector left, int right)
  378. {
  379. return new ColorVector(left.A * right, left.R * right, left.G * right, left.B * right);
  380. }
  381. /// <summary>
  382. /// 整数乘以颜色向量
  383. /// </summary>
  384. /// <param name="left">整数</param>
  385. /// <param name="right">颜色向量</param>
  386. /// <returns>返回新颜色向量</returns>
  387. public static ColorVector operator *(int left, ColorVector right)
  388. {
  389. return new ColorVector(left * right.A, left * right.R, left * right.G, left * right.B);
  390. }
  391. /// <summary>
  392. /// 颜色向量除以浮点数
  393. /// </summary>
  394. /// <param name="left">颜色向量</param>
  395. /// <param name="right">浮点数</param>
  396. /// <returns>返回新颜色向量</returns>
  397. public static ColorVector operator /(ColorVector left, float right)
  398. {
  399. return new ColorVector((int)(left.A / right), (int)(left.R / right), (int)(left.G / right), (int)(left.B / right));
  400. }
  401. /// <summary>
  402. /// 浮点数除以颜色向量
  403. /// </summary>
  404. /// <param name="left">浮点数</param>
  405. /// <param name="right">颜色向量</param>
  406. /// <returns>返回新颜色向量</returns>
  407. public static ColorVector operator /(float left, ColorVector right)
  408. {
  409. return new ColorVector((int)(left / right.A), (int)(left / right.R), (int)(left / right.G), (int)(left / right.B));
  410. }
  411. /// <summary>
  412. /// 颜色向量除以整数
  413. /// </summary>
  414. /// <param name="left">颜色向量</param>
  415. /// <param name="right">整数</param>
  416. /// <returns>返回新颜色向量</returns>
  417. public static ColorVector operator /(ColorVector left, int right)
  418. {
  419. return new ColorVector(left.A / right, left.R / right, left.G / right, left.B / right);
  420. }
  421. /// <summary>
  422. /// 整数除以颜色向量
  423. /// </summary>
  424. /// <param name="left">整数</param>
  425. /// <param name="right">颜色向量</param>
  426. /// <returns>返回新颜色向量</returns>
  427. public static ColorVector operator /(int left, ColorVector right)
  428. {
  429. return new ColorVector(left / right.A, left / right.R, left / right.G, left / right.B);
  430. }
  431. #endregion
  432. }
  433. }