RGB顏色,就是用紅、綠、藍三個分量組成的顏色,.Net中用Color類來表示,HSL顏色,就是用色調(Hue)、飽和度(Saturation)、亮度(Lightness)來描繪一個顏色,這兩種顏色的介紹網上很多,我就不具體介紹了。RGB顏色和HSL顏色的轉化時有固定公式的,大家可以參考WIKI上的介紹(HSL and HSV),下面來介紹一下HSLColor類,它主要實現以下功能,RGB顏色跟HSL顏色的相互轉換,傳入一個RGB顏色,我們可以得到這個顏色的色調(Hue)、飽和度(Saturation)、亮度(Lightness),我們可以調節這3個量,得到一個新的顏色,利用這個類,通過調節圖片的每個像素的顏色,就可以得到不同效果的圖片了。來看看HSLColor類的詳細源碼:
1 ///<summary>在項目中,為了演示用HSL顏色調節圖片效果,還實現了一個HSLModifier類,這個類的功能就是利用HSLColor類,可以對圖片的色調、飽和度和亮度進行調節,需要注意的是,為了提高圖片調節的效率,在實現中使用了指針,所以在編譯的時候需要選擇允許不安全代碼。看看HSLModifIEr類的詳細源碼:
2 /// RGB 與 HSL 顏色的相互轉換。
3 /// 轉換算法參考:
4 ///http://en.wikipedia.org/wiki/HSL_color_space。
5 ///</summary>
6 publicclass HSLColor
7 {
8 privateint _alpha =255;
9 privateint _hue =0;
10 privatedouble _saturation = 1d;
11 privatedouble _lightness = 1d;
12
13 public HSLColor()
14 {
15 }
16
17 ///<summary>
18 /// 用一個RGB顏色構造HSLColor。
19 ///</summary>
20 ///<param name="color"></param>
21 public HSLColor(Color color)
22 {
23 _alpha = color.A;
24 FromRGB(color);
25 }
26
27 ///<summary>
28 /// 用色彩、飽和度、亮度構造HSLColor。
29 ///</summary>
30 ///<param name="hue">色彩。</param>
31 ///<param name="saturation">飽和度。</param>
32 ///<param name="lightness">亮度。</param>
33 public HSLColor(
34 int hue,
35 double saturation,
36 double lightness)
37 {
38 Hue = hue;
39 Saturation = saturation;
40 Lightness = lightness;
41 }
42
43 publicint Hue
44 {
45 get { return _hue; }
46 set
47 {
48 if (value <0)
49 {
50 _hue = value +360;
51 }
52 elseif (_hue >360)
53 {
54 _hue = value %360;
55 }
56 else
57 {
58 _hue = value;
59 }
60 }
61 }
62
63 publicdouble Saturation
64 {
65 get { return _saturation; }
66 set
67 {
68 if (_saturation <0)
69 {
70 _saturation =0;
71 }
72 else
73 {
74 _saturation = Math.Min(value, 1d);
75 }
76 }
77 }
78
79 publicdouble Lightness
80 {
81 get { return _lightness; }
82 set
83 {
84 if (_lightness <0)
85 {
86 _lightness =0;
87 }
88 else
89 {
90 _lightness = Math.Min(value, 1d);
91 }
92 }
93 }
94
95 public Color Color
96 {
97 get { return ToRGB(); }
98 set { FromRGB(value); }
99 }
100
101 publicstaticboolOperator==(HSLColor left, HSLColor right)
102 {
103 return (left.Hue == right.Hue &&
104 left.Lightness == right.Lightness &&
105 left.Saturation == right.Saturation);
106 }
107
108 publicstaticboolOperator!=(HSLColor left, HSLColor right)
109 {
110 return!(left == right);
111 }
112
113 publicoverridebool Equals(object obj)
114 {
115 if (obj ==null&&!(obj is HSLColor))
116 {
117 returnfalse;
118 }
119
120 HSLColor color = (HSLColor)obj;
121 returnthis== color;
122 }
123
124 publicoverrideint GetHashCode()
125 {
126 return Color.GetHashCode();
127 }
128
129 publicoverridestring ToString()
130 {
131 returnstring.Format(
132 "HSL({0:f2}, {1:f2}, {2:f2})",
133 Hue, Saturation, Lightness);
134 }
135
136 privatevoid FromRGB(Color color)
137 {
138 double r = ((double)color.R) /255;
139 double g = ((double)color.G) /255;
140 double b = ((double)color.B) /255;
141
142 double min = Math.Min(Math.Min(r, g), b);
143 double max = Math.Max(Math.Max(r, g), b);
144 double distance = max - min;
145
146 _lightness = (max + min) /2;
147 if (distance ==0)
148 {
149 _hue =0;
150 _saturation =0;
151 }
152 else
153 {
154 double hueTmp;
155 _saturation =
156 (_lightness <0.5) ?
157 (distance / (max + min)) : (distance / ((2- max) - min));
158 double tempR = (((max - r) /6) + (distance /2)) / distance;
159 double tempG = (((max - g) /6) + (distance /2)) / distance;
160 double tempB = (((max - b) /6) + (distance /2)) / distance;
161 if (r == max)
162 {
163 hueTmp = tempB - tempG;
164 }
165 elseif (g == max)
166 {
167 hueTmp = (0.33333333333333331+ tempR) - tempB;
168 }
169 else
170 {
171 hueTmp = (0.66666666666666663+ tempG) - tempR;
172 }
173 if (hueTmp <0)
174 {
175 hueTmp +=1;
176 }
177 if (hueTmp >1)
178 {
179 hueTmp -=1;
180 }
181 _hue = (int)(hueTmp *360);
182 }
183 }
184
185 private Color ToRGB()
186 {
187 byte r;
188 byte g;
189 byte b;
190
191 if (_saturation ==0)
192 {
193 r = (byte)(_lightness *255);
194 g = r;
195 b = r;
196 }
197 else
198 {
199 double vH = ((double)_hue) /360;
200 double v2 =
201 (_lightness <0.5) ?
202 (_lightness * (1+ _saturation)) :
203 ((_lightness + _saturation) - (_lightness * _saturation));
204 double v1 = (2* _lightness) - v2;
205 r = (byte)(255* HueToRGB(v1, v2, vH +0.33333333333333331));
206 g = (byte)(255* HueToRGB(v1, v2, vH));
207 b = (byte)(255* HueToRGB(v1, v2, vH -0.33333333333333331));
208 }
209 return Color.FromArgb(r, g, b);
210 }
211
212 privatedouble HueToRGB(double v1, double v2, double vH)
213 {
214 if (vH <0)
215 {
216 vH +=1;
217 }
218 if (vH >1)
219 {
220 vH -=1;
221 }
222 if ((6* vH) <1)
223 {
224 return v1 + (((v2 - v1) *6) * vH);
225 }
226 if ((2* vH) <1)
227 {
228 return v2;
229 }
230 if ((3* vH) <2)
231 {
232 return v1 + (((v2 - v1) * (0.66666666666666663- vH)) *6);
233 }
234 return v1;
235 }
236 }
1 publicclass HSLModifIEr : FilterColorToColor最後來看看例子的效果:
2 {
3 privateint _hue;
4 privatedouble _saturation;
5 privatedouble _lightness;
6
7 public HSLModifIEr()
8 {
9 }
10
11 public HSLModifIEr(
12 int hue,
13 double saturation,
14 double lightness)
15 {
16 Hue = hue;
17 Saturation = saturation;
18 Lightness = lightness;
19 }
20
21 publicint Hue
22 {
23 get { return _hue; }
24 set
25 {
26 _hue = Math.Max(0, Math.Min(value, 360));
27 }
28 }
29
30 publicdouble Saturation
31 {
32 get { return _saturation; }
33 set
34 {
35 _saturation = Math.Max(-1, Math.Min(value, 1));
36 }
37 }
38
39 publicdouble Lightness
40 {
41 get { return _lightness; }
42 set
43 {
44 _lightness = Math.Max(-1, Math.Min(value, 1));
45 }
46 }
47
48 protectedoverrideunsafevoid ProcessFilter(BitmapData imageData)
49 {
50 int width = imageData.Width;
51 int height = imageData.Height;
52 int perPixelLength =base.GetPerPixelFormatLength(
53 imageData.PixelFormat);
54 int offset = imageData.Stride - (width * perPixelLength);
55 Color rgb;
56 HSLColor hsl =new HSLColor();
57
58 byte* csan0 = (byte*)imageData.Scan0.ToPointer();
59
60 for (int i =0; i < height; i++)
61 {
62 int widthOffset =0;
63 while (widthOffset < width)
64 {
65 rgb = Color.FromArgb(csan0[2], csan0[1], csan0[0]);
66 hsl.Color = rgb;
67
68 hsl.Hue += _hue;
69 hsl.Saturation += _saturation;
70 hsl.Lightness += _lightness;
71
72 rgb = hsl.Color;
73
74 csan0[2] = rgb.R;
75 csan0[1] = rgb.G;
76 csan0[0] = rgb.B;
77
78 widthOffset++;
79 csan0 += perPixelLength;
80 }
81 csan0 += offset;
82 }
83 }
84 }
(1)圖像調節前
(2)圖像調節後