天天看點

MFC之CDC類、繪圖工具類學習與繪圖初級繪制像素點1.筆記2.使用練習

1.筆記

1.1CDC類

第一個C是Class,D是Device,第二個C是Context,即“裝置上下文”,是MFC中應用程式的圖形裝置接口,封裝了繪圖所需的成員函數。

1.1.1使用規則

任何時候,最多隻能獲得5個CDC同時使用。

1.1.2獲得CDC

函數原型:

CDC* CWnd::GetDC();
           

調用成功則傳回目前視窗客戶區裝置上下文辨別符,否則傳回NULL。

1.1.3釋放CDC

函數原型:

int CWnd::ReleaseDC(CDC* pDC);
           

pDC是要釋放裝置上下文的辨別符,調用成功則傳回非0,否則傳回0。

1.2繪圖工具類

1.2.1主要繪圖工具類

CGdiObject 提供各種Windows GDI繪圖工具的基類
CBitmap 封裝GDI位圖,提供位圖操作的接口
CBrush 封裝GDI畫刷,可以選作裝置上下文的目前畫刷
CFont 封裝GDI字型,可以選作裝置上下文的目前字型
CPalette 封裝GDI調色闆,提供應用程式和顯示器之間的顔色接口
CPen 封裝GDI畫筆,可以選作裝置上下文的目前畫筆

1.2.2 使用GDI對象繪圖時的規則

(1)繪圖開始前,建立一個新的GDI對象,并選入目前裝置上下文中,同時儲存指向原GDI對象的指針。

(2)使用新的GDI對象畫圖。

(3)繪圖結束後,使用儲存的原GDI對象的指針将裝置上下文恢複原狀。

1.3繪制像素點

1.3.1SetPixel

函數原型:

COLORREF CDC::SetPixel(POINT point,COLORREF crColor);
COLORREF CDC::SetPixel(int x,int y,COLORREF crColor);
           

參數順序為像素點位置,像素點顔色。調用成功則傳回像素點的RGB值,否則傳回-1。

1.3.2SetPixelV

函數原型:

BOOL CDC::SetPixelV(POINT point,COLORREF crColor);
BOOL CDC::SetPixelV(int x,int y,COLORREF crColor);
           

參數含義同上,調用成功則傳回非0,否則傳回0。

1.3.3比較

因為SetPixel要傳回RGB值,而SetPixelV不需要,故SetPixelV執行速度稍快。

1.4RGB

1.4.1RGB宏

原型:

COLORREF RGB(BYTE byRed,BYTE byGreen,BYTE byBlue);
           

三個參數都是位元組型變量,傳回值COLORREF類型,是用DWORD表示的整型數。

1.4.2RGB宏定義

#define RGB(r,g,b) ((COLORREF)(((BYTE)(r)|((WORD)((BYTE)(g))<<8))|
    (((DWORD)(BYTE)(b)<<16)))
           

記憶體原理圖:

MFC之CDC類、繪圖工具類學習與繪圖初級繪制像素點1.筆記2.使用練習

 1.4.3表示方法

以紅色為例:

(1)RGB(255,0,0):順序為red,green,blue

(2)0x0000FF:順序為blue,green,red,與記憶體原理圖對應

2.使用練習

2.1使用SetPixelV在(100,100)位置處繪制一個紅色像素點,然後讀出該像素點顔色,水準右移100個像素點再繪制一個紅色像素點,在裝置坐标系中程式設計實作。

2.1.1擷取像素點的顔色

函數原型:

COLORREF CDC::GetPixel(int x,int y)const;
COLORREF CDC::GetPixel(POINT point)const;
           

調用成功傳回指定位置的RGB值,否則傳回-1。

2.1.2程式設計實作

void CExample1View::OnDraw(CDC* pDC)
{
	CExample1Doc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	if (!pDoc)
		return;

	// TODO: 在此處為本機資料添加繪制代碼
	CPoint p0(100, 100);//聲明點
	CPoint p1(p0.x + 100, p0.y);
	
	pDC->SetPixelV(p0, RGB(255, 0, 0));//繪制像素點
	COLORREF crColor = pDC->GetPixel(p0);//擷取像素點顔色
	pDC->SetPixelV(p1,crColor);
}
           

2.2使用SetPixelV,将顔色設定為随機色,在x軸正向繪制左下角為(50,-50),右上角為(150,50)的正方形點集,然後讀出該正方形每個像素點顔色,在x軸負向對稱位置重新繪制該正方形。

因為繪圖範圍不止第一象限,是以需要在客戶區自建坐标系,采用之前的代碼在客戶區中心建立x正向右、y正向上的坐标系。因為x坐标和y坐标是互相獨立的,是以嵌套循環中x和y的順序可以交換,結合循環變量的設定,可以實作不同的動畫效果。

void CExample1View::OnDraw(CDC* pDC)
{
	CExample1Doc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	if (!pDoc)
		return;

	// TODO: 在此處為本機資料添加繪制代碼
	CRect rect;
	GetClientRect(rect);
	pDC->SetMapMode(MM_ANISOTROPIC);
	pDC->SetWindowExt(rect.Width(), rect.Height());
	pDC->SetViewportExt(rect.Width(), -rect.Height());
	pDC->SetViewportOrg(rect.Width() / 2, rect.Height() / 2);
	rect.OffsetRect(-rect.Width() / 2, -rect.Height() / 2);

	srand((unsigned)time(NULL));//防止獲得的随機數重複,time傳回系統時間的秒數
	COLORREF crColor;
	for (int x = 50; x < 150; ++x)//從左往右
		for (int y = -50; y < 50; ++y)//一列一列畫,從下往上
			pDC->SetPixelV(x, y, RGB(rand() % 256,
				rand() % 256, rand() % 256));
	for(int x = 50; x < 150; ++x)//對應x'從-50到-150,從右往左
		for (int y = -50; y < 50; ++y) {
			crColor = pDC->GetPixel(x, y);
			pDC->SetPixelV(-x, y, crColor);
		}
}