一、位元影像 -- 光柵映像 -- 縮放會失真
元檔案 -- 向量映像 -- 縮放不失真
二、一些函數:
1、BitBlt (bit blit)
直接拷貝位元影像象素。
2、BOOL CDC::StretchBlt( int x, int y, int nWidth, int nHeight, CDC* pSrcDC, int xSrc, int ySrc, int nSrcWidth, int nSrcHeight, DWORD dwRop );
可以縮放、翻轉。
翻轉方法:x 表示目的地X座標,nWidth表示目的地寬度,正的表示向右,負的表示向左。 源的寬度和目的寬度正負不一致,即為翻轉。 y座標同理。
StretchBlt函數縮放圖形會失真,可以用SetStretchBltMode方法來控制失真。
複製模式dwRop 。這個實際上是在源裝置、目標裝置和畫刷三者之間做邏輯操作。
3、BOOL CDC::PatBlt( int x, int y, int nWidth, int nHeight, DWORDdwRop );
圖案塊傳送
這個函數實際上就是StretchBlt去掉源裝置的情況,只是目標裝置和畫刷之間的邏輯操作。
三、GDI位元影像對象有時候也被稱為裝置相關位元影像或DDB。
DDB依賴於具體裝置,它只能存在於記憶體中(視頻記憶體或系統記憶體),其顏色模式必須與特定的輸出裝置相一致,使用系統調色盤。一般只能載入色彩較簡單的DDB位元影像,對於顏色較豐富的位元影像,需使用DIB才能長期儲存。
DDB儲存在GDI模式內部,由應用程式軟體的數字控制代碼引用。如:HBITMAP hBitmap;
建立DDB獲得控制代碼 hBitmap = GreateBitmap(...);//分配並初始化GDI記憶體中的一些記憶體來儲存關於位元影像的資訊,以及實際位元影像的位資訊。應用程式不能直接存取這段記憶體。位元影像與裝置描述表無關。
一般只有在建立單色位元影像的時候才用GreateBitmap,更多的時候用CreateCompatibleBitmap來簡化問題。
hBitmap = CreateCompatibleBitmap(hdc,cx,cy)建立與裝置相容的位元影像。
還有一個建立DDB的函數 hBitmap = CreateBitmapIndirect(&bitmap)
也可以在建立位元影像後,設定位元影像位資訊 SetBitmapBits(hBitmap , cBytes,&bits);//一般只用來設定單色。比如用來寫字。
還有一個獲得DDB控制代碼的方法: hBitmap = LoadBitmap(...);//與視頻顯示器相容。
清除記憶體: DeleteObject(hBitmap);
四、記憶體裝置描述表
HDC hdcMem = CreateCompatibleDC(hdc); //建立與hdc相容的記憶體裝置描述表,如果hdc為NULL,那建立與視頻顯示器相相容的記憶體裝置描述表。
SelectObject(hdcMem,hBitmap);//將DDB選入裝置描述表。只有選進的位元影像是單色的,或者和與相容裝置有相同的彩色結構時,SelectObject才會起作用。其實建立相容裝置描述表,就是設定具有相同的彩色結構。
DeleteDC(hdcMem);//清除。
五、GetTextExtentPoint,判斷一個字串的大小(範圍)。在Win32環境中,最好使用GetTextExtentPoint32,它提供了更精確的計算結果。
在裝置上寫字,然後貼在客戶區:
case WM_CREATE: hdc = GetDC (hwnd) ; hdcMem = CreateCompatibleDC (hdc) ; GetTextExtentPoint32 (hdc, szText, lstrlen (szText), &size) ; cxBitmap = size.cx ; cyBitmap = size.cy ; hBitmap = CreateCompatibleBitmap (hdc, cxBitmap, cyBitmap) ; ReleaseDC (hwnd, hdc) ; SelectObject (hdcMem, hBitmap) ; TextOut (hdcMem, 0, 0, szText, lstrlen (szText)) ; return 0 ;case WM_PAINT: hdc = BeginPaint (hwnd, &ps) ; switch (iSize) { case IDM_BIG: StretchBlt (hdc, 0, 0, cxClient, cyClient, hdcMem, 0, 0, cxBitmap, cyBitmap, SRCCOPY) ; break ; case IDM_SMALL: for (y = 0 ; y < cyClient ; y += cyBitmap) for (x = 0 ; x < cxClient ; x += cxBitmap) { BitBlt (hdc, x, y, cxBitmap, cyBitmap, hdcMem, 0, 0, SRCCOPY) ; } break ; } EndPaint (hwnd, &ps) ; return 0 ;
六、GetObject(ByVal hObject As Long, ByVal nCount As Long, lpObject As Any)取得對指定對象進行說明的一個結構。如擷取HBITMAP大小。對於不同的Object,如BITMAP、畫刷等,返回的結構體不同。
七、掩碼。
掩碼的實質就是通過SRCCOPY、SRCAND.....這類的參數,用BitBlt這類的方法,將源DC複製到目的DC。
原理:黑色為0,白色為1, 然後用包含白色或黑色位元影像的源DC,對目的DC進行邏輯運算。
範例:
LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
static HBITMAP hBitmapImag, hBitmapMask ;
static HINSTANCE hInstance ;
static int cxClient, cyClient, cxBitmap, cyBitmap ;
BITMAP bitmap ;
HDC hdc, hdcMemImag, hdcMemMask ;
int x, y ;
PAINTSTRUCT ps ;
switch (message)
{
case WM_CREATE:
hInstance = ((LPCREATESTRUCT) lParam)->hInstance ;
// Load the original image and get its size
hBitmapImag = LoadBitmap (hInstance, TEXT ("Matthew")) ;
GetObject (hBitmapImag, sizeof (BITMAP), &bitmap) ;
cxBitmap = bitmap.bmWidth ;
cyBitmap = bitmap.bmHeight ;
// Select the original image into a memory DC
hdcMemImag = CreateCompatibleDC (NULL) ;
SelectObject (hdcMemImag, hBitmapImag) ;
// Create the monochrome mask bitmap and memory DC
hBitmapMask = CreateBitmap (cxBitmap, cyBitmap, 1, 1, NULL) ;
hdcMemMask = CreateCompatibleDC (NULL) ;
SelectObject (hdcMemMask, hBitmapMask) ;
// Color the mask bitmap black with a white ellipse
SelectObject (hdcMemMask, GetStockObject (BLACK_BRUSH)) ;
Rectangle (hdcMemMask, 0, 0, cxBitmap, cyBitmap) ;
SelectObject (hdcMemMask, GetStockObject (WHITE_BRUSH)) ;
Ellipse (hdcMemMask, 0, 0, cxBitmap, cyBitmap) ;
// Mask the original image
BitBlt (hdcMemImag, 0, 0, cxBitmap, cyBitmap,
hdcMemMask, 0, 0, SRCAND) ;
DeleteDC (hdcMemImag) ;
DeleteDC (hdcMemMask) ;
return 0 ;
case WM_SIZE:
cxClient = LOWORD (lParam) ;
cyClient = HIWORD (lParam) ;
return 0 ;
case WM_PAINT:
hdc = BeginPaint (hwnd, &ps) ;
// Select bitmaps into memory DCs
hdcMemImag = CreateCompatibleDC (hdc) ;
SelectObject (hdcMemImag, hBitmapImag) ;
hdcMemMask = CreateCompatibleDC (hdc) ;
SelectObject (hdcMemMask, hBitmapMask) ;
// Center image
x = (cxClient - cxBitmap) / 2 ;
y = (cyClient - cyBitmap) / 2 ;
// Do the bitblts
BitBlt (hdc, x, y, cxBitmap, cyBitmap, hdcMemMask, 0, 0, 0x220326) ;
BitBlt (hdc, x, y, cxBitmap, cyBitmap, hdcMemImag, 0, 0, SRCPAINT) ;
DeleteDC (hdcMemImag) ;
DeleteDC (hdcMemMask) ;
EndPaint (hwnd, &ps) ;
return 0 ;
case WM_DESTROY:
DeleteObject (hBitmapImag) ;
DeleteObject (hBitmapMask) ;
DeleteDC(mydc);
PostQuitMessage (0) ;
return 0 ;
}
return DefWindowProc (hwnd, message, wParam, lParam) ;
}
八、建立一副位元影像,並對他進行操作:
hdc = GetDC (hwnd) ;
hdcMem = CreateCompatibleDC (hdc) ;
hBitmap = CreateCompatibleBitmap (hdc, cxTotal, cyTotal) ;
ReleaseDC (hwnd, hdc) ;
SelectObject (hdcMem, hBitmap) ;
Rectangle (hdcMem, -1, -1, cxTotal + 1, cyTotal + 1) ;
hBrush = CreateHatchBrush (HS_DIAGCROSS, 0L) ;
SelectObject (hdcMem, hBrush) ;
SetBkColor (hdcMem, RGB (255, 0, 255)) ;
Ellipse (hdcMem, cxMove, cyMove, cxTotal - cxMove, cyTotal - cyMove) ;
DeleteDC (hdcMem) ;
DeleteObject (hBrush) ;
九、
hwnd = GetDesktopWindow () //擷取桌面視窗控制代碼
LockWindowUpdate(hwnd)//禁止視窗被其他程式重新整理
LockWindowUpdate (NULL) ;//取消禁止
GetDCEx (hwnd, NULL, DCX_CACHE | DCX_LOCKWINDOWUPDATE) ;