GDI:Graphics Device Interface,即圖形設備接口,是Windows API的一個重要組成部分。它是Windows圖形顯示程序與實際物理設備之間的橋梁,GDI使得用戶無需關心具體設備的細節,而只需在一個虛擬的環境(即邏輯設備)中進行操作。它的橋梁作用體現在:
(1)用戶通過調用GDI函數將邏輯空間的操作轉化為具體針對設備驅動程序的調用。
為實現圖形設備無關性,Windows的繪圖操作在一個設備描述表上進行。用戶擁有自己的“邏輯坐標”系統,它獨立於實際的物理設備,與“設備坐標”相對應。開發Windows應用程序時,程序員關心的是邏輯坐標,我們在邏輯坐標系上繪圖,利用GDI將邏輯窗口映射到物理設備上。
(2)GDI能檢測具體設備的能力,並依據具體的設備以最優方式驅動這些設備,完成真實的顯示。
GDI函數大致可分類為:
GDI雖然使程序員得到了一定程度的解脫,但是其編程方式仍很麻煩。譬如,顯示一張位圖,程序員需要進行“裝入位圖 | 讀取位圖文件頭信息 | 啟用設備場景 | 調色板變換”等一連串操作。而有了GDI+,這些問題便迎刃而解了。
GDI+:GDI+是GDI的后續版本,最早於2001年隨WinXP一起推出,后來又被包裝進.NET框架的托管類庫中,成為.NET中窗體繪圖的主要工具。
GDI+主要提供了以下三類服務:
(1)二維矢量圖形:GDI+提供了存儲圖形基元自身信息的類(或結構體)、存儲圖形基元繪制方式信息的類以及實際進行繪制的類;
(2)圖像處理:大多數圖片都難以划定為直線和曲線的集合,無法使用二維矢量圖形方式進行處理。因此,GDI+為我們提供了Bitmap、Image等類。它們可用於顯示、操作和保存BMP、JPG、GIF等圖像。
(3)文字顯示:GDI+支持使用各種字體、字號和樣式來顯示文本。
GDI接口是基於函數的,而GDI+是基於C++ OO的編程接口,因此使用起來比GDI要方便。因為GDI+實際上是GDI的封裝和擴展,所以執行效率一般要低於GDI。
使用GDI時,經常需要將PEN、BRUSH等GDI對象選入DC,並需要保存舊的GDI對象,然后進行一些繪圖操作。此時調用的繪圖函數都是使用這些新選入的PEN、BRUSH,繪圖完成之后再把舊的GDI對象重新選回DC,這稱之為“狀態模式”。而GDI+不是這樣,GDI+只是將PEN、BRUSH等對象作為參數傳遞給繪圖函數,它們只影響這一次的繪制,下次再調用繪圖函數,可以將新的PEN、BRUSH傳入給繪圖函數,這稱為“無狀態模式”。與GDI相比,GDI+的編程模式發生了改變。
1、DC與Graphics
DC是GDI的核心,Graphics對象是GDI+的核心。DC和Graphics對象的作用相似,但使用句柄的編程模式和使用Graphics對象的面向對象的編程模型之間,存在一些基本的差異。
Graphics對象(像DC一樣)與屏幕上的特定窗口關聯,並具有指定如何繪制項目的屬性(如 SmoothingMode 和 TextRenderingHint)。但Graphics 對象不受筆、刷、路徑、圖像或字體的約束,這與DC不同。例如,使用DC畫線之前,必須先調用SelectObject以使筆對象和DC關聯,即將筆選入DC中。之后的畫線操作均使用該筆,直到選擇另一支不同的筆為止。在GDI+中,將Pen對象作為參數傳遞給Graphics類的DrawLine方法。可以在一系列的 DrawLine 調用中,使用不同的Pen對象,而不必將給定的Pen對象與Graphics對象關聯。
2、以畫線為例
無論是GDI還是GDI+,都有API和MFC封裝類兩種使用方式。下面每個示例都從點(20, 10)到點(200, 100)繪制一條寬為3 的紅色線條。
(1)GDI API
(2)GDI MFC
(3)GDI+ API
(4)GDI+ MFC
3、方法重載
許多GDI+方法都是重載的,這與MFC封裝后的GDI類似。例如,DrawLine的重載方法有:
4、繪制和填充
GDI有一個Rectangle函數,可一步完成繪制輪廓和填充矩形內部。輪廓由當前選定的筆繪制,而內部則由當前選定的刷來填充。 GDI+使用Graphics類的DrawRectangle方法將 Pen對象作為參數繪制輪廓,使用Graphics類FillRectangle方法將Brush對象作為參數填充內部。
5、構造區域
GDI提供幾種用於創建區域的函數(在MFC中,被封裝在CRng類里):CreateRectRgn、CreateEllpticRgn、CreateRoundRectRgn、CreatePolygonRgn 和CreatePolyPolygonRgn。你或許希望GDI+中的Region類也有類似的構造函數,將矩形、橢圓、圓角矩形和多邊形作為參數接收,但事實並非如此。GDI+中的Region類提供一個接收Rectangle 對象的構造函數和另一個接收GraphicsPath對象的構造函數。如果想基於橢圓、圓角矩形或多邊形構造區域,可以通過創建一個GraphicsPath對象(可包含橢圓的對象等),然后將其傳遞至Region構造函數來輕松實現。
路徑(path)是一系列相互連接的直線和曲線,由許多不同類型的點所構成,用於表示復雜的不規則圖形,也叫做圖形路徑(graphics path)。路徑可以被畫輪廓和填充,也可以用於創建區域和路徑漸變刷等。在 GDI+中,路徑由圖形路徑類GraphicsPath表示,它也是圖形基類GraphicsBase 的派生類。關於GraphicsPath,以后再學習。