MFC在内存DC中绘图

                                       MFC在内存DC中绘图

 

文章目录

  1. 定义
  2. DC对象介绍
  1. 声明DC
  2. 选择DC对象
  3. 开始绘图
  4. 保存及显示

 


前言

       因为用MFC框架做软件开发,前前后后用了几次GDI绘图,但一直没有系统地整理一下GDI绘图的方法和逻辑,似懂非懂,今天将之前用过的GDI绘图方法和逻辑整理一下。


 

一、DC是什么?

1.定义:DC,即:Device Context,设备环境(也叫设备上下文,设备描述表)。它提供了MFC绘图的环境。用画画举个例子,画画的话,需要用到得东西有画板,画布,画笔,颜料等。DC就相当于画板,是画图的基础环境,在画图开始之前就必须确定的东西,即在画图之前就声明且定义一个DC环境用于后续画图。

2.DC有6种对象:区域,画笔,画刷,字体,调色板,位图。DC选择对象的函数SelectObject()。后续会介绍DC中画笔,画刷,位图的使用。

 

二、绘图步骤

1.声明DC

获取DC:有四种,这里介绍常用的两种:

①:使用HDC绘图

//获取窗口的DC
HDC hdc;
CWnd* pWnd=GetDlgItem(IDC_STATIC_PICTURE);//获取窗口指针
HWND hwnd=pWnd->GetSafeHandle();//获取窗口句柄
hdc=::GetDc(hwnd);
MoveToEx(hdc,x,y,NULL);
LineTo(hdc,x,y);
::ReleaseDC(cwnd,hdc);//释放句柄,必须和GetDC成对使用

//新建兼容DC
CDC dc;
HDC hdc;
hdc=createCompatibleDc(dc);//创建兼容DC,以便将图像保存为不同的格式。
MoveToEx(hdc,x,y,NULL);
LineTo(hdc,x,y);
ReleaseDC(hdc);//释放句柄,必须和GetDC成对使用

②:使用DC绘图

CDC* dc=GetDC();//参数为空,默认当前窗口
dc->MoveTo(x,y);
dc->LineTo(x,y);
ReleaseDC(dc);

 

2.选择DC对象

1.位图。

       首先说一下为什么需要位图,因为位图为DC提供了可以绘图的地方,如果说DC是画板的画,那么位图就是画布,有了画布,才能开始绘图。

        DC选择位图之前,需要先有一个位图,然后使用selectObject()将位图选入DC,得到位图的方式有两种:

①新建一个位图:

CBitmap bitmap;
CDC dc;
HDC hdc = CreateCompatibleDC(dc); //创建兼容DC,以便将图像保存为不同的格式
bitmap.CreateCompatibleBitmap(dc,rect.Width(), rect.Height());
dc.SelectObject(&bitmap);//把位图选入内存DC

②从磁盘导入一个位图文件:

HBITMAP hbitmap1 = (HBITMAP)::LoadImage(NULL, LPCWSTR(inputImage), IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);//从磁盘中导入位图文件   
HBITMAP hOldMap = (HBITMAP)SelectObject(hdc, hbitmap1);	//将位图选入DC,并保存返回值 

 

2.画笔及画刷。画笔及画刷的作用是设置绘图的颜色及线条的大小。

 //画刷
 CBrush brush;
 brush.CreateSolidBrush(RGB(255,0,0));//建立个红色的画刷给内存DC
 dc.SelectObject(&brush)///选择这个刷子


//画笔
CPen pen;
pen.CreatePen(PS_SOLID,1,RGB(255,0,0));//建立个红色的画笔给内存DC
dc.SelectObject(&pen)///选择这个画笔



//上面都是使用dc来选择画笔,画刷的用法,下面是使用dhc选择画笔的用法
HPEN hPen;
hPen=CreatePen(PS_SOLID, 1, RGB(0, 255, 0));
HPEN hOldPen = (HPEN)::SelectObject(hdc,hPen);

 

3.开始绘图

绘图主要使用的函数:

MoveTo(x,y);   MoveToEx(hdc,x,y,NULL),

LineTo(x,y);LineTo(hdc,x,y);

AngleArc(ptCenter.x,ptCenter.y,r,angleStart,angleEnd);

//hdc画直线
MoveToEx(hdc, centerX-5, centerY, NULL);
LineTo(hdc, centerX + 5, centerY);	
MoveToEx(hdc, centerX, centerY-5, NULL);
LineTo(hdc, centerX, centerY+5);

//hdc画圆
MoveToEx(hdc, centerX, centerY-5, NULL);
AngleArc(hdc,centerX, centerY, radius, 0, 360);

//dc画直线
dc.MoveTo(centerX-5, centerY);
dc.LineTo(centerX+5, centerY);
dc.MoveTo(centerX, centerY - 5);
dc.LineTo(centerX, centerY + 5);

//dc画圆
dc.MoveTo(centerX+radius, centerY);
dc.AngleArc(centerX, centerY, radius, 0, 360);



 

4.保存及显示

保存:

//保存屏幕中的图像到本地
LPCTSTR szFileName = _T("C:\\test1.bmp");
SaveHDCToFile(hdc, &rect, szFileName);

//直接保存DC中绘制完成的位图到本地
CImage image;
image.Attach(hbitmap1);  //将位图转化为一般图像
//char*转LPCTSTR
CString strOut(_outputImage);
LPCTSTR outputImage = (LPCTSTR)strOut;
image.Save(outputImage);

显示:

CImage image;
image.StretchBlt(pDc->m_hDC, rect1, SRCCOPY); //将图片画到Picture控件表示的矩形区域

 

三、示例

代码1:DC中绘图并保存到本地

double SaveResultToBmp(char* _inputImage, char* _outputImage,double centerX, double centerY)
{
	//char*转lpcwstr
	CString str = CString(_inputImage);
	USES_CONVERSION;
	LPCWSTR inputImage = A2CW(W2A(str));

	CDC dc;
	HDC hdc = CreateCompatibleDC(dc); //创建兼容DC,以便将图像保存为不同的格式
	HBITMAP hbitmap1 = (HBITMAP)::LoadImage(NULL, LPCWSTR(inputImage), IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);//从磁盘中导入位图文件   
	HBITMAP hOldMap = (HBITMAP)SelectObject(hdc, hbitmap1);	//将位图选入DC,并保存返回值 
	

	HPEN hPen;
	hPen=CreatePen(PS_SOLID, 1, RGB(0, 255, 0));
	HPEN hOldPen = (HPEN)::SelectObject(hdc,hPen);

	MoveToEx(hdc, centerX-5, centerY, NULL);
	LineTo(hdc, centerX + 5, centerY);	
	MoveToEx(hdc, centerX, centerY-5, NULL);
	LineTo(hdc, centerX, centerY+5);

	CImage image;
	image.Attach(hbitmap1);  //将位图转化为一般图像
	//char*转LPCTSTR
	CString strOut(_outputImage);
	LPCTSTR outputImage = (LPCTSTR)strOut;
	image.Save(outputImage);


	dc.SelectObject(hOldMap);

	return 0.0;
}

 

代码2:DC中绘图,显示到PICTURE控件中,并将PICTURE控件中的图像保存到本地

由于不能从VS中把代码拷贝出来,暂时记录一下使用到的主要功能函数:

CImage image;

image.StretchBlt(pDC->m_hDC,rect1,SRCCOPY);//将DC中图片滑倒picture控件中

LPCTSTR szFileName=_T("c:/000.bmp");

SaveHDCToFile(hdc,&rect,szFileName);//保存屏幕中picture控件中的图像到本地。


总结

        总结一下:MFC中的DC绘图的主要流程:获取DC(开辟绘图环境,内存)→选择需要用到的DC对象(其中位图,画笔,画刷基本是必选的工具)→绘图的显示与保存(主要功能函数:StretchBlt(),SaveHDCToFile(),CImage::Save())。

        需要注意的点:获取DC,选择DC对象的时候,都会有两种方式,即DC和HDC。DC是MFC中CDC类的对象,HDC是windows的DC的句柄,他们都可以用来选择DC对象,单使用的时候函数参数或者名称不一样。下面是MFC  Object和Windows Object的对应关系:

0001

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值