晃了好多论坛了,没一个人具体做过这个东西或是能给出一点具体的解决方案.问题其实不麻烦我想做的工作是:用VC做一个程序每隔十秒钟截一次屏,截获的数据要保存成文件传到服务器上去.我遇到的问题是:1:截屏其实并不难,可当运行到GetDIBits时,CPU占用的特别高,整个屏幕会非常的慢,由于我要截获的屏幕上大部分情况下是在播放视频,所有截屏的时候会一顿一顿的,效果非常不好,
请问哪位用过其他的什么好办法同样可以截屏却不耗费那么大资源?或是分块截屏也行,但本人水平有限,确实不会实现...2:不知道做过截屏的朋友们遇到过没有,反正我是遇到了,就是把截下来的屏幕存成文件后,如果屏幕上此时正在放的视频,那么当你打开截下来的图片文件时,图片上的视频区域居然不是静止的,而是和屏幕上放的视频一起动!!!哪位遇到过,请多多指教这其中的原因.
请问哪位用过其他的什么好办法同样可以截屏却不耗费那么大资源?或是分块截屏也行,但本人水平有限,确实不会实现...2:不知道做过截屏的朋友们遇到过没有,反正我是遇到了,就是把截下来的屏幕存成文件后,如果屏幕上此时正在放的视频,那么当你打开截下来的图片文件时,图片上的视频区域居然不是静止的,而是和屏幕上放的视频一起动!!!哪位遇到过,请多多指教这其中的原因.
你遇到的问题应该是你的程序处理有问题!我也写过截屏的程序,是用gdiplus来处理的!考虑网络传送的问题,建议最好将图片存为jpg格式,然后再传送!
www.software168.com
{
CDC dc;
dc.CreateDC("DISPLAY",NULL,NULL,NULL); char filename[128];
memset(filename,0,sizeof(filename)); int nX = 0;
int nY = 0;
int Width=GetSystemMetrics(SM_CXSCREEN);
int Height=GetSystemMetrics(SM_CYSCREEN); CBitmap bm;
bm.CreateCompatibleBitmap(&dc,Width,Height);
CDC tdc;
tdc.CreateCompatibleDC(&dc);
CBitmap*pOld=tdc.SelectObject(&bm);
tdc.BitBlt(0,0,Width,Height,&dc,nX,nY,SRCCOPY);
tdc.SelectObject(pOld);
BITMAP btm;
bm.GetBitmap(&btm);
DWORD size=btm.bmWidthBytes*btm.bmHeight;
LPSTR lpData=(LPSTR)GlobalAllocPtr(GPTR,size); BITMAPINFOHEADER bih;
bih.biBitCount=btm.bmBitsPixel;
bih.biClrImportant=0;
bih.biClrUsed=0;
bih.biCompression=0;
bih.biHeight=btm.bmHeight;
bih.biPlanes=1;
bih.biSize=sizeof(BITMAPINFOHEADER);
bih.biSizeImage=size;
bih.biWidth=btm.bmWidth;
bih.biXPelsPerMeter=0;
bih.biYPelsPerMeter=0;
GetDIBits(tdc,bm,0,bih.biHeight,lpData,(BITMAPINFO*)&bih,DIB_RGB_COLORS);
BITMAPFILEHEADER bfh;
bfh.bfReserved1=bfh.bfReserved2=0;
bfh.bfType=((WORD)('M'<< 8)|'B');
bfh.bfSize=54+size;
bfh.bfOffBits=54; CFile bf;
if(bf.Open(path,CFile::modeCreate|CFile::modeWrite)){
bf.WriteHuge(&bfh,sizeof(BITMAPFILEHEADER));
bf.WriteHuge(&bih,sizeof(BITMAPINFOHEADER));
bf.WriteHuge(lpData,size);
bf.Close();
}
else
return FALSE; GlobalFreePtr(lpData);
return TRUE;
}
void *pBits=NULL;
CRect rect;//客户区窗口
GetClientRect(&rect);
int nWidth=rect.right;
int nHeight=rect.bottom;
//填充信息头
ZeroMemory(&bi,sizeof(bi));
bi.bmiHeader.biSize=sizeof(bi.bmiHeader);
bi.bmiHeader.biHeight=nHeight;
bi.bmiHeader.biWidth=nWidth;
bi.bmiHeader.biPlanes=1;
bi.bmiHeader.biBitCount=24;
bi.bmiHeader.biCompression=BI_RGB;
bi.bmiHeader.biSizeImage=3*nWidth*nHeight;//拷贝客户区至内存DC
CDC dc;
dc.CreateDC("DISPLAY",NULL,NULL,NULL);
HDC hActiveDC=dc.m_hDC;
HDC hActiveWndCompatibleDC=CreateCompatibleDC(hActiveDC);
HDC hActiveWndCompactibleBitmap=CreateCompatibleBitmap(hActiveDC,rect.right,rect.bottom);
SelectObject(hActiveWndCompatibleDC,hActiveWndCompactibleBitmap);//保存内存DC
HDChBmpFileDC=CreateCompatibleDC(hActiveWndCompatibleDC);
HBITMAPhBmpFileBitmap=CreateDIBSection(hActiveWndCompatibleDC,&bi,DIB_RGB_COLORS,&pBits,NULL,0);
SelectObject(hBmpFileDC,hBmpFileBitmap);
BitBlt(hBmpFileDC,0,0,nWidth,nHeight,hActiveWndCompatibleDC,0,0,SRCCOPY);CString tempFileName;//目标文件名
HANDLEhFile=CreateFile(tempFileName,GENERIC_WRITE,FILE_SHARE_WRITE,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);
if(hFile!=INVALID_HANDLE_VALUE)
{
DWORDdwRet=0;
//填充文件头
BITMAPFILEHEADERbmfHeader;
ZeroMemory(&bmfHeader,sizeof(bmfHeader));
bmfHeader.bfOffBits=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER);
bmfHeader.bfSize=bi.bmiHeader.biSizeImage+bmfHeader.bfOffBits;
bmfHeader.bfType='MB';
WriteFile(hFile,&bmfHeader,sizeof(bmfHeader),&dwRet,NULL);
WriteFile(hFile,&bi.bmiHeader,sizeof(bi.bmiHeader),&dwRet,NULL);
WriteFile(hFile,pBits,bi.bmiHeader.biSizeImage,&dwRet,NULL);
CloseHandle(hFile);
}
int nWidth=rect.right;
int nHeight=rect.bottom;
处存的是电子书程序的窗口宽和高,要全屏的话这里要写入屏幕的宽和高
for(int i=0;i<8;i++)
{
char filename[128];
memset(filename,0,sizeof(filename));
sprintf(filename,"monitor_%d.bmp",i)
SaveScreenToBitmap(filename);
}那么我的想法是能不能在SaveScreenToBitmap函数中先一次性取到屏幕的数据,然后在分次的调用GetDIBits一块一块的取数据呢?比方说:
BOOL SaveScreenToBitmap(char *path)
{
......
先准备好屏幕的数据,然后:
for(int i=0;i<8;i++)
{
GetDIBits();//不知道这儿该怎么写?
}
......
}
这种想法有问题吗?能不能实现??
bm.CreateCompatibleBitmap(&dc,Width,Height);
这两个好像没有看到释放的
可这也没解决任何问题啊
看来csdn也全军覆没了......
那就只好覆没了
开始->运行->dxdiag->显示->DirectDraw 加速(把这个禁用), 这样就可以用GDI来截图了,视频也可以正常播放。我用BitBlt做的截屏程序能成功截屏,按PrintScreen也有效。
希望有用。
请问把DirectDraw 加速这个东西去掉,会不会影响视频播放的质量呢?
您说的办法我这就去试
您的办法解决了第二个问题,谢谢您了.就这么结贴了,第一个问题我还是决定分块截屏,虽然图象错位了,可总算是能截到了.我确实是没分了,可别嫌少啊,呵呵.