Utiliser DirectX pour capturer l’écran sous Windows

J’expérimentais des méthodes de capture d’écran sur Windows et décidais par conséquent du moyen le plus rapide de le faire. Le plus courant est évidemment la voie GDI. Et c’est aussi une performance décente. Selon la charge du système et le contenu d’écran statique / non statique, le taux de capture d’écran variait de 27 à 47 ips (Windows 7, Intel i5@ 2,6 GHz, 8 Go de RAM).

Maintenant, avec l’approche du tampon frontal DirectX (en utilisant l’API GetFrontBufferData ()), les performances étaient comparables mais légèrement inférieures (je ne pouvais pas atteindre 48 fps).

J’ai parcouru ce post: La méthode la plus rapide de capture d’écran et la méthode testée dans la réponse acceptée en utilisant getRenderTarget () et getRenderTargetData (), mais comme le suggèrent les commentaires, je n’ai qu’une image noire. Voici mon code complet, y compris les configurations initiales pour le périphérique:

IDirect3DSurface9* pRenderTarget=NULL; IDirect3DSurface9* pDestTarget=NULL; // sanity checks. if (g_pd3dDevice == NULL){ return; } HRESULT hr; // get the render target surface. hr = g_pd3dDevice->GetRenderTarget(0, &pRenderTarget); // get the current adapter display mode. //hr = pDirect3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT,&d3ddisplaymode); // create a destination surface. hr = g_pd3dDevice->CreateOffscreenPlainSurface(1600, 900, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &pDestTarget, NULL); //copy the render target to the destination surface. hr = g_pd3dDevice->GetRenderTargetData(pRenderTarget, pDestTarget); D3DLOCKED_RECT lockedRect; hr =pDestTarget->LockRect(&lockedRect,NULL, D3DLOCK_NO_DIRTY_UPDATE|D3DLOCK_NOSYSLOCK|D3DLOCK_READONLY); for( int i=0 ; i < 900 ; i++) { for(int j=0; j UnlockRect(); // clean up. pRenderTarget->Release(); pDestTarget->Release(); 

Et pour la partie Initialisation du périphérique:

 g_pDirect3D = Direct3DCreate9(D3D_SDK_VERSION); D3DPRESENT_PARAMETERS PresentParams; memset(&PresentParams, 0, sizeof(D3DPRESENT_PARAMETERS)); PresentParams.Windowed = TRUE; PresentParams.SwapEffect =D3DSWAPEFFECT_DISCARD; g_pDirect3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL ,GetDesktopWindow(),D3DCREATE_SOFTWARE_VERTEXPROCESSING, &PresentParams,&g_pd3dDevice); 

Veuillez signaler l’erreur dans le code ci-dessus. Toutes les suggestions sont les bienvenues. J’ai également essayé l’API GetBackBuffer () mais je n’ai pas pu obtenir les données d’image.

MODIFIER:

Mon cas d’utilisation était de capturer l’écran du bureau, ce qui semble être fait uniquement avec GetFrontBufferData () via directX. GetBackBuffer () / GetRenderTargetData () n’est pas la bonne API à appeler pour ce cas. Référence: La capture du bureau avec DirectX ne fonctionne pas et Comment obtenir la capture d’écran du bureau à partir du tampon arrière avec DirectX .

Cependant, les suggestions concernant une méthode plus rapide pour capturer l’écran du bureau ou optimiser le mode GDI sont les bienvenues.

Avez-vous rendu quelque chose avant de prendre la capture d’écran?

  • GetFrontBufferData – cette fonction récupère les données de l’écran
  • GetRenderTargetData – cette fonction récupère les données de la cible de rendu

Donc, si vous n’avez rien rendu, vous aurez certainement une image vierge.