原文出处
http://blog.csdn.net/ncjmc/archive/2006/08/28/1132879.aspx
以前在用C#做网站保存缩略图的程序中发现,当保存为GIF文件类型时,原来的透明背景变成了黑色,当时由于赶时间,就统一用白色代替了背景,并用Jpeg格式存储,并没有深究。
近来在网上查阅了许多资料,看到了两种解决方法:一种是在显示时设置透明背景色,GIF文件本身并不改变,另一种是不推荐使用的调用API的方法。将后一种I的VB源码用C#重写后,发现其中的调色板设置太少,转换效果不理想。
重新到网上搜索关于调色板的资料,发现MSDN上的一篇《对 ASP.NET 图像的颜色量化(Quantization)进行优化》的文章。
http://www.microsoft.com/china/MSDN/library/archives/library/DNAspp/html/colorquant.asp
将其中基于调色板量化的代码分离出来,透明背景色的图片保存成功。
完整代码如下:
1public class GifPalette
2 {
3 private static ArrayList _cardPalette;
4 private Color[] _colors;
5 private Hashtable _colorMap;
6
7 public GifPalette(ArrayList palette)
8 {
9 _colorMap = new Hashtable();
10 _colors = new Color[palette.Count];
11 palette.CopyTo(_colors);
12 }
13
14 public GifPalette()
15 {
16 ArrayList palette = SetPalette();
17 _colorMap = new Hashtable();
18 _colors = new Color[palette.Count];
19 palette.CopyTo(_colors);
20 }
21
22 public Bitmap Quantize(Image source)
23 {
24 int height = source.Height;
25 int width = source.Width;
26
27 Rectangle bounds = new Rectangle(0, 0, width, height);
28
29 Bitmap copy = new Bitmap(width, height, PixelFormat.Format32bppArgb);
30 Bitmap output = new Bitmap(width, height, PixelFormat.Format8bppIndexed);
31
32 using (Graphics g = Graphics.FromImage(copy))
33 {
34 g.PageUnit = GraphicsUnit.Pixel;
35
36 g.DrawImageUnscaled(source, bounds);
37 }
38
39 BitmapData sourceData = null;
40
41 try
42 {
43 sourceData = copy.LockBits(bounds, ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
44
45 output.Palette = this.GetPalette(output.Palette);
46
47 SecondPass(sourceData, output, width, height, bounds);
48 }
49 finally
50 {
51 copy.UnlockBits(sourceData);
52 }
53
54 return output;
55 }
56
57 private ColorPalette GetPalette(ColorPalette palette)
58 {
59 for (int index = 0; index < _colors.Length; index++)
60 palette.Entries[index] = _colors[index];
61 return palette;
62 }
63
64 private unsafe void SecondPass(BitmapData sourceData, Bitmap output, int width, int height, Rectangle bounds)
65 {
66 BitmapData outputData = null;
67
68 try
69 {
70 outputData = output.LockBits(bounds, ImageLockMode.WriteOnly, PixelFormat.Format8bppIndexed);
71
72 byte* pSourceRow = (byte*)sourceData.Scan0.ToPointer();
73 Int32* pSourcePixel = (Int32*)pSourceRow;
74 Int32* pPreviousPixel = pSourcePixel;
75
76 byte* pDestinationRow = (byte*)outputData.Scan0.ToPointer();
77 byte* pDestinationPixel = pDestinationRow;
78
79 byte pixelValue = QuantizePixel((Color32*)pSourcePixel);
80
81 *pDestinationPixel = pixelValue;
82
83 for (int row = 0; row < height; row++)
84 {
85 pSourcePixel = (Int32*)pSourceRow;
86
87 pDestinationPixel = pDestinationRow;
88
89 for (int col = 0; col < width; col++, pSourcePixel++, pDestinationPixel++)
90 {
91 if (*pPreviousPixel != *pSourcePixel)
92 {
93 pixelValue = QuantizePixel((Color32*)pSourcePixel);
94
95 pPreviousPixel = pSourcePixel;
96 }
97
98 *pDestinationPixel = pixelValue;
99 }
100
101 pSourceRow += sourceData.Stride;
102
103 pDestinationRow += outputData.Stride;
104 }
105 }
106 finally
107 {
108 output.UnlockBits(outputData);
109 }
110 }
111
112 private unsafe byte QuantizePixel(Color32* pixel)
113 {
114 byte colorIndex = 0;
115 int colorHash = pixel->ARGB;
116
117 if (_colorMap.ContainsKey(colorHash))
118 colorIndex = (byte)_colorMap[colorHash];
119 else
120 {
121 if (0 == pixel->Alpha)
122 {
123 for (int index = 0; index < _colors.Length; index++)
124 {
125 if (0 == _colors[index].A)
126 {
127 colorIndex = (byte)index;
128 break;
129 }
130 }
131 }
132 else
133 {
134 int leastDistance = int.MaxValue;
135 int red = pixel->Red;
136 int green = pixel->Green;
137 int blue = pixel->Blue;
138
139 for (int index = 0; index < _colors.Length; index++)
140 {
141 Color paletteColor = _colors[index];
142
143 int redDistance = paletteColor.R - red;
144 int greenDistance = paletteColor.G - green;
145 int blueDistance = paletteColor.B - blue;
146
147 int distance = (redDistance * redDistance) +
148 (greenDistance * greenDistance) +
149 (blueDistance * blueDistance);
150
151 if (distance < leastDistance)
152 {
153 colorIndex = (byte)index;
154 leastDistance = distance;
155
156 if (0 == distance)
157 break;
158 }
159 }
160 }
161
162 _colorMap.Add(colorHash, colorIndex);
163 }
164
165 return colorIndex;
166 }
167
168 [StructLayout(LayoutKind.Explicit)]
169 public struct Color32
170 {
171 [FieldOffset(0)]
172 public byte Blue;
173
174 [FieldOffset(1)]
175 public byte Green;
176
177 [FieldOffset(2)]
178 public byte Red;
179
180 [FieldOffset(3)]
181 public byte Alpha;
182
183 [FieldOffset(0)]
184 public int ARGB;
185
186 public Color Color
187 {
188 get { return Color.FromArgb(Alpha, Red, Green, Blue); }
189 }
190 }
191
192 public static ArrayList SetPalette()
193 {
194 if (null == _cardPalette)
195 {
196 _cardPalette = new ArrayList();
197
198 //Insert the colors into the arraylist
199 Insert the colors into the arraylist#region Insert the colors into the arraylist
200 _cardPalette.Add(Color.FromArgb(255, 0, 0, 0));
201 _cardPalette.Add(Color.FromArgb(255, 128, 0, 0));
202 _cardPalette.Add(Color.FromArgb(255, 0, 128, 0));
203 _cardPalette.Add(Color.FromArgb(255, 128, 128, 0));
204 _cardPalette.Add(Color.FromArgb(255, 0, 0, 128));
205 _cardPalette.Add(Color.FromArgb(255, 128, 0, 128));
206 _cardPalette.Add(Color.FromArgb(255, 0, 128, 128));
207 _cardPalette.Add(Color.FromArgb(255, 192, 192, 192));
208 _cardPalette.Add(Color.FromArgb(255, 192, 220, 192));
209 _cardPalette.Add(Color.FromArgb(255, 166, 202, 240));
210 _cardPalette.Add(Color.FromArgb(255, 1, 25, 83));
211 _cardPalette.Add(Color.FromArgb(255, 1, 37, 92));
212 _cardPalette.Add(Color.FromArgb(255, 2, 51, 103));
213 _cardPalette.Add(Color.FromArgb(255, 18, 66, 114));
214 _cardPalette.Add(Color.FromArgb(255, 39, 78, 123));
215 _cardPalette.Add(Color.FromArgb(255, 101, 63, 107));
216 _cardPalette.Add(Color.FromArgb(255, 72, 92, 119));
217 _cardPalette.Add(Color.FromArgb(255, 89, 74, 121));
218 _cardPalette.Add(Color.FromArgb(255, 85, 101, 122));
219 _cardPalette.Add(Color.FromArgb(255, 122, 89, 127));
220 _cardPalette.Add(Color.FromArgb(255, 101, 108, 106));
221 _cardPalette.Add(Color.FromArgb(255, 111, 116, 111));
222 _cardPalette.Add(Color.FromArgb(255, 109, 118, 122));
223 _cardPalette.Add(Color.FromArgb(255, 120, 119, 97));
224 _cardPalette.Add(Color.FromArgb(255, 121, 124, 114));
225 _cardPalette.Add(Color.FromArgb(255, 1, 52, 154));
226 _cardPalette.Add(Color.FromArgb(255, 16, 61, 156));
227 _cardPalette.Add(Color.FromArgb(255, 15, 63, 160));
228 _cardPalette.Add(Color.FromArgb(255, 37, 55, 131));
229 _cardPalette.Add(Color.FromArgb(255, 24, 69, 158));
230 _cardPalette.Add(Color.FromArgb(255, 21, 68, 162));
231 _cardPalette.Add(Color.FromArgb(255, 35, 71, 137));
232 _cardPalette.Add(Color.FromArgb(255, 33, 71, 152));
233 _cardPalette.Add(Color.FromArgb(255, 43, 93, 130));
234 _cardPalette.Add(Color.FromArgb(255, 51, 68, 139));
235 _cardPalette.Add(Color.FromArgb(255, 48, 79, 159));
236 _cardPalette.Add(Color.FromArgb(255, 53, 85, 131));
237 _cardPalette.Add(Color.FromArgb(255, 49, 81, 151));
238 _cardPalette.Add(Color.FromArgb(255, 34, 78, 167));
239 _cardPalette.Add(Color.FromArgb(255, 41, 84, 170));
240 _cardPalette.Add(Color.FromArgb(255, 50, 91, 173));
241 _cardPalette.Add(Color.FromArgb(255, 54, 94, 176));
242 _cardPalette.Add(Color.FromArgb(255, 53, 101, 136));
243 _cardPalette.Add(Color.FromArgb(255, 60, 97, 168));
244 _cardPalette.Add(Color.FromArgb(255, 59, 99, 177));
245 _cardPalette.Add(Color.FromArgb(255, 68, 93, 134));
246 _cardPalette.Add(Color.FromArgb(255, 67, 91, 150));
247 _cardPalette.Add(Color.FromArgb(255, 86, 93, 151));
248 _cardPalette.Add(Color.FromArgb(255, 64, 102, 142));
249 _cardPalette.Add(Color.FromArgb(255, 76, 105, 153));
250 _cardPalette.Add(Color.FromArgb(255, 75, 116, 150));
251 _cardPalette.Add(Color.FromArgb(255, 81, 103, 140));
252 _cardPalette.Add(Color.FromArgb(255, 84, 106, 147));
253 _cardPalette.Add(Color.FromArgb(255, 91, 113, 146));
254 _cardPalette.Add(Color.FromArgb(255, 75, 107, 172));
255 _cardPalette.Add(Color.FromArgb(255, 65, 103, 180));
256 _cardPalette.Add(Color.FromArgb(255, 77, 113, 184));
257 _cardPalette.Add(Color.FromArgb(255, 90, 104, 162));
258 _cardPalette.Add(Color.FromArgb(255, 90, 115, 160));
259 _cardPalette.Add(Color.FromArgb(255, 90, 123, 189));
260 _cardPalette.Add(Color.FromArgb(255, 101, 87, 130));
261 _cardPalette.Add(Color.FromArgb(255, 106, 108, 158));
262 _cardPalette.Add(Color.FromArgb(255, 101, 115, 130));
263 _cardPalette.Add(Color.FromArgb(255, 103, 121, 149));
264 _cardPalette.Add(Color.FromArgb(255, 112, 99, 139));
265 _cardPalette.Add(Color.FromArgb(255, 122, 110, 148));
266 _cardPalette.Add(Color.FromArgb(255, 101, 122, 165));
267 _cardPalette.Add(Color.FromArgb(255, 116, 124, 172));
268 _cardPalette.Add(Color.FromArgb(255, 93, 126, 192));
269 _cardPalette.Add(Color.FromArgb(255, 96, 127, 192));
270 _cardPalette.Add(Color.FromArgb(0, 72, 254, 42));
271 _cardPalette.Add(Color.FromArgb(255, 90, 128, 160));
272 _cardPalette.Add(Color.FromArgb(255, 97, 130, 159));
273 _cardPalette.Add(Color.FromArgb(255, 119, 129, 138));
274 _cardPalette.Add(Color.FromArgb(255, 118, 133, 154));
275 _cardPalette.Add(Color.FromArgb(255, 107, 131, 169));
276 _cardPalette.Add(Color.FromArgb(255, 105, 132, 186));
277 _cardPalette.Add(Color.FromArgb(255, 118, 138, 170));
278 _cardPalette.Add(Color.FromArgb(255, 117, 137, 180));
279 _cardPalette.Add(Color.FromArgb(255, 118, 145, 173));
280 _cardPalette.Add(Color.FromArgb(255, 124, 152, 183));
281 _cardPalette.Add(Color.FromArgb(255, 95, 128, 192));
282 _cardPalette.Add(Color.FromArgb(255, 102, 133, 195));
283 _cardPalette.Add(Color.FromArgb(255, 112, 141, 199));
284 _cardPalette.Add(Color.FromArgb(255, 120, 147, 202));
285 _cardPalette.Add(Color.FromArgb(255, 154, 53, 53));
286 _cardPalette.Add(Color.FromArgb(255, 131, 72, 91));
287 _cardPalette.Add(Color.FromArgb(255, 143, 87, 104));
288 _cardPalette.Add(Color.FromArgb(255, 129, 123, 92));
289 _cardPalette.Add(Color.FromArgb(255, 156, 124, 68));
290 _cardPalette.Add(Color.FromArgb(255, 129, 126, 101));
291 _cardPalette.Add(Color.FromArgb(255, 154, 105, 120));
292 _cardPalette.Add(Color.FromArgb(255, 169, 83, 82));
293 _cardPalette.Add(Color.FromArgb(255, 165, 125, 70));
294 _cardPalette.Add(Color.FromArgb(255, 160, 125, 80));
295 _cardPalette.Add(Color.FromArgb(255, 176, 109, 114));
296 _cardPalette.Add(Color.FromArgb(255, 205, 53, 2));
297 _cardPalette.Add(Color.FromArgb(255, 209, 67, 19));
298 _cardPalette.Add(Color.FromArgb(255, 210, 85, 47));
299 _cardPalette.Add(Color.FromArgb(255, 230, 67, 21));
300 _cardPalette.Add(Color.FromArgb(255, 243, 88, 46));
301 _cardPalette.Add(Color.FromArgb(255, 255, 97, 53));
302 _cardPalette.Add(Color.FromArgb(255, 201, 92, 71));
303 _cardPalette.Add(Color.FromArgb(255, 214, 107, 79));
304 _cardPalette.Add(Color.FromArgb(255, 205, 117, 105));
305 _cardPalette.Add(Color.FromArgb(255, 245, 112, 74));
306 _cardPalette.Add(Color.FromArgb(255, 131, 101, 136));
307 _cardPalette.Add(Color.FromArgb(255, 139, 110, 144));
308 _cardPalette.Add(Color.FromArgb(255, 130, 120, 156));
309 _cardPalette.Add(Color.FromArgb(255, 146, 124, 155));
310 _cardPalette.Add(Color.FromArgb(255, 162, 117, 131));
311 _cardPalette.Add(Color.FromArgb(255, 141, 133, 94));
312 _cardPalette.Add(Color.FromArgb(255, 156, 131, 72));
313 _cardPalette.Add(Color.FromArgb(255, 151, 133, 83));
314 _cardPalette.Add(Color.FromArgb(255, 157, 144, 92));
315 _cardPalette.Add(Color.FromArgb(255, 137, 132, 102));
316 _cardPalette.Add(Color.FromArgb(255, 135, 136, 120));
317 _cardPalette.Add(Color.FromArgb(255, 147, 139, 102));
318 _cardPalette.Add(Color.FromArgb(255, 148, 143, 115));
319 _cardPalette.Add(Color.FromArgb(255, 156, 146, 106));
320 _cardPalette.Add(Color.FromArgb(255, 148, 145, 122));
321 _cardPalette.Add(Color.FromArgb(255, 168, 136, 73));
322 _cardPalette.Add(Color.FromArgb(255, 168, 138, 88));
323 _cardPalette.Add(Color.FromArgb(255, 172, 147, 90));
324 _cardPalette.Add(Color.FromArgb(255, 178, 138, 82));
325 _cardPalette.Add(Color.FromArgb(255, 186, 153, 69));
326 _cardPalette.Add(Color.FromArgb(255, 179, 150, 91));
327 _cardPalette.Add(Color.FromArgb(255, 174, 139, 100));
328 _cardPalette.Add(Color.FromArgb(255, 166, 154, 107));
329 _cardPalette.Add(Color.FromArgb(255, 161, 151, 114));
330 _cardPalette.Add(Color.FromArgb(255, 182, 154, 101));
331 _cardPalette.Add(Color.FromArgb(255, 190, 162, 81));
332 _cardPalette.Add(Color.FromArgb(255, 172, 160, 117));
333 _cardPalette.Add(Color.FromArgb(255, 183, 161, 103));
334 _cardPalette.Add(Color.FromArgb(255, 182, 163, 119));
335 _cardPalette.Add(Color.FromArgb(255, 205, 168, 63));
336 _cardPalette.Add(Color.FromArgb(255, 218, 174, 52));
337 _cardPalette.Add(Color.FromArgb(255, 221, 177, 53));
338 _cardPalette.Add(Color.FromArgb(255, 255, 154, 1));
339 _cardPalette.Add(Color.FromArgb(255, 255, 161, 18));
340 _cardPalette.Add(Color.FromArgb(255, 235, 184, 44));
341 _cardPalette.Add(Color.FromArgb(255, 228, 182, 52));
342 _cardPalette.Add(Color.FromArgb(255, 247, 190, 36));
343 _cardPalette.Add(Color.FromArgb(255, 200, 155, 94));
344 _cardPalette.Add(Color.FromArgb(255, 192, 153, 104));
345 _cardPalette.Add(Color.FromArgb(255, 223, 130, 103));
346 _cardPalette.Add(Color.FromArgb(255, 215, 132, 118));
347 _cardPalette.Add(Color.FromArgb(255, 201, 167, 68));
348 _cardPalette.Add(Color.FromArgb(255, 196, 167, 87));
349 _cardPalette.Add(Color.FromArgb(255, 209, 173, 70));
350 _cardPalette.Add(Color.FromArgb(255, 212, 169, 91));
351 _cardPalette.Add(Color.FromArgb(255, 213, 177, 73));
352 _cardPalette.Add(Color.FromArgb(255, 198, 166, 102));
353 _cardPalette.Add(Color.FromArgb(255, 196, 168, 123));
354 _cardPalette.Add(Color.FromArgb(255, 219, 172, 112));
355 _cardPalette.Add(Color.FromArgb(255, 219, 183, 106));
356 _cardPalette.Add(Color.FromArgb(255, 217, 185, 115));
357 _cardPalette.Add(Color.FromArgb(255, 255, 131, 91));
358 _cardPalette.Add(Color.FromArgb(255, 249, 143, 109));
359 _cardPalette.Add(Color.FromArgb(255, 227, 186, 108));
360 _cardPalette.Add(Color.FromArgb(255, 229, 186, 112));
361 _cardPalette.Add(Color.FromArgb(255, 255, 164, 123));
362 _cardPalette.Add(Color.FromArgb(255, 207, 195, 127));
363 _cardPalette.Add(Color.FromArgb(255, 253, 204, 94));
364 _cardPalette.Add(Color.FromArgb(255, 235, 194, 108));
365 _cardPalette.Add(Color.FromArgb(255, 233, 197, 117));
366 _cardPalette.Add(Color.FromArgb(255, 252, 204, 104));
367 _cardPalette.Add(Color.FromArgb(255, 249, 204, 115));
368 _cardPalette.Add(Color.FromArgb(255, 251, 208, 106));
369 _cardPalette.Add(Color.FromArgb(255, 253, 209, 117));
370 _cardPalette.Add(Color.FromArgb(255, 128, 137, 140));
371 _cardPalette.Add(Color.FromArgb(255, 136, 144, 145));
372 _cardPalette.Add(Color.FromArgb(255, 151, 150, 130));
373 _cardPalette.Add(Color.FromArgb(255, 144, 149, 148));
374 _cardPalette.Add(Color.FromArgb(255, 137, 131, 165));
375 _cardPalette.Add(Color.FromArgb(255, 137, 140, 180));
376 _cardPalette.Add(Color.FromArgb(255, 140, 154, 168));
377 _cardPalette.Add(Color.FromArgb(255, 133, 151, 180));
378 _cardPalette.Add(Color.FromArgb(255, 149, 137, 167));
379 _cardPalette.Add(Color.FromArgb(255, 149, 152, 188));
380 _cardPalette.Add(Color.FromArgb(255, 138, 168, 188));
381 _cardPalette.Add(Color.FromArgb(255, 175, 135, 148));
382 _cardPalette.Add(Color.FromArgb(255, 169, 154, 129));
383 _cardPalette.Add(Color.FromArgb(255, 187, 135, 134));
384 _cardPalette.Add(Color.FromArgb(255, 178, 138, 148));
385 _cardPalette.Add(Color.FromArgb(255, 184, 146, 156));
386 _cardPalette.Add(Color.FromArgb(255, 168, 149, 173));
387 _cardPalette.Add(Color.FromArgb(255, 170, 163, 131));
388 _cardPalette.Add(Color.FromArgb(255, 184, 165, 128));
389 _cardPalette.Add(Color.FromArgb(255, 181, 166, 157));
390 _cardPalette.Add(Color.FromArgb(255, 162, 175, 186));
391 _cardPalette.Add(Color.FromArgb(255, 189, 185, 170));
392 _cardPalette.Add(Color.FromArgb(255, 130, 155, 206));
393 _cardPalette.Add(Color.FromArgb(255, 134, 158, 208));
394 _cardPalette.Add(Color.FromArgb(255, 146, 155, 196));
395 _cardPalette.Add(Color.FromArgb(255, 142, 169, 193));
396 _cardPalette.Add(Color.FromArgb(255, 140, 163, 209));
397 _cardPalette.Add(Color.FromArgb(255, 153, 168, 199));
398 _cardPalette.Add(Color.FromArgb(255, 148, 170, 213));
399 _cardPalette.Add(Color.FromArgb(255, 157, 177, 216));
400 _cardPalette.Add(Color.FromArgb(255, 164, 166, 193));
401 _cardPalette.Add(Color.FromArgb(255, 171, 179, 198));
402 _cardPalette.Add(Color.FromArgb(255, 167, 185, 220));
403 _cardPalette.Add(Color.FromArgb(255, 181, 179, 205));
404 _cardPalette.Add(Color.FromArgb(255, 181, 188, 211));
405 _cardPalette.Add(Color.FromArgb(255, 173, 190, 224));
406 _cardPalette.Add(Color.FromArgb(255, 178, 196, 217));
407 _cardPalette.Add(Color.FromArgb(255, 174, 192, 224));
408 _cardPalette.Add(Color.FromArgb(255, 174, 212, 224));
409 _cardPalette.Add(Color.FromArgb(255, 184, 198, 227));
410 _cardPalette.Add(Color.FromArgb(255, 185, 218, 229));
411 _cardPalette.Add(Color.FromArgb(255, 202, 145, 142));
412 _cardPalette.Add(Color.FromArgb(255, 196, 172, 134));
413 _cardPalette.Add(Color.FromArgb(255, 203, 161, 158));
414 _cardPalette.Add(Color.FromArgb(255, 203, 177, 134));
415 _cardPalette.Add(Color.FromArgb(255, 207, 185, 151));
416 _cardPalette.Add(Color.FromArgb(255, 210, 186, 132));
417 _cardPalette.Add(Color.FromArgb(255, 215, 189, 148));
418 _cardPalette.Add(Color.FromArgb(255, 213, 168, 167));
419 _cardPalette.Add(Color.FromArgb(255, 234, 155, 132));
420 _cardPalette.Add(Color.FromArgb(255, 253, 172, 140));
421 _cardPalette.Add(Color.FromArgb(255, 193, 191, 193));
422 _cardPalette.Add(Color.FromArgb(255, 206, 194, 135));
423 _cardPalette.Add(Color.FromArgb(255, 214, 198, 136));
424 _cardPalette.Add(Color.FromArgb(255, 219, 204, 145));
425 _cardPalette.Add(Color.FromArgb(255, 218, 209, 141));
426 _cardPalette.Add(Color.FromArgb(255, 215, 209, 154));
427 _cardPalette.Add(Color.FromArgb(255, 231, 196, 135));
428 _cardPalette.Add(Color.FromArgb(255, 225, 213, 143));
429 _cardPalette.Add(Color.FromArgb(255, 231, 217, 148));
430 _cardPalette.Add(Color.FromArgb(255, 251, 212, 129));
431 _cardPalette.Add(Color.FromArgb(255, 255, 199, 172));
432 _cardPalette.Add(Color.FromArgb(255, 202, 205, 219));
433 _cardPalette.Add(Color.FromArgb(255, 193, 205, 230));
434 _cardPalette.Add(Color.FromArgb(255, 200, 211, 233));
435 _cardPalette.Add(Color.FromArgb(255, 211, 220, 237));
436 _cardPalette.Add(Color.FromArgb(255, 213, 222, 240));
437 _cardPalette.Add(Color.FromArgb(255, 201, 226, 228));
438 _cardPalette.Add(Color.FromArgb(255, 201, 231, 242));
439 _cardPalette.Add(Color.FromArgb(255, 216, 227, 232));
440 _cardPalette.Add(Color.FromArgb(255, 219, 227, 241));
441 _cardPalette.Add(Color.FromArgb(255, 228, 233, 237));
442 _cardPalette.Add(Color.FromArgb(255, 229, 234, 244));
443 _cardPalette.Add(Color.FromArgb(255, 236, 241, 248));
444 _cardPalette.Add(Color.FromArgb(255, 240, 239, 243));
445 _cardPalette.Add(Color.FromArgb(255, 253, 253, 254));
446 _cardPalette.Add(Color.FromArgb(255, 255, 251, 240));
447 _cardPalette.Add(Color.FromArgb(255, 160, 160, 164));
448 _cardPalette.Add(Color.FromArgb(255, 128, 128, 128));
449 _cardPalette.Add(Color.FromArgb(255, 255, 0, 0));
450 _cardPalette.Add(Color.FromArgb(255, 0, 255, 0));
451 _cardPalette.Add(Color.FromArgb(255, 255, 255, 0));
452 _cardPalette.Add(Color.FromArgb(255, 0, 0, 255));
453 _cardPalette.Add(Color.FromArgb(255, 255, 0, 255));
454 _cardPalette.Add(Color.FromArgb(255, 0, 255, 255));
455 _cardPalette.Add(Color.FromArgb(255, 255, 255, 255));
456 #endregion
457 }
458 return _cardPalette;
459 }
460
461
462 }
调用方法:
先将该类添加到项目中,再在合适的地方调用。例:
Bitmap bitmap = new System.Drawing.Bitmap(width, height); // Image类也可
// ......(图形操作代码)
WindwoodGif.GifPalette gifPalette = new WindwoodGif.GifPalette();
bitmap = gifPalette.Quantize(bitmap);
bitmap.Save(SaveFileName, ImageFormat.Gif);
经测试,这种方法能够实现GIF文件的透明背景存储,在WinForm、WebForm均能使用。由于使用了标准256色调色板,内存开销可能较大,转换时间相对较慢,图像质量也有一定影响。此外,代码中使用了非安全代码(指针),在编译时项目属性中要设置允许不安全代码。