注册 登录
编程论坛 VC++/MFC

采用双缓冲技术显示来自串口接收到的灰度图像数据

hlmzrdongdong 发布于 2013-11-01 20:44, 670 次点击
我的任务是,串口发送采集的灰度图像数据,这些数据只有各像素点的像素值,因此不能采用MFC的CBitmap类直接显示,必须人工填充BITMAP的像素值部分。
此外,在采用MFC自绘时,经常用到双缓冲技术来避免闪烁。于是有了下面的解决方案:

程序代码:
  CRect rt;
    GetDlgItem(IDC_PIXAREA)->GetClientRect(&rt);//IDC_PIXAREA是用于显示图像的图片控件的ID
    HWND hPixArea=GetDlgItem(IDC_PIXAREA)->GetSafeHwnd();
    HDC hDC=::GetDC(hPixArea);//获得显示区域的设备上下文
    HDC hMemDC=CreateCompatibleDC(hDC);//创建与显示区域设备上下文兼容的内存DC
    HBITMAP hBitmap=CreateCompatibleBitmap(hDC,rt.Width(),rt.Height());//创建与显示区域设备上下文DC兼容的Bitmap
    HGDIOBJ hOldGdiObj=SelectObject(hMemDC,hBitmap);//将Bitmap选入内存DC
   
    for(int i=0;i<rt.Width();i++)//下面用从串口接到的像素值替换Bitmap的像素值区域
        for(int j=0;j<rt.Height();j++)
        {
            SetPixel(hMemDC,i,j,RGB(j+m_BaseIndex,j+m_BaseIndex,j+m_BaseIndex));
        }
        
    StretchBlt(hDC,0,0,rt.Width(),rt.Height(),hMemDC,0,0,rt.Width(),rt.Height(),SRCCOPY);//将在内存DC绘制好的Bitmap复制在显示区域,即完成双缓冲
        
    CString s;
    s.Format("Width=%-3d Height=%-3d GrayValue=%-3d",rt.Width(),rt.Height(),m_BaseIndex);
    SetTextAlign(hDC,TA_CENTER|VTA_CENTER);
    TextOut(hDC,rt.Width()/2,rt.Height()/2,s,s.GetLength());
   
    SelectObject(hMemDC,hOldGdiObj);//恢复原来的GDI对象
    DeleteObject(hBitmap);//有资料显示,hBitmap应该会被自动删除
    DeleteObject(hMemDC);//删除内存DC
    ::ReleaseDC(hPixArea,hDC);//释放显示区域的设备上下文DC


只有本站会员才能查看附件,请 登录


程序代码:
只有本站会员才能查看附件,请 登录
2 回复
#2
我菜1192013-11-03 00:31
CString s;
s.Format("Width=%-3d Height=%-3d GrayValue=%-3d",rt.Width(),rt.Height(),m_BaseIndex);
SetTextAlign(hDC,TA_CENTER|VTA_CENTER);
TextOut(hDC,rt.Width()/2,rt.Height()/2,s,s.GetLength());


很纳闷,这块为什么不直接绘制到内存DC上,既然创建的位图与源DC一样大,直接用BitBlt函数就行,不必用StretchBlt()
#3
我菜1192013-11-03 00:33
双缓冲只是从显卡的显示上解决屏闪的问题,有些时候使用双缓冲未必就不闪了,还要考虑绘制的方法,比如说当绘制一张很大的图片时,就算使用双缓冲未必不闪!
1