摘要:利用操作系統的GDI API來制作透明圖像,通過這個功能可以達到多張圖片的色彩混合,能實現較高級系統中的類似接口的功能。
關鍵詞:位圖;像素;分辨率;顏色通道;RGB
中圖分類號:TP312文獻標識碼:A文章編號:1009-3044(2009)27-7734-02
The Research and Application Based on VC++6.0
MEI Yuan-zhao
(Zunyi Vocational and Technical College, Zunyi 563000, China)
Abstract: GDI API to use the operating system to create transparent images, this feature can be achieved through multiple pictures of the color mixing, to achieve higher system interface similar functions.
Key words: bit map; pixel; resolution; color channel; RGB
制作透明位圖并不容易,一般的方法是取出位圖的各個像素點,將各個像素點的RGB值乘以透明度百分比,然后將它放到一個數組中,再取出背景圖與位圖重疊部分的像素點,將各點的RGB值乘以透明度百分比。存入另一個數組中,將兩個數組相加,得到色彩值。
獲得目標和源的像素位,計算出最終的該位置的圖像色彩,這種方式是大多數圖形處理軟件處理的方法,通過對它的了解可以掌握常見的圖像處理方法。
1 主要基礎技術知識
1.1位圖基礎
位圖就是存貯于電腦中的圖片。位圖文件有常見格式有.BMP、.JPG、.GIF、.PIC等,但Windows僅支持Windows Bitmap Graphics格式,即BMP文件。
1.1.1 位圖
位圖(Bitmap):位圖圖形也稱為光柵圖形,由排列為矩形網格形式的小方塊(像素)組成。簡單地說,位圖就是以無數的色彩點組成的圖案。
位圖圖像用圖像的寬度和高度來定義,以像素為量度單位,每個像素包含的位數表示像素包含的顏色數。在使用RGB顏色模型的位圖圖像中,像素由三個字節組成:紅、綠和藍。每個字節包含一個0至255之間的值。將字節與像素合并時,它們可以產生與藝術混合繪畫顏色相似的顏色。
位圖圖像的品質由圖像分辨率和顏色深度位值共同確定。分辨率與圖像中包含的像素數有關。像素數越大,分辨率越高,圖像也就越精確。顏色深度又叫色彩位數,與像素可包含的信息量有關。即位圖中要用多少個二進制位來表示每個點的顏色,是分辨率的一個重要指標。常用有1位(單色),2位(4色,CGA),4位(16色,VGA),8位(256色),16位(增強色),24位和32位(真彩色)等。因此,色深高的位圖像與色深低度的位圖像相比,其陰影具有更高的平滑度。由于位圖圖形跟分辨率有關,因此不能很好地進行縮放。
1.1.2重要術語及概念
顏色通道:通常,將顏色表示為幾種基本顏色的混合顏色,通常是紅色、綠色和藍色。每種基本顏色都視為一個顏色通道;每個顏色通道中的顏色量混合在一起可確定最終顏色。
顏色深度:也稱為“位深度”,指專門用于每個像素的計算機內存量,因而可以確定圖像中可以顯示的可能顏色數。
像素:位圖圖像中的最小信息單位,實際上就是顏色點。
分辨率:圖像的像素尺寸,它決定圖像中包含的精細細節的級別。分辨率通常表示為用像素數表示的寬度和高度。
RGB 顏色:一種配色方案,其中每個像素的顏色均表示為紅、綠和藍色值的混合顏色。
1.2 位圖顯示
計算機中使用的位圖最終是BMP文件。使用位圖最簡單的方法就是把它定義在資源文件(.rc)中。定義的方法有兩種。一種方法是把它定義為整數宏,具體如下:
#define IDB_MYBITMAP 100
IDB_MYBITMAP BITMAP \"c:\\project\\example.bmp\"
另一種方法是給它起一個名字,也就是把它定義為字符串,具體如下:
MyBitMap BITMAP \"c:\\project\\example.bmp\"
兩種方法效果是一樣的。
接著就是把它顯示在窗口的客戶區上。使用API函數LoadBitmap取得位圖句柄,下面是LoadBitmap函數的完型:
HBITMAPLoadBitmap(HINSTANCE hInstance,LPSTR lpBitmapName)
該函數返回一個位圖句柄。函數有兩個參數,其中hInstance 是程序句柄。lpBitmapName是位圖名字的指針(適用于第二種定義方法)。如果你使用了第一種定義方法,你可以填入指向位圖的值或整數宏(對應上例這個值就是100,整數宏是IDB_MYBITMAP)。
如果在其它消息中則可以用API函數GetDC獲得。創建這個DC的內存映像。這樣做的目的是建立一張“隱藏的畫紙”,把位圖“畫”在上面,作緩沖之用。完成這項工作后,我們就通過一個函數把“畫紙”上的位圖復制到真正的DC中。這就是在屏幕上快速顯示圖象的雙緩沖技術。這張“畫紙”用API函數 CreateCompatibleDC 建立,下面是它的完型:
HDCCreateCompatibleDC(HDC hdc)
如果函數執行成功,將返回DC內存映像即“畫紙”的句柄。
現在我們已經有了“畫紙”,可以把位圖畫在上面了。這可以通過API函數SelectObject完成,其中第一個參數是“畫紙”的句柄,第二個參數則是位圖的句柄,下面是函數的完型:
HGDIOBJ WINAPI SelectObject(HDC, HGDIOBJ)
現在位圖已經畫在“畫紙”上了。下一步我們要把位圖復制到真正的DC中。
有很多API函數都能完成這項工作,例如BitBlt和StretchBlt。函數BitBlt僅僅將一個DC的內容簡單地復制到另一個DC中,而函數 StretchBlt 則能夠自動調整源DC復制內容的大小已適應目的DC的輸出區域大小,因此前者比后者速度更快。
在這里我們只使用函數 BitBlt,下面是它的完型:
BOOL BitBlt( int x, int y, int nWidth, int nHeight,
CDC* pSrcDC, int xSrc, int ySrc, DWORD dwRop );
x,y表示矩形的左上角的坐標
nwidth,nheight是表示矩形圖的寬和高
pSrcDC是設備上下文的指針
xSrc,ySrc是位圖的坐標
dwROP 屏面運算碼(ROP)。該參數用以確定復制內容的顏色與輸出區域原來的顏色按哪種運算方式處理。通常,只需要簡單地用復制內容把輸出區域覆蓋掉。
一切辦妥后,就用API函數 DeleteObject 釋放位圖對象,也就是把位圖“抹掉”。
2 軟件實現原理及實現方式
2.1 窗口中多個圖片的混合
2.1.1 繪制像素函數
原型: COLORREF SetPixel(int x,int y,COLORREF crColor );
參數說明: SetPixel 函數中, COLORREF是32位顏色數據類型;第一和第二個參數x, y是像素點位置的邏輯坐標值,第三個參數 crColor 是像素點的顏色值, COLORREF型變量可以利用 RGB(bRed , bGreen , bBlue)來指定相應的顏色值,每種顏色用一個字節表示,可以被設定為0~255之間的任意值, 0代表無色, 255代表全色。
2.1.2 獲取像素顏色函數
原型: COLORREF GetPixel(int x , int y)const ;
參數說明:得到指定像素的RGB顏色值,本函數是常成員函數。
2.2 相應的實現核心代碼
//設置兩張圖片的色彩混合
COLORREF c,f,ff;// c 為前景圖像色彩,f 為前景圖像應屏蔽的色彩
POINT p;
f = MemDC1.GetPixel(2,2);// 獲取前景要屏蔽的色彩
for(int i = 0;i for(int j = 0;j c = MemDC1.GetPixel(i,j); p.x =100+ i; p.y =100+ j;// 100為前景在背景中的水平位置和垂直位置 if(c == f) // 前景屏蔽的色彩用背景圖像的色彩填充 MemDC1.SetPixel(CPoint(i,j),MemDC2.GetPixel(p)); Else{// 前景圖像的色彩與背景圖像的色彩混合 ff = MemDC2.GetPixel(p); unsigned char *a,*b; a = (unsigned char*)c;b = (unsigned char*)ff; a[0] = a[0] * m_pa/100 + b[0]*(100-m_pa)/100; a[1] = a[1] * m_pa/100 + b[1]*(100-m_pa)/100; a[2] = a[2] * m_pa/100 + b[2]*(100-m_pa)/100; MemDC1.SetPixel(CPoint(i,j),c);}} pDC->BitBlt(100,100,bt.bmWidth,bt.bmHeight,MemDC1,0,0,SRCCOPY); 3 結束語 對于windows2000以上的系統來講,系統提供了接口函數AlphaBlend與SetLayeredWindowAttributes都能讓圖片透明,我們這里可以既可達到AlphaBlend的色度遞減與背景溶合,又可以達到SetLayeredWindowAttributes透明,只是要拿到的相應顯示硬件的圖像表示部分即可。這充分的說明了使用系統的公共的低級接口方法可以讓系統實現高檔的系統接口方法。 參考文獻: [1] 楊淑瑩,邊奠英.VC++圖像處理程序設計[M].北京:清華大學出版社,2003:18-22. [2] API畫透明位圖[EB/OL].(2009-03-26).http:http://www.qqgb.com/Program/VC/VCJC/Program_248609.html.