VC 截屏性能问题 我在winxp可以直接把帧缓冲映射到用户空间,之后可以直接复制内容,这样截屏应该是最快的但我还不知道在winvista,win7该咋搞 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 能说说具体怎么弄?我试试在WIN7能不能用?另外你测试过这样做一次截屏消耗的时间么? winxp里BitBlt最终也是从帧缓冲复制,但到达这一步要经过一堆其他步骤winvista开始显卡驱动结构发生了很大的变化,所以xp的方法不能用 最近在使用media foundation 来做一个屏幕录像机 但是将图像转换到wmv 文件后 所有帧都是黑白色 和模糊的。不知道是什么原因。 用驱动截图吧,参考UVNC_MD_SDK。 我怎么记得有个这么个帖子后来的结论是用DirectX可以提高速度 win7的d3dDevice->GetFrontBufferData截屏最终调用的还是gdi32!BitBltwinxp里面倒是用NtGdiDdLock锁定显存然后在用户模式复制 确实啊。前面我错了。之后做测试,结果也符合你所说的。我是WIN7平台的,用DX来截屏,速度确实比不上BitBlt。请问大侠,有什么好办法呢?还有想请教一下你,你所说的在WIN7下最终调用GDI32,而在WINXP下会是另外一种模式。那么在软件发布后,难道在不同平台会有不同的调用方式? directX 如何截图?求代码 .h头文件//DX IDirect3D9* mv_pD3D; IDirect3DDevice9* mv_pd3dDevice; IDirect3DSurface9* mv_pSurface; RECT mv_screenRect; bool mv_bCapturing; LPVOID mv_pBits; HDC mv_hBackDC; HBITMAP mv_hBackBitmap; HBITMAP mv_hOldBitmap; NOTIFYICONDATA mv_nid; int mv_nDisplayWidth; int mv_nDisplayHeight;.cpp文件的函数实现////////DXBOOL CBmpManager::InitDX(){ ///初始化变量 mv_pD3D=NULL; mv_pd3dDevice=NULL; mv_pSurface=NULL; mv_screenRect.left=0; mv_screenRect.right=0; mv_screenRect.top=0; mv_screenRect.bottom=0; mv_bCapturing=false; mv_pBits=NULL; mv_hBackDC=NULL; mv_hBackBitmap=NULL; mv_hOldBitmap=NULL; /// if(FAILED(InitD3D(NULL))){ AfxMessageBox(_T("Failed to InitD3D!")); return FALSE; } return TRUE;}HRESULT CBmpManager::InitD3D(HWND hWnd){ D3DDISPLAYMODE ddm; D3DPRESENT_PARAMETERS d3dpp; if((mv_pD3D=Direct3DCreate9(D3D_SDK_VERSION))==NULL) { AfxMessageBox(_T("Unable to Create Direct3D ")); return E_FAIL; } if(FAILED(mv_pD3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT,&ddm))) { AfxMessageBox(_T("Unable to Get Adapter Display Mode")); return E_FAIL; } ////// ddm.Height=ddm.Height; ddm.Width=ddm.Width; ////// ZeroMemory(&d3dpp,sizeof(D3DPRESENT_PARAMETERS)); d3dpp.Windowed=WINDOW_MODE; d3dpp.Flags=D3DPRESENTFLAG_LOCKABLE_BACKBUFFER; d3dpp.BackBufferFormat=ddm.Format; d3dpp.BackBufferHeight=mv_nDisplayHeight=mv_screenRect.bottom =ddm.Height; d3dpp.BackBufferWidth=mv_nDisplayWidth=mv_screenRect.right =ddm.Width; d3dpp.MultiSampleType=D3DMULTISAMPLE_NONE; d3dpp.SwapEffect=D3DSWAPEFFECT_DISCARD; d3dpp.hDeviceWindow=hWnd; d3dpp.PresentationInterval=D3DPRESENT_INTERVAL_DEFAULT; d3dpp.FullScreen_RefreshRateInHz=D3DPRESENT_RATE_DEFAULT; if(FAILED(mv_pD3D->CreateDevice(D3DADAPTER_DEFAULT,D3DDEVTYPE_HAL,hWnd,D3DCREATE_SOFTWARE_VERTEXPROCESSING ,&d3dpp,&mv_pd3dDevice))) { AfxMessageBox(_T("Unable to Create Device")); return E_FAIL; } if(FAILED(mv_pd3dDevice->CreateOffscreenPlainSurface(ddm.Width, ddm.Height, D3DFMT_A8R8G8B8, D3DPOOL_SCRATCH, &mv_pSurface, NULL))) { AfxMessageBox(_T("Unable to Create Surface")); return E_FAIL; } return S_OK;}LPD3DXBUFFER CBmpManager::GetBmpFromRectDX(CRect cRect){ //HBITMAP hBitmap; static int i=0; ////// LARGE_INTEGER m_liPerfFreq={0}; //获取每秒多少CPU Performance Tick QueryPerformanceFrequency(&m_liPerfFreq); ////// LPD3DXBUFFER lpD3DBuf; mv_pd3dDevice->GetFrontBufferData(0, mv_pSurface); LARGE_INTEGER liPerfStart={0}; QueryPerformanceCounter(&liPerfStart); ///// RECT rect; rect.left=cRect.left; rect.top=cRect.top; rect.bottom=cRect.bottom; rect.right=cRect.right; CString szFileName; szFileName.Format(_T("hooksBmp/ScreenShot%d.jpg"),i++);// D3DXSaveSurfaceToFile(szFileName,D3DXIFF_JPG,mv_pSurface,NULL,&rect); D3DXSaveSurfaceToFileInMemory(&lpD3DBuf, D3DXIFF_BMP,mv_pSurface,NULL,&rect); ///////////////////////////////////// LARGE_INTEGER liPerfEnd={0}; QueryPerformanceCounter(&liPerfEnd); int time=(int)(((liPerfEnd.QuadPart - liPerfStart.QuadPart) * 1000)/m_liPerfFreq.QuadPart); return lpD3DBuf;} D3D和GDI截屏性能是一样的,WIN7下测试过了。 winxp里面倒是用NtGdiDdLock锁定显存然后在用户模式复制 那位帅哥知道怎么实现啊 这个方法我有试过了,对于游戏不全屏的情况下可以正常,但是如果游戏全屏之后,那createdevice这边就会出错,如果把这个函数里面的句柄改为NULL,同样创建失败 快速截屏:是在WIN7下可以的吗? 截屏这个我有看过很多人说用mirror driver这个技术,但是我在win7下安装不了这个驱动,也没有源代码啊,不知道哪位大侠有这方面的资料的,帮帮忙啊!!!! 主机头怎么写 高手请进 关于CWorkBooks的Add. 请问指定程序使用VPN怎么实现? 我愿出钱200元,请高手为我编一个多媒体播放器,DEMO即可!! 请求帮助 刚完成一个扑克牌游戏,欢迎各位网友指正 VC如何实现网页自动登录 VC GDI绘图 关于NetApi的编译问题 MFC使对话框最大化后,任务栏也被遮住了,去掉任务栏的遮盖? 绘制曲线的问题
winvista开始显卡驱动结构发生了很大的变化,所以xp的方法不能用
后来的结论是用DirectX可以提高速度
winxp里面倒是用NtGdiDdLock锁定显存然后在用户模式复制
请问大侠,有什么好办法呢?还有想请教一下你,你所说的在WIN7下最终调用GDI32,而在WINXP下会是另外一种模式。那么在软件发布后,难道在不同平台会有不同的调用方式?
//DX
IDirect3D9* mv_pD3D;
IDirect3DDevice9* mv_pd3dDevice;
IDirect3DSurface9* mv_pSurface;
RECT mv_screenRect;
bool mv_bCapturing;
LPVOID mv_pBits;
HDC mv_hBackDC;
HBITMAP mv_hBackBitmap;
HBITMAP mv_hOldBitmap;
NOTIFYICONDATA mv_nid;
int mv_nDisplayWidth;
int mv_nDisplayHeight;
.cpp文件的函数实现
////////DX
BOOL CBmpManager::InitDX()
{
///初始化变量
mv_pD3D=NULL;
mv_pd3dDevice=NULL;
mv_pSurface=NULL;
mv_screenRect.left=0;
mv_screenRect.right=0;
mv_screenRect.top=0;
mv_screenRect.bottom=0;
mv_bCapturing=false;
mv_pBits=NULL;
mv_hBackDC=NULL;
mv_hBackBitmap=NULL;
mv_hOldBitmap=NULL; ///
if(FAILED(InitD3D(NULL))){
AfxMessageBox(_T("Failed to InitD3D!"));
return FALSE;
}
return TRUE;
}HRESULT CBmpManager::InitD3D(HWND hWnd)
{
D3DDISPLAYMODE ddm;
D3DPRESENT_PARAMETERS d3dpp; if((mv_pD3D=Direct3DCreate9(D3D_SDK_VERSION))==NULL)
{
AfxMessageBox(_T("Unable to Create Direct3D "));
return E_FAIL;
} if(FAILED(mv_pD3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT,&ddm)))
{
AfxMessageBox(_T("Unable to Get Adapter Display Mode"));
return E_FAIL;
} //////
ddm.Height=ddm.Height;
ddm.Width=ddm.Width;
//////
ZeroMemory(&d3dpp,sizeof(D3DPRESENT_PARAMETERS)); d3dpp.Windowed=WINDOW_MODE;
d3dpp.Flags=D3DPRESENTFLAG_LOCKABLE_BACKBUFFER;
d3dpp.BackBufferFormat=ddm.Format;
d3dpp.BackBufferHeight=mv_nDisplayHeight=mv_screenRect.bottom =ddm.Height;
d3dpp.BackBufferWidth=mv_nDisplayWidth=mv_screenRect.right =ddm.Width;
d3dpp.MultiSampleType=D3DMULTISAMPLE_NONE;
d3dpp.SwapEffect=D3DSWAPEFFECT_DISCARD;
d3dpp.hDeviceWindow=hWnd;
d3dpp.PresentationInterval=D3DPRESENT_INTERVAL_DEFAULT;
d3dpp.FullScreen_RefreshRateInHz=D3DPRESENT_RATE_DEFAULT; if(FAILED(mv_pD3D->CreateDevice(D3DADAPTER_DEFAULT,D3DDEVTYPE_HAL,hWnd,D3DCREATE_SOFTWARE_VERTEXPROCESSING ,&d3dpp,&mv_pd3dDevice)))
{
AfxMessageBox(_T("Unable to Create Device"));
return E_FAIL;
} if(FAILED(mv_pd3dDevice->CreateOffscreenPlainSurface(ddm.Width, ddm.Height, D3DFMT_A8R8G8B8, D3DPOOL_SCRATCH, &mv_pSurface, NULL)))
{
AfxMessageBox(_T("Unable to Create Surface"));
return E_FAIL;
} return S_OK;
}
LPD3DXBUFFER CBmpManager::GetBmpFromRectDX(CRect cRect)
{
//HBITMAP hBitmap;
static int i=0;
//////
LARGE_INTEGER m_liPerfFreq={0};
//获取每秒多少CPU Performance Tick
QueryPerformanceFrequency(&m_liPerfFreq);
//////
LPD3DXBUFFER lpD3DBuf;
mv_pd3dDevice->GetFrontBufferData(0, mv_pSurface); LARGE_INTEGER liPerfStart={0};
QueryPerformanceCounter(&liPerfStart);
///// RECT rect;
rect.left=cRect.left;
rect.top=cRect.top;
rect.bottom=cRect.bottom;
rect.right=cRect.right; CString szFileName;
szFileName.Format(_T("hooksBmp/ScreenShot%d.jpg"),i++);
// D3DXSaveSurfaceToFile(szFileName,D3DXIFF_JPG,mv_pSurface,NULL,&rect);
D3DXSaveSurfaceToFileInMemory(&lpD3DBuf,
D3DXIFF_BMP,mv_pSurface,NULL,&rect); /////////////////////////////////////
LARGE_INTEGER liPerfEnd={0};
QueryPerformanceCounter(&liPerfEnd); int time=(int)(((liPerfEnd.QuadPart -
liPerfStart.QuadPart) * 1000)/m_liPerfFreq.QuadPart); return lpD3DBuf;
}
那位帅哥知道怎么实现啊
这个方法我有试过了,对于游戏不全屏的情况下可以正常,但是如果游戏全屏之后,那createdevice这边就会出错,如果把这个函数里面的句柄改为NULL,同样创建失败
快速截屏:是在WIN7下可以的吗?