ColorConverter.cs 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. using System.Drawing;
  2. namespace Masuit.Tools.Media;
  3. internal static class ColorConverter
  4. {
  5. // RGB转换器
  6. public static LabColor ToLab(this Color color)
  7. {
  8. // 第一步:将RGB转换为0-1范围
  9. double rLinear = color.R / 255.0;
  10. double gLinear = color.G / 255.0;
  11. double bLinear = color.B / 255.0;
  12. // 第二步:应用逆伽马校正
  13. rLinear = (rLinear <= 0.04045) ? rLinear / 12.92 : Math.Pow((rLinear + 0.055) / 1.055, 2.4);
  14. gLinear = (gLinear <= 0.04045) ? gLinear / 12.92 : Math.Pow((gLinear + 0.055) / 1.055, 2.4);
  15. bLinear = (bLinear <= 0.04045) ? bLinear / 12.92 : Math.Pow((bLinear + 0.055) / 1.055, 2.4);
  16. // 第三步:转换为XYZ(D65白点)
  17. double x = rLinear * 0.4124564 + gLinear * 0.3575761 + bLinear * 0.1804375;
  18. double y = rLinear * 0.2126729 + gLinear * 0.7151522 + bLinear * 0.0721750;
  19. double z = rLinear * 0.0193339 + gLinear * 0.1191920 + bLinear * 0.9503041;
  20. // 第四步:XYZ转Lab(使用D65参考白)
  21. const double xn = 0.95047;
  22. const double yn = 1.00000;
  23. const double zn = 1.08883;
  24. double xRatio = x / xn;
  25. double yRatio = y / yn;
  26. double zRatio = z / zn;
  27. double fx = (xRatio > 0.008856) ? Math.Pow(xRatio, 1.0 / 3.0) : (903.3 * xRatio + 16) / 116.0;
  28. double fy = (yRatio > 0.008856) ? Math.Pow(yRatio, 1.0 / 3.0) : (903.3 * yRatio + 16) / 116.0;
  29. double fz = (zRatio > 0.008856) ? Math.Pow(zRatio, 1.0 / 3.0) : (903.3 * zRatio + 16) / 116.0;
  30. double l = (yRatio > 0.008856) ? (116 * fy - 16) : (903.3 * yRatio);
  31. double a = 500 * (fx - fy);
  32. double bVal = 200 * (fy - fz);
  33. return new LabColor(l, a, bVal);
  34. }
  35. // CMY转换器
  36. public static LabColor ToLab(this CMYColor cmy)
  37. {
  38. // CMY转RGB (0-1范围)
  39. double r = 1 - cmy.C;
  40. double g = 1 - cmy.M;
  41. double b = 1 - cmy.Y;
  42. // RGB转Lab
  43. return ToLab(Color.FromArgb((int)(r * 255), (int)(g * 255), (int)(b * 255)));
  44. }
  45. // CMYK转换器
  46. public static LabColor ToLab(this CMYKColor cmyk)
  47. {
  48. // CMYK转RGB
  49. double r = (1 - cmyk.C) * (1 - cmyk.K);
  50. double g = (1 - cmyk.M) * (1 - cmyk.K);
  51. double b = (1 - cmyk.Y) * (1 - cmyk.K);
  52. // RGB转Lab
  53. return ToLab(Color.FromArgb((int)(r * 255), (int)(g * 255), (int)(b * 255)));
  54. }
  55. // HSL转换器
  56. public static LabColor ToLab(this HSLColor hsl)
  57. {
  58. // HSL转RGB
  59. Color rgb = ToRgb(hsl);
  60. return ToLab(rgb);
  61. }
  62. private static Color ToRgb(HSLColor hsl)
  63. {
  64. double h = hsl.H / 360.0;
  65. double s = hsl.S;
  66. double l = hsl.L;
  67. double r, g, b;
  68. if (s == 0)
  69. {
  70. r = g = b = l;
  71. }
  72. else
  73. {
  74. double q = l < 0.5 ? l * (1 + s) : l + s - l * s;
  75. double p = 2 * l - q;
  76. r = HueToRgb(p, q, h + 1.0 / 3);
  77. g = HueToRgb(p, q, h);
  78. b = HueToRgb(p, q, h - 1.0 / 3);
  79. }
  80. return Color.FromArgb((int)(r * 255), (int)(g * 255), (int)(b * 255));
  81. }
  82. private static double HueToRgb(double p, double q, double t)
  83. {
  84. if (t < 0) t += 1;
  85. if (t > 1) t -= 1;
  86. if (t < 1.0 / 6) return p + (q - p) * 6 * t;
  87. if (t < 1.0 / 2) return q;
  88. if (t < 2.0 / 3) return p + (q - p) * (2.0 / 3 - t) * 6;
  89. return p;
  90. }
  91. // LCH转换器
  92. public static LabColor ToLab(this LCHColor lch)
  93. {
  94. // LCH转Lab
  95. double rad = lch.H * Math.PI / 180.0;
  96. double a = lch.C * Math.Cos(rad);
  97. double b = lch.C * Math.Sin(rad);
  98. return new LabColor(lch.L, a, b);
  99. }
  100. // XYZ转换器
  101. public static LabColor ToLab(this XYZColor xyz)
  102. {
  103. // 使用D65参考白点
  104. const double xn = 0.95047;
  105. const double yn = 1.00000;
  106. const double zn = 1.08883;
  107. double xRatio = xyz.X / xn;
  108. double yRatio = xyz.Y / yn;
  109. double zRatio = xyz.Z / zn;
  110. double fx = Fxyz(xRatio);
  111. double fy = Fxyz(yRatio);
  112. double fz = Fxyz(zRatio);
  113. double L = 116 * fy - 16;
  114. double a = 500 * (fx - fy);
  115. double b = 200 * (fy - fz);
  116. return new LabColor(L, a, b);
  117. }
  118. private static double Fxyz(double t)
  119. {
  120. const double delta = 6.0 / 29.0;
  121. const double delta3 = delta * delta * delta;
  122. return (t > delta3) ? Math.Pow(t, 1.0 / 3.0) : t / (3 * delta * delta) + 4.0 / 29.0;
  123. }
  124. // YXZ转换器 (假设YXZ是Y,X,Z顺序)
  125. public static LabColor YxzToLab(this YXZColor yxz)
  126. {
  127. // 转换为标准XYZ顺序
  128. return ToLab(new XYZColor(yxz.X, yxz.Y, yxz.Z));
  129. }
  130. }