程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> MFC雙緩沖繪圖實例,mfc繪圖實例

MFC雙緩沖繪圖實例,mfc繪圖實例

編輯:C++入門知識

MFC雙緩沖繪圖實例,mfc繪圖實例


本人之前一直了解雙緩沖繪圖的基本原理,但是在研究很久之後才大概知道具體的使用過程,本文將詳細介紹本人在實際項目中使用雙緩沖繪圖的案例。

實現功能:主界面顯示某張包含人臉的圖片,通過dlib detector獲取到人臉上的68個關鍵點,繪制在圖片上顯示,然後通過鼠標拖動圖片上的關鍵點,調整位置,之後保存。雙緩沖主要能夠解決拖動關鍵點時屏幕閃爍的問題,本文主要側重在雙緩沖的實現,其他功能概不介紹。

具體實現:

1.定義全局變量:

CDC dc_mem://內存繪制dc

CDC *dc://繪圖dc

vector<CPoint> face://保存人臉中關鍵點的坐標

CBitmap bitmap; //內存繪圖相關變量

CImage image;

 

2.在OnInitDialog()函數中初始化繪圖dc=GetDC();

3.OnEraseBkgnd()函數直接return true;

  添加函數afx_msg BOOL OnEraseBkgnd(CDC* pDC); 

  添加消息ON_WM_ERASEBKGND();

  這一步很關鍵!!!

4.在OnPaint()中調用DrawOnBuffer()繪圖

 

void CEditLmDlg::DrawOnBuffer()
{
    CRgn rgn;
    rgn.CreateRectRgn(0, 0, image_width, image_height);
    dc->SelectClipRgn(&rgn);

    dc_mem.CreateCompatibleDC(dc);
    bitmap.CreateCompatibleBitmap(dc, edit_rect.Width(), edit_rect.Height());
    CBitmap *pOldBit = dc_mem.SelectObject(&bitmap);
    dc_mem.FillSolidRect(edit_rect, dc->GetBkColor());

    dc_mem.SetStretchBltMode(HALFTONE);
    CRect rect(0, 0, image_width, image_height);
    image.Draw(dc_mem.m_hDC, rect);
    
    dc->BitBlt(0, 0, edit_rect.Width(), edit_rect.Height(), &dc_mem, 0, 0,SRCCOPY);
   
    /**將所有的點繪制到dc_mem上*/代碼略

    dc->SelectClipRgn(NULL);
    dc_mem.DeleteDC();
    bitmap.DeleteObject();
}

 

函數中CreateRectRgn函數設置裁剪區可以保證刷新時只刷新圖片的部分,不刷新圖片外的其他控件,這樣其他控件就不會出現閃爍的情況,另外函數結束時要將裁剪區設置為空。

5.至於拖動關鍵點的操作需要調用以下三個函數,以及聲明對應的三個消息即可,在OnLButtonUp,OnMouseMove中將變化後的點的坐標更新到face中,並調用Invalidate()即可。

 

afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
afx_msg void OnMouseMove(UINT nFlags, CPoint point);

ON_WM_LBUTTONDOWN()
ON_WM_LBUTTONUP()
ON_WM_MOUSEMOVE()

 綜上,雙緩沖繪圖的關鍵是怎麼把所有的繪圖操作放到一個繪圖函數中,該過程可能需要很多的全局變量來保存繪圖相關數據。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved