GDI,圖像設備接口的簡稱。
首先介紹幾個概念。
1、DC,設備上下文DeviceContext,也稱為設備描述表。它是一個關於如何繪制圖形的方法集合,既可以繪制各種圖形,也可以確定在應用窗口中繪制圖形的方式,即繪圖模式和映射模式。Win32編程中使用HDC來標識。DC類似於畫布,我們想要繪制圖形首先就需要獲得DC。
常見獲得DC的方法
HDC hdc = ::GetDC(hwnd);
::ReleaseDC(hwnd,hdc);
此方法適合在窗口現有圖形的基礎上進行繪制。(獲得DC后一定要記得Release,否則會造成內存泄漏)
PAINTSTRUCT ps;
HDC hdc = ::BeginPaint(hWnd,&ps);
::EndPaint(hWnd,&ps);
BeginPaint函數就是將窗口上所有內容清除干凈,然后在上面繪制。參數ps可以指定更新的區域,而不必重繪制整個界面, BeginPaint和EndPaint總是被用來響應WM_PAINT消息。
HDC hMemDC = ::CreateCompatibleDC(hDest);
//其他繪圖操作代碼
::BitBlt(hDest,x,y,w,h,hMemDC,0,0,SRCCOPY);//將hMemDC上繪制的圖像數據拷貝到hDest上,界面此時才會顯示
::DeleteDC(hMemDC);
通過調用CreateCompatibleDC函數來創建與目標DC兼容的內存DC,一般用於解決界面的閃爍問題。
2、常用的GDI對象
畫筆Pen:負責畫線,畫邊框(矩形邊框,圓邊框,餅邊框)都是采用畫筆來操作的。默認畫筆是黑色,寬度為1,樣式為實線的畫筆。
畫刷Brush:負責填充矩形,填充圓、餅等以及刷窗口背景。默認為白色畫刷。
字體Font:負責基於具體字體對象的所有的文本繪制,默認字體是系統等寬字體,比如對話框標題。
區域Region:用HRGN表示,在窗口中一個區域可以是橢圓形,多邊形或者更常見的矩形。
位圖Bitmap:在GDI中,用HBITMAP來表示位圖,GDI的繪制從答題上可以分為圖形繪制和圖像繪制。對於線,矩形,圓,餅等的繪制屬於圖形繪制,而對於位圖的繪制是屬於圖像繪制。
3、使用GDI對象
SelectObject函數,選擇使用的GDI對象
HGDIOBJ SelectObject(HDC hdc, HGDIOBJ hgdiobj)
hdc:設備上下文環境的句柄。
hgdiobj:被選擇的對象的句柄,該指定對象必須由如下的函數創建。
返回值:返回該DC對象的老的相同類型的GDI對象。
HGDIOBJ GetStockObject(int i),獲得默認的GDI對象
通過ID號來獲得windows默認提供的一些GDI對象。ID號為預定義的宏,這些對象獲得后,不需要人為的銷毀。
//字體
#define OEM_FIXED_FONT 10
#define ANSI_FIXED_FONT 11
…
//畫刷
#define WHITE_BRUSH 0
…
//畫筆
#define WHITE_PEN 6
…
GetObject函數,獲取GDI對象的信息
int GetObject(HGDIOBJ hgdiobj, int cbBuffer, LPVOID lpvObject);
第一個參數填入GDI對象的句柄;
第二個參數填入結構的大小;
第三個參數填入結構的指針,這里的結構對應相應的GDI對象的結構。
DeleteObject函數,刪除GDI對象。
創建的GDI對象一定要刪除,否則會造成內存泄漏。
4、繪制位圖的步驟
獲得目標DC句柄
創建與目標DC兼容的臨時內存DC
將位圖句柄選入到臨時內存DC中
使用BitBlt函數將臨時內存DC中的位圖拷貝到目標DC上來
將位圖句柄選出臨時內存DC
銷毀臨時的內存DC
注意:一定要將位圖句柄選出臨時內存DC,否則目標DC被拷貝的位圖也會被銷毀掉。
下面是用到的函數
加載BitMap圖片
HBITMAP LoadBitmap(HINSTANCE hInstance, LPCTSTR lpBitmapName);
從應用程序資源中讀取位圖數據,所以使用這個接口時,我們需要先將位圖導入資源中。第一個參數傳入資源所在的模塊實例句柄,第二參數是位圖在資源中的ID名稱。
HBITMAP hbmp = LoadBitmap(hInstance,MAKEINTRESOURCE(IDB_BACK));
宏MAKEINTRESOURCE將數字的ID號轉換成整形資源號字符串。
LoadBitmap已經被LoadImage函數取代了。
LoadImage函數可以加載位圖、圖標、光標等多種圖像數據。
既可以從資源加載:
HBITMAP hbmp = (HBITMAP)::LoadImage(hInstance, MAKEINTRESOURCE(IDB_BACK)
,IMAGE_BITMAP,0,0,LR_CREATEDDIBSECTION|LR_LOADMAP3DCOLORS);
或者直接從路徑加載:
HBITMAP hbmp = (HBITMAP)::LoadImage(NULL, _T(“.\\1.bmp”),IMAGE_BITMAP,0,0,
LR_LOADFORMFILE|LR_DEFAULTSIZE| LR_LOADMAP3DCOLORS);
BitBlt繪制位圖函數。
BOOL BitBlt( _In_ HDC hdcDest, _In_ int nXDest, _In_ int nYDest, _In_ int nWidth, _In_ int nHeight, _In_ HDC hdcSrc, _In_ int nXSrc, _In_ int nYSrc, _In_ DWORD dwRop);
hDestDC:指向目標設備環境的句柄。
x:指定目標矩形區域左上角的X軸邏輯坐標。
y:指定目標矩形區域左上角的Y軸邏輯坐標。
nWidth:指定源在目標矩形區域的邏輯寬度。
nHeight:指定源在目標矩形區域的邏輯高度。
hSrcDC:指向源設備環境的句柄。
xSrc:指定源矩形區域左上角的X軸邏輯坐標。
ySrc:指定源矩形區域左上角的Y軸邏輯坐標。
dwRop:指定光柵操作代碼。這些代碼將定義源矩形區域的顏色數據,如何與目標矩形區域的顏色數據組合以完成最后的顏色。一般SRCCOPY是拷貝的意思。
HDC hDCmem = ::CreateCompatibleDC(hdc);
HBITMap hOldBmp = (HBITMap)::SelectObject(hDCmem,hbmpBack);
BITMAP bmp;
::GetObject(hbmpBack,sizeof(BITMAP),&bmp);
::BitBlt(hdc,0,0,bmp.bmWidth,bmp.bmHeight,HDCmem,0,0,SRCCOPY);
//繪圖
::SelectObject(hDCmem,hOldBmp);
::DeleteDC(hDCmem);
拉伸圖片
GetClientRect函數獲得客戶區大小
使用StretchBlt函數對圖片進行拉伸
5、文字繪制
指定字體的大小編碼的結構體LOGFONT
設置文字的顏色GetTextColor
獲得文字的顏色SetTextColor
設置背景模式SetBKMode,設置DC的背景模式,相對應的GetBKMode是用來獲取背景模式的。mode參數可以是TRANSPARENT(透明)與OPAQUE(不透明,默認值)
DrawText函數和TextOut函數都是繪制文字的函數,前者通過控制繪制區域和繪制格式來控制繪制的位置,后者可以直接指定繪制的起始位置和結束位置。
6、繪制點,線,面
SetPixel/GetPixel設置/返回指定點的顏色。
MoveToEx設置線的繪制起點
LineTo繪制線
Rectangle采用選定的畫筆和畫刷來繪制矩形。畫筆負責繪制矩形的邊框,畫刷負責填充矩形。
Ellipse繪制圓,需要指定這個圓的外接矩形。
Pie繪制扇形圖
GDI+的介紹
GDI+是windows系統中的一個子系統,它主要負責在顯示屏幕和打印設備輸出有關信息,它是一組通過C++類實現的應用程序編程接口。GDI+對以前的Windows版本中GDI進行了優化,並添加了許多新的功能。作為圖形設備接口的GDI+使得應用程序開發人員在輸出屏幕和打印機信息的時候無需考慮具體顯示設備的細節,他們只需要調用GDI+庫輸出的類的一些方法即可完成圖形操作。
GDI+的使用方法
在使用GDI+的cpp文件中包含GdiPlus.h的頭文件,並引用命名空間using namespace Gdiplus。
同時需要在項目屬性中的連接器->輸入->附加依賴項中加入gdiplus.lib。
同時需要在主程序的開始部分,添加如下代碼:
//GDI+資源初始化
ULONG_PTR uToken = 0;
GdiplusStartupInput gdiplusStartupInput;
GdiplusStartup(&uToKen,&gdiplusStartupInput,NULL);
應用程序結束時,需要銷毀GDI+資源
GdiplusShutdown(uToken);
GDI+系統中的透明度的概念
透明度是像素之間的一種合成運算,它的計算公式是:
輸出顏色=前景色*Alpha/255 + 背景色*(255-Alpha)/255;
GDI+常用的幾個類。
Graphics類,類似於GDI中DC。
Bitmap類,繼承與Image類。
GDI+中使用Graphics類的DrawImage函數來繪制圖片。
使用Graphics類measureString函數來測量字符串的需要容納的矩形區域。
DrawLine/DrawRectangle/DrawEllipse/DrawPie畫圖
GDI+中的核心是Graphics類而GDI中是基於DC句柄的。
GDI+在GDI的設備環境DC上進行圖形的繪制。GDI+就回吧當前的DC作為默認的目標畫布,之后調用Graphics中的任何函數都會被繪制到DC對象上,當然每個函數的調用完成並不會立即反映到DC中,只有當Graphics類析構的時候才會把所有繪制的內容全部一次性地拷貝到hDC中。
Graphics提供了獲得HDC的函數GetHDC,這樣我們就可以在hDC上進行GDI函數的繪制。
