MFC中CvvImage类的应用

CVVImage类

OPENCVhighgui.h中定义的CvvImage类,可以很好的实现opencv和windowsMFC显示接口。

将CvvImage.cpp和CvvImage.h加入到工程中后,可以很容易的在windows窗口中显示图像。

void  CDistance::DrawPicToHDC(IplImage *img, UINT ID)   //自己添加的类函数,前面需添加声明
{
	CDC *pDC = GetDlgItem(ID)->GetDC(); //GetDlgItem(ID)通过资源ID获取对话框控件内的指针;这句话表示获取某控件内的设备绘图指针
	HDC hDC= pDC->GetSafeHdc();//获取该DC指针的句柄
	CRect rect;
	GetDlgItem(ID)->GetClientRect(&rect);//获取控件的坐标范围
	CvvImage cimg;
	cimg.CopyOf( img ); // 复制图片
	cimg.DrawToHDC( hDC, &rect );   // 将图片绘制到显示控件的指定区域内
	ReleaseDC( pDC );
}

void CDistance::OnPaint()                   //OnPaint()是CWnd的类成员,负责响应WM_PAINT消息。当Windows或应用程序请求重画应用程序窗口的一部分时,框架调用这个成员函数。
{
	CPaintDC dc(this); // device context for painting
	// TODO: 在此处添加消息处理程序代码
	// 不为绘图消息调用 CDialogEx::OnPaint()
		CRect rectL;
		GetDlgItem(IDC_AddSiftImg)->GetClientRect(&rectL);此处获得坐标范围只是为了根据控件的范围来重新构图
		int row,colume;
		row=rectL.bottom-rectL.top;
		colume=rectL.right-rectL.left;
		IplImage *resizeimage=cvCreateImage(cvSize(colume,row), siftimg->depth, siftimg->nChannels);
		cvResize(siftimg,resizeimage);
		DrawPicToHDC(resizeimage, IDC_AddSiftImg);//IDC_AddSiftImg是资源ID
}


资源ID、句柄、指针与类

以以上程序为例:

资源ID:IDC_AddSiftImg

指针:GetDlgItem(IDC_AddSiftImg)

类:CDC *pDC=GetDlgItem(IDC_AddSiftImg)->GetDC();

句柄: HDC hDC=pDC->GetSafeHdc()


HINSTANCE: 进程实例或者句柄

HANDLE:       文件句柄

HWND:        窗口的句柄,用来标识窗口对象

HPEN:         画笔句柄,用来标识画笔对象

HBITMAP:      位图句柄

HDC         设备环境句柄   

CWnd      是提供窗口处理的一个MFC封装基类,

            一般都和一个窗口句柄HWND绑定,有HWND m_hWnd成员

CDC:       是进行设备环境处理的一个MFC封装类,

            一般都和一个设备环境句柄HDC绑定,有HDC m_hDC 


注释1:想要对任何设备绘图,首先必须得到设备环境句柄(hDC),几乎所有的GDI函数的操作目标都是hDC,并且当你获得的设备环境句柄不在有用时应当将其释放,因此得到设备环境句柄的函数与释放设备环境句柄的函数总是成对出现在同一个消息处理过程之中的。

句柄和类的相互转换:
1.句柄构造类

   1.1 临时使用,用完不用删除

CDC *pDC = CDC::FromHandle(hDC); //MFC不保证什么时候删除DC
CBitmap *pBmp = CBitmap::FromHandle(hBitmap) 

   1.2 永久使用,用完需要删除GDI对象一定要释放内存并删除对象

   CDC dc;
   dc.Attach(hDC);  //窗口绑定,永久的,一直到你删除它
   //..........//   
   dc.Detach(hDC);  //当不用的时候要销毁

2.从类得到句柄

  CDC  dc;
   HDC  hDC;
   hDC = dc.GetSafeHdc();


CDC类下面有4个子类:

CDC是进行设备环境处理的类,GDI和GDI+显示类库需要这个设备显示对象(包括图像,画笔,线条,画刷等)

1.  CPaintDC   

// For drawing in window’s client area(OnPaint handles only)

    在构造时自动调用CWnd::BeginPaint,

    析构时调用CWnd::EndPaint。

    通常 CPaintDC用来响应WM_PAINT消息。一般应用在OnPaint函数窗口在很多时候能被绘制或重新绘制,如在窗口创建、大小变更、从其他窗口后面移出窗口、最大或最       小化等的时候。在窗口内容因某项操作改变时,系统将向程序发出WM_PAINT消息,通知程序作出相应的绘制工作


2.  CClientDC  

//For drawing in window’s client area(anywhere but OnPain)

     客户区窗口DC

     构造时自动调用GetDC函数,

     析构时自动调用ReleaseDC函数.一般应用于客户区窗口的绘制

     需要处理一个鼠标的单击,然后马上画出一个圆,你不能等到下一个WM_PAINT的消息到来才画图,而是马上,这是就需要CclientDC了。它可以在OnPaint的外面创建一      个客户区域DC

    void CMainWindow::OnLButtonDown (UINT nFlags, CPoint point)
    {
        CRect rect;
        GetClientRect (&rect);

        CClientDC dc (this);
        dc.MoveTo (rect.left, rect.top);
        dc.LineTo (rect.right, rect.bottom);
        dc.MoveTo (rect.right, rect.top);
        dc.LineTo (rect.left, rect.bottom);
    }


3.   CWindowDC     

//For drawing anywhere in window, including the nonclient area 

不仅是客户区,还包括窗口客户区以外的部分(如窗口标题栏、菜单栏等)需要需要重画时,系统向程序发出WM_NCPAINT消息。因标准窗口的客户区以外部分为窗口必需部分,因而WM_NCPAINT消息将默认被发送到DefWindowProc函数进行默认处理。程序可通过截获该消息来实现窗口其他部分的自定义绘制。使用的是CWindowDC


4.  CMetaFileDC   

//For drawing to GDI metafile


上面这4个子类由于构造和析构函数在获取和释放DC的时候会调用合适的函数,所以可以直接使用,不用释放DC,而CDC就要释放资源RealseDC()

 

 

   如果想在整个屏幕绘制时,可以创建一个CclientDC或CwindowDC对象,然后给他的构造函数传递一个NULL指针。如下:

    CClientDC dc(NULL);

    dc.Ellipse(0,0,100,100);

实例1:

 HWND hWnd;

  hWnd ::GetTopWindow(NULL);

  hWnd ::GetSafeHwnd();

 

实例2

void draw()   
     
     CWnd*   pWnd GetDlgItem(IDC_PICTURE);   // 获取绘图的标签   
     CDC*   pDC     pWnd->GetDC();   //获取设备上下文   
     int nOldDrawMode pDC->SetROP2(R2_XORPEN); //设置绘制方式为异或模式   
     pDC->SetBkMode(TRANSPARENT);   
     pDC->MoveTo(,);   
           ....   
     pWnd->ReleaseDC(pDC) 

   //注:CreateDC()     对应   DeleteDC()    都是CDC类的函数   
    //注:GetDC()   对应   ReleaseDC()       都是CWnd类的函数        
     


CDC等设备上下分类,都含有一个类的成员变量:m_nHdc;即HDC类型的句柄. 

参考:

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值