正在做一个视频捕捉的程序。
现在已经做好了双缓冲绘制,在视频上画一个十字线,不闪烁。代码类似这个样子:
pdc = GetDlgItem(IDC_VIDEO_WINDOW )->GetDC();
crColor = RGB(255,0,0); CPen myPen;
myPen.CreatePen( PS_DOT, 1, crColor );
pdc->SetBkMode(TRANSPARENT);
pdc->SetBkMode(
CPen * oldPen = pdc->SelectObject( &myPen );
int x=wrc.right;
int y=wrc.bottom;
m_pMemDC->CreateCompatibleDC(pdc);
m_dcBack->CreateCompatibleDC(pdc);
m_pMemBitmap->CreateCompatibleBitmap(pdc,x,y);
m_pBakBitmap->CreateCompatibleBitmap(pdc,x,y);
m_pOldBitmap = m_pMemDC->SelectObject(m_pMemBitmap);
m_dcBack->SelectObject(m_pBakBitmap);
m_pMemDC->SetBkMode(TRANSPARENT);
m_pMemDC->SelectObject(&myPen );
CBrush* brush = CBrush::FromHandle((HBRUSH)GetStockObject(NULL_BRUSH));
oldBrush = m_pMemDC->SelectObject(brush);
if(pdc != NULL)
{
m_pMemDC->BitBlt(0, 0, x, y, m_dcBack, 0, 0, SRCCOPY);
POINT pt = m_pMemDC->MoveTo( xStart );
m_pMemDC->LineTo( xStop );
pt = m_pMemDC->MoveTo( yStart );
m_pMemDC->LineTo( yStop );
pdc->BitBlt(0,0,x,y,m_pMemDC,0,0,SRCCOPY);
m_pMemDC->SelectObject(m_pOldBitmap);
m_pMemBitmap->DeleteObject();
m_pMemDC->SelectObject(oldBrush);
brush->DeleteObject();
m_pMemDC->DeleteDC();
this->ReleaseDC( pdc );
}视频被双缓冲的前景给挡住了。
该如何实现这种透明绘制,也就是说,最终的画面是背后出现摄像头画面,而前景是十字线,并且移动十字线的时候不闪烁。
现在已经做好了双缓冲绘制,在视频上画一个十字线,不闪烁。代码类似这个样子:
pdc = GetDlgItem(IDC_VIDEO_WINDOW )->GetDC();
crColor = RGB(255,0,0); CPen myPen;
myPen.CreatePen( PS_DOT, 1, crColor );
pdc->SetBkMode(TRANSPARENT);
pdc->SetBkMode(
CPen * oldPen = pdc->SelectObject( &myPen );
int x=wrc.right;
int y=wrc.bottom;
m_pMemDC->CreateCompatibleDC(pdc);
m_dcBack->CreateCompatibleDC(pdc);
m_pMemBitmap->CreateCompatibleBitmap(pdc,x,y);
m_pBakBitmap->CreateCompatibleBitmap(pdc,x,y);
m_pOldBitmap = m_pMemDC->SelectObject(m_pMemBitmap);
m_dcBack->SelectObject(m_pBakBitmap);
m_pMemDC->SetBkMode(TRANSPARENT);
m_pMemDC->SelectObject(&myPen );
CBrush* brush = CBrush::FromHandle((HBRUSH)GetStockObject(NULL_BRUSH));
oldBrush = m_pMemDC->SelectObject(brush);
if(pdc != NULL)
{
m_pMemDC->BitBlt(0, 0, x, y, m_dcBack, 0, 0, SRCCOPY);
POINT pt = m_pMemDC->MoveTo( xStart );
m_pMemDC->LineTo( xStop );
pt = m_pMemDC->MoveTo( yStart );
m_pMemDC->LineTo( yStop );
pdc->BitBlt(0,0,x,y,m_pMemDC,0,0,SRCCOPY);
m_pMemDC->SelectObject(m_pOldBitmap);
m_pMemBitmap->DeleteObject();
m_pMemDC->SelectObject(oldBrush);
brush->DeleteObject();
m_pMemDC->DeleteDC();
this->ReleaseDC( pdc );
}视频被双缓冲的前景给挡住了。
该如何实现这种透明绘制,也就是说,最终的画面是背后出现摄像头画面,而前景是十字线,并且移动十字线的时候不闪烁。
2. 你这个不是双缓冲。只用pdc和m_pMemDC就实现双缓冲了。做法是:
把你的视频图像画到m_pMemDC,然后再在m_pMemDC上画线,最后把m_pMemDC上画好的东西BitBlt到pdc上
每次需要更新界面时,先调用m_pMemDC的封装函数,然后使窗口重绘。
CDC *dc= GetDC();//得到CDC的DC
MemDC.CreateCompatibleDC(dc);//随后建立与屏幕显示兼容的内存显示设备
CBitmap MemBitmap;//定义一个位图对象//建立一个与屏幕显示兼容的位图,至于位图的大小嘛,可以用窗口的大小
MemBitmap.CreateCompatibleBitmap(dc,Width,Height);
//将位图选入到内存显示设备中
//只有选入了位图的内存显示设备才有地方绘图,画到指定的位图上
CBitmap *pOldBit=MemDC.SelectObject(&MemBitmap)
StretchDIBits(MemDC.m_hDC,0,0,Width,Height,0,0,Width,Height,M_CBmpInfo,pbufferInfo,DIB_RGB_COLORS,SRCCOPY)//把图象画在缓存上.
//定义画笔
CPen *oldpen;
MemDC.SelectStockObject(NULL_BRUSH);
oldpen=MemDC.SelectObject(&newpen);
...................//画十子架
dc->BitBlt(0,0,Width,Height,&MemDC,0,0,SRCCOPY);//把缓存上面的图形再拷贝到显示屏上面.
MemDC.SelectObject(oldpen);
MemDC.SelectObject(pOldBit);
MemDC.DeleteDC();
MemBitmap.DeleteObject();
dc->DeleteDC();
视频是摄像头视频,用directshow捕捉的,在picturecontrol里面显示,然后在视频上画十字线,不用双缓冲的,移动线的时候,会闪烁,用了双缓冲,视频就被十字线的前景给挡住了。
归根到底,还是直接拿到图像数据方便。从现成的control上搞数据总是不保险。
需要有摄像头。不要也可以。
StretchDIBits(MemDC.m_hDC,//定义内存的DC
0, //显示窗口宽度x起点
0, //显示窗口宽度y起点
Width, //显示窗口宽度
Height, //显示窗口高度
0,
0,
Width, //图像宽度
Height, //图像高度
M_BmpInfo,//保存图象的指针
pbufferInfo,//BMP图像描述信息
DIB_RGB_COLORS,
SRCCOPY
);
pdc->BitBlt(0,0,Width,Height,&MemDC,0,0,SRCCOPY);//把缓存上面的图形再拷贝到显示屏上面.