123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158 |
- using System.Drawing;
- namespace Masuit.Tools.Media;
- internal static class ColorConverter
- {
- // RGB转换器
- public static LabColor ToLab(this Color color)
- {
- // 第一步:将RGB转换为0-1范围
- double rLinear = color.R / 255.0;
- double gLinear = color.G / 255.0;
- double bLinear = color.B / 255.0;
- // 第二步:应用逆伽马校正
- rLinear = (rLinear <= 0.04045) ? rLinear / 12.92 : Math.Pow((rLinear + 0.055) / 1.055, 2.4);
- gLinear = (gLinear <= 0.04045) ? gLinear / 12.92 : Math.Pow((gLinear + 0.055) / 1.055, 2.4);
- bLinear = (bLinear <= 0.04045) ? bLinear / 12.92 : Math.Pow((bLinear + 0.055) / 1.055, 2.4);
- // 第三步:转换为XYZ(D65白点)
- double x = rLinear * 0.4124564 + gLinear * 0.3575761 + bLinear * 0.1804375;
- double y = rLinear * 0.2126729 + gLinear * 0.7151522 + bLinear * 0.0721750;
- double z = rLinear * 0.0193339 + gLinear * 0.1191920 + bLinear * 0.9503041;
- // 第四步:XYZ转Lab(使用D65参考白)
- const double xn = 0.95047;
- const double yn = 1.00000;
- const double zn = 1.08883;
- double xRatio = x / xn;
- double yRatio = y / yn;
- double zRatio = z / zn;
- double fx = (xRatio > 0.008856) ? Math.Pow(xRatio, 1.0 / 3.0) : (903.3 * xRatio + 16) / 116.0;
- double fy = (yRatio > 0.008856) ? Math.Pow(yRatio, 1.0 / 3.0) : (903.3 * yRatio + 16) / 116.0;
- double fz = (zRatio > 0.008856) ? Math.Pow(zRatio, 1.0 / 3.0) : (903.3 * zRatio + 16) / 116.0;
- double l = (yRatio > 0.008856) ? (116 * fy - 16) : (903.3 * yRatio);
- double a = 500 * (fx - fy);
- double bVal = 200 * (fy - fz);
- return new LabColor(l, a, bVal);
- }
- // CMY转换器
- public static LabColor ToLab(this CMYColor cmy)
- {
- // CMY转RGB (0-1范围)
- double r = 1 - cmy.C;
- double g = 1 - cmy.M;
- double b = 1 - cmy.Y;
- // RGB转Lab
- return ToLab(Color.FromArgb((int)(r * 255), (int)(g * 255), (int)(b * 255)));
- }
- // CMYK转换器
- public static LabColor ToLab(this CMYKColor cmyk)
- {
- // CMYK转RGB
- double r = (1 - cmyk.C) * (1 - cmyk.K);
- double g = (1 - cmyk.M) * (1 - cmyk.K);
- double b = (1 - cmyk.Y) * (1 - cmyk.K);
- // RGB转Lab
- return ToLab(Color.FromArgb((int)(r * 255), (int)(g * 255), (int)(b * 255)));
- }
- // HSL转换器
- public static LabColor ToLab(this HSLColor hsl)
- {
- // HSL转RGB
- Color rgb = ToRgb(hsl);
- return ToLab(rgb);
- }
- private static Color ToRgb(HSLColor hsl)
- {
- double h = hsl.H / 360.0;
- double s = hsl.S;
- double l = hsl.L;
- double r, g, b;
- if (s == 0)
- {
- r = g = b = l;
- }
- else
- {
- double q = l < 0.5 ? l * (1 + s) : l + s - l * s;
- double p = 2 * l - q;
- r = HueToRgb(p, q, h + 1.0 / 3);
- g = HueToRgb(p, q, h);
- b = HueToRgb(p, q, h - 1.0 / 3);
- }
- return Color.FromArgb((int)(r * 255), (int)(g * 255), (int)(b * 255));
- }
- private static double HueToRgb(double p, double q, double t)
- {
- if (t < 0) t += 1;
- if (t > 1) t -= 1;
- if (t < 1.0 / 6) return p + (q - p) * 6 * t;
- if (t < 1.0 / 2) return q;
- if (t < 2.0 / 3) return p + (q - p) * (2.0 / 3 - t) * 6;
- return p;
- }
- // LCH转换器
- public static LabColor ToLab(this LCHColor lch)
- {
- // LCH转Lab
- double rad = lch.H * Math.PI / 180.0;
- double a = lch.C * Math.Cos(rad);
- double b = lch.C * Math.Sin(rad);
- return new LabColor(lch.L, a, b);
- }
- // XYZ转换器
- public static LabColor ToLab(this XYZColor xyz)
- {
- // 使用D65参考白点
- const double xn = 0.95047;
- const double yn = 1.00000;
- const double zn = 1.08883;
- double xRatio = xyz.X / xn;
- double yRatio = xyz.Y / yn;
- double zRatio = xyz.Z / zn;
- double fx = Fxyz(xRatio);
- double fy = Fxyz(yRatio);
- double fz = Fxyz(zRatio);
- double L = 116 * fy - 16;
- double a = 500 * (fx - fy);
- double b = 200 * (fy - fz);
- return new LabColor(L, a, b);
- }
- private static double Fxyz(double t)
- {
- const double delta = 6.0 / 29.0;
- const double delta3 = delta * delta * delta;
- return (t > delta3) ? Math.Pow(t, 1.0 / 3.0) : t / (3 * delta * delta) + 4.0 / 29.0;
- }
- // YXZ转换器 (假设YXZ是Y,X,Z顺序)
- public static LabColor YxzToLab(this YXZColor yxz)
- {
- // 转换为标准XYZ顺序
- return ToLab(new XYZColor(yxz.X, yxz.Y, yxz.Z));
- }
- }
|