MFC之CDC类、绘图工具类学习与绘图初级绘制像素点

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)))

内存原理图:

 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);
		}
}

  • 3
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

赴星辰大海

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值