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

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

編輯:關於.NET

6.透明,半透明和不透明

這是個大題目。在WinForm/WPF裡面我們經常會看到一些關於透明的屬性,比如Backcolor 裡面可以選擇Transparant, Form裡面有一個叫Opacity的屬性。都是和透明以及透明度相關 的。在其實是在GDI+應用層上的一些東西,在這裡我就不講了。主要從更基本的地方講起, 其中還包括兩塊完全不同的內容。

6.1 Alpha

我們在上一講中提到了PixelFormat,當時我們在LockBits的時候把PixelFormat設定成為 Format24bppRgb。但是如果你仔細研究,會發現其實裡面有各種各樣的圖片格式,其中有一 種叫做Format32bppArgb。這個意思是說除了RGB,在圖像中還存在一個通道,叫做A。這個A 就是用來描述當前像素是透明,半透明,還是全透明的分量。這個通道是2個叫Catmull和 Smith在上世紀70年代初發明的。通過這個分量,我們可以進行alpha混合的一些計算。從而 使表面的圖像和背景圖像混合,從而造成透明半透明的效果。在這種格式下A作為一個byte, 取值可以從0到255,那麼0表示圖像完全透明,則完全不可見,255則表示圖像完全不透明。 每個像素都可以實現這種透明或者半透明的效果。更詳細解釋可以參考 http://en.wikipedia.org/wiki/Alpha_compositing,或者去買本數字圖像處理的書回來看 。讓我們來看看下面這段代碼,這個函數可以把圖像變成半透明的。

1         public unsafe Bitmap GenerateBitmap(byte alpha)
2          {
3             FileStream fs = new FileStream (image, FileMode.Open, FileAccess.Read);
4             Image img = Image.FromStream(fs, false, false);
5             Bitmap bmp = new Bitmap(img);
6             img.Dispose();
7              fs.Close();
8
9             int width = bmp.Width;
10              int height = bmp.Height;
11
12              BitmapData bmData = bmp.LockBits(
13                 new Rectangle(0, 0, width, height),
14                 ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
15
16              byte* p = (byte*)bmData.Scan0;
17             int offset = bmData.Stride - width * 4;
18             for (int j = 0; j < height; j++)
19             {
20                  for (int i = 0; i < width; i++)
21                 {
22                     p[3] = alpha;
23                      p += 4;
24                 }
25                  p += offset;
26             }
27
28             bmp.UnlockBits(bmData);
29             
30             return bmp;
31         }
32

大家可以注意一下第17,22和23行,由於圖像格式不對了,所以我們計算offset和遞加的 操作都該了,此外由於用小數端存儲方式,Alpha通道在p[3]的位置。

順便提一句,還有一種格式叫做Format32bppPArgb,這叫做premultiplied alpha,就是 說在RGB分量裡面,alpha分量的數據已經被預先乘進去了。比如說,一個半透明的紅色點, 在ARGB下,矢量是(255,0,0,128),而在PARGB下就變成了(128,0,0,128)。這是為了不要每次 都做乘法。

還有要注意的是,如果你想把這個Bitmap保存成為一個文件,那麼必須用png格式,才能 夠保存alpha通道的信息。如果你存為JPG/BMP/GIF,那麼alpha通道的信息將會被丟失。如果 存為BMP,那麼文件格式將變成Format32bppRgb,其中1個字節不再使用;如果保存為JPEG,那 麼是Format24bppRgb;存為GIF,格式將變成Format8bppIndexed。根據標准,BMP/JPG本來就 不支持透明通道,所以沒有可能保留透明信息。GIF倒是支持透明,但是GIF中顏色的信息都 是索引,所以Alpha的解釋對GIF完全沒有效果,接下去我們來分析怎麼樣使用GIF的透明。

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