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