【2012年终总结】之二 opencv + ds采集摄像头视频 GDI点点滴滴

在这个项目中用到了几个GDI的函数,包括CFont  CPen  CBrush等,一般要和设备上下文DC结合起来使用。

并且创建GDI对象使用完后一定要释放,否则可能会造成资源泄漏

对于CPen CFont CBrush用构造函数定义的GDI对象 和 用 CreateXXX获得的对象在释放时要调用DeleteObject

对于GetXXX获得的对象在释放时要使用ReleaseObject。

 1     CDC *pDC0 = GetDlgItem(IDC_VIDEO0)->GetDC();
 2     CFont font;                                               // GDI对象
 3     font.CreatePointFont(200, _T("宋体"));                    //CreateXXX
 4     CFont *oldFont = pDC0->SelectObject(&font);
 5     pDC0->TextOut(20, 20, CString(_T("1")));
 6     pDC0->SelectObject(oldFont);
 7 
 8     GetDlgItem(IDC_VIDEO0)->ReleaseDC(pDC0); 
 9 
10    font.DeleteObject();                                  //释放GDI对象资源

下面的例子是画一个矩形的边框,矩形是一个Picture控件,当点击该控件时给这个控件的边缘画颜色

 1     CRect rect;
 2     CDC* pDC = GetDlgItem(m_nCurrentPicture)->GetDC();
 3     GetDlgItem(m_nCurrentPicture)->GetClientRect(&rect);
 4 
 5     CPen pen(PS_SOLID, 10, RGB(0x99, 0x32, 0xcc));
 6     CPen *oldPen = NULL;
 7     oldPen = pDC->SelectObject(&pen);
 8 
 9     //上边框;
10     pDC->MoveTo(rect.TopLeft());
11     pDC->LineTo(CPoint(rect.TopLeft().x + rect.Width(),   //x
12         rect.TopLeft().y                                          //y
13         ) );
14 
15     //右边框;
16     pDC->MoveTo(CPoint(rect.TopLeft().x + rect.Width(),   //x
17         rect.TopLeft().y                                  //y
18         ));
19     pDC->LineTo(rect.BottomRight());
20 
21     //下边框;
22     pDC->MoveTo(rect.BottomRight());
23     pDC->LineTo(rect.TopLeft().x,                         //x
24         rect.BottomRight().y                              //y
25         );
26 
27     //左边框;
28     pDC->MoveTo(rect.TopLeft().x,                         //x
29         rect.BottomRight().y                              //y
30         );
31     pDC->LineTo(rect.TopLeft());
32 
33 
34     pDC->SelectObject(oldPen);
35 
36     int ret = GetDlgItem(m_nCurrentPicture)->ReleaseDC(pDC); 
37     pDC = NULL; 
38     
39     pen.DeleteObject();

 多个Picture控件,每个Picture控件都在控件中间位置写上1 2 3 4等数字标识是哪个摄像头

 1 void CCameraMonitorView::OnDraw(CDC* /*pDC*/)
 2 {
 3     // TODO: 在此添加专用代码和/或调用基类;
 4 
 5     if (0 != m_nCurrentPicture)
 6     {
 7         ChoosePicture(m_nCurrentPicture);
 8     } 
 9 
10     int index = 0;
11     for (index = 0; index < MAX_CAMERAS_NUM; ++ index)
12     {
13         if (videoPicturesCtrl[index] != 0)
14         {
15             CDC *pDC = GetDlgItem(videoPicturesCtrl[index])->GetDC();
16             CFont font;
17             font.CreatePointFont(800, _T("宋体"));
18             CFont *oldFont = pDC->SelectObject(&font);
19             pDC->SetBkMode(TRANSPARENT);
20             CRect rect;
21             GetDlgItem(videoPicturesCtrl[index])->GetClientRect(&rect);
22 
23             int x = (rect.Width() / 2) - 20;
24             int y = (rect.Height() / 2) - 40;
25             char numArr[5] = {0};
26             _itoa_s(index + 1, numArr, RADIX_10);
27             CString strDisplayNum(numArr);
28 
29             pDC->TextOut(x, y, strDisplayNum);
30             pDC->SelectObject(oldFont); 
31 
32             GetDlgItem(IDC_VIDEO1)->ReleaseDC(pDC);
33 
34             font.DeleteObject(); 
35             
36         }
37     }
38  
39 }

从窗口指针获得DC

CDC *pDC = pWnd->GetDC();

根据DC获得HDC

HDC hDC = pDC->GetSafeHdc();

根据句柄获得窗口指针

CWnd *pWnd = FromHandle(hWnd);
void CJietu::OnPaint()
{
    CPaintDC dc(this); // device context for painting
    // TODO: 在此处添加消息处理程序代码
    // 不为绘图消息调用 CDialog::OnPaint()  
    
    HWND hWnd = m_hWnd;
    CWnd *pWnd = FromHandle(hWnd); 
    CDC *pDC = pWnd->GetDC();
    HDC hDC = pDC->GetSafeHdc();

    StretchBlt(hDC, 0, 0, m_nCx, m_nCy, m_hDCGlobal, 0, 0, m_nCx, m_nCy, SRCCOPY); 

    pWnd->ReleaseDC(pDC); 
     
}

 另外一个例子

 1 bool DrawPicToHDC(IplImage *img, HWND hWnd, bool bIsShowInfo)
 2 { 
 3     CWnd *pWnd = CWnd::FromHandle(hWnd);
 4     if (NULL == pWnd || FALSE == ::IsWindow(pWnd->m_hWnd))
 5     {
 6         AfxMessageBox(_T("DrawPicToHDC error 2"));
 7         return false;
 8     } 
 9 
10     CDC *pDC = pWnd->GetDC();
11     HDC hDC = pDC->GetSafeHdc();
12     CRect rect;
13     pWnd->GetClientRect(&rect);
14     CvvImage cimg;
15     cimg.CopyOf(img);
16     cimg.DrawToHDC(hDC, &rect); 
17 
18     pDC->SetBkMode(TRANSPARENT);              //文字透明;
19     CTime time = CTime::GetCurrentTime();     //获得当前时间;
20     CString strTime;
21     strTime = time.Format("%Y-%m-%d  %H:%M:%S");
22  
23     CFont font;
24     font.CreatePointFont(200, _T("宋体"), NULL);
25     CFont *oldFont = pDC->SelectObject(&font);
26     pDC->SetTextColor(RGB(255, 0, 0));       //文字颜色
27 
28     pDC->TextOut(10, 10, strTime);
29 
30     if (true == bIsShowInfo)
31     {
32         pDC->TextOut(10, 35, CString("正在录像..."));
33     }
34 
35     pDC->SelectObject(oldFont);
36 
37     ReleaseDC(hWnd,hDC);   //释放DC
38     font.DeleteObject();     //释放GDI对象
39 
40     return true;    
41 }
原文地址:https://www.cnblogs.com/cuish/p/2893303.html