程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> 關於.NET >> GDI+中常見的幾個問題(6)

GDI+中常見的幾個問題(6)

編輯:關於.NET

6.2 GIF

GIF的全稱是圖像交換格式Graphics Interchange Format,是CompuServe公司在1987年創 建並使用的。這種格式使用8位索引值來表達一個像素,也就是說1個像素1個byte,最多可以 表示256種顏色。它使用LZW無損壓縮算法來對圖像進行壓縮,之後這家公司又和幾家其他的 公司發明了PNG文件格式,並被更廣泛地應用在Web以及其他領域。GIF支持動畫,可以保存數 個幀並不斷地播放。關於動畫的部分我們將會放到非常後面來講,現在只談談GIF的透明。

在GIF文件的頭部有一個調色板Palette,裡面保存了顏色的信息。一般而言,如果對GIF 進行LockBits的操作,只能把它lock成Format*bppIndexed,這樣才不會導致前面調色板信息 的丟失,在處理上也更方便一些。在調色板裡面定義了透明的顏色,也就是說當實際數據為 這個顏色時,那個位置的顏色為透明。讓我們來看看Palette是怎麼使用的。 順便再說一句 ,GIF沒有半透明,只支持完全透明或者不透明。此外,在一個調色板中,只有一種顏色可以 設置為透明,這是GIF標准所決定的。

1         public static unsafe void ConvertTransparancyGif(int colorIndex, string baseFile, string outputFile)
2         {
3              using (FileStream fs = new FileStream(baseFile, FileMode.Open, FileAccess.Read))
4             {
5                  Bitmap img = (Bitmap)Image.FromStream(fs, false, false);
6                  int width = img.Width;
7                 int height = img.Height;
8
9                 Bitmap resultbmp = new Bitmap(width, height, PixelFormat.Format8bppIndexed);
10                  ColorPalette palette = resultbmp.Palette;
11                  int n = 0;
12                 foreach (Color tc in img.Palette.Entries)
13                 {
14                     palette.Entries[n] = Color.FromArgb(255, tc);
15                     n++;
16                  }
17
18                 palette.Entries[colorIndex] = Color.FromArgb(0, palette.Entries [colorIndex]);
19                 resultbmp.Palette = palette;
20
21                 //now to copy the actual bitmap data
22                 BitmapData src = img.LockBits (
23                     new Rectangle(0, 0, width, height),
24                     ImageLockMode.ReadOnly,
25                     img.PixelFormat);
26
27                 BitmapData dst = resultbmp.LockBits(
28                     new Rectangle (0, 0, width, height),
29                     ImageLockMode.WriteOnly,
30                     resultbmp.PixelFormat);
31
32                 byte* pSrc = (byte*)src.Scan0.ToPointer();
33                 byte* pDst = (byte*)dst.Scan0.ToPointer();
34                 int offset = src.Stride - width;
35
36                 //steps through each pixel
37                 for (int y = 0; y < height; y++)
38                 {
39                      for (int x = 0; x < width; x++)
40                      {
41                         pDst[0] = pSrc[0];
42                         pDst++;
43                          pSrc++;
44                      }
45                     pDst += offset;
46                     pSrc += offset;
47                  }
48
49                 //unlock the bitmaps
50                 img.UnlockBits(src);
51                  resultbmp.UnlockBits(dst);
52
53                  resultbmp.Save(outputFile, ImageFormat.Gif);
54
55                  img.Dispose();
56                 resultbmp.Dispose();
57             }
59         }

請注意,在這裡,我讀圖的時候和我之前推薦的方法不同。 我沒有創建一個新的Bitmap ,這是因為在創建新的Bitmap的時候,調色板信息會完全丟失,所以Indexed的格式不可以隨 意進行復制,否則將造成信息的丟失。這也就是為什麼當時我說這是一個土辦法的原因。真 正的好辦法是復制那個流,而不是直接去復制Bitmap。不過那是看需求的。在創建一個帶透 明顏色的GIF的時候,只要創建一個調色板,就一切OK了。這比Alpha通道修正要簡單。還可 以參考KB 319061 http://support.microsoft.com/kb/319061/en-us

最後提一句,Bitmap類還提供了一個MakeTransparent方法用於設置透明顏色,不過只對 PNG有效。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved