2017-04-20 3 views
0

J'essaie de créer un code simple en C++ pour faire une capture d'écran et obtenir le buffer des pixels (RGB). J'utilise DirectX mais j'ai une erreur de segmentation. J'ai suivi un code que j'ai trouvé mais rien.Screenshot Desktop DirectX C++/QT

voici mon code:

static void* pBits; 
static IDirect3DDevice9* g_pd3dDevice; 

void Screenshot::dxCaptureScreen() { 
IDirect3DSurface9* pSurface; 
g_pd3dDevice->CreateOffscreenPlainSurface(_screenWidth, _screenHeight, D3DFMT_A8R8G8B8, D3DPOOL_SCRATCH, &pSurface, NULL); //Segfault here. 
g_pd3dDevice->GetFrontBufferData(0, pSurface); 
D3DLOCKED_RECT lockedRect; 
pSurface->LockRect(&lockedRect, NULL, D3DLOCK_NO_DIRTY_UPDATE | D3DLOCK_NOSYSLOCK | D3DLOCK_READONLY); 

for (int i = 0; i < _screenHeight; i++) { 
    memcpy((BYTE*)pBits + i * _screenWidth * 32/8, (BYTE*) lockedRect.pBits + i * lockedRect.Pitch, _screenWidth * 32/8); 
} 
pSurface->UnlockRect(); 
pSurface->Release(); 

} 

quelqu'un peut me aider s'il vous plaît?

Répondre

0

Si vous avez un QQuickWindow et une poignée, et vous voulez capturer ce qui est visible dans cette fenêtre, vous pouvez simplement faire ceci:

QQuickWindow* window = qobject_cast<QQuickWindow*>(mYourWindowHandle); 
QPixmap screenshot = window->grabWindow(); 
+0

Nous vous remercions de votre réponse. Je sais de cette façon dans QT, le problème est que je veux appeler cette fonction beaucoup et envoyer des images via des sockets pour simuler une mise en miroir dans un autre appareil. Donc, je cherche l'efficacité ... Je voulais utiliser DirectX – DevAndroid

+0

@DevAndroid, vous trouverez probablement que l'envoi des images et/ou de les compresser prendra beaucoup plus de temps que la capture d'écran et serait mieux regarder l'optimisation après le développement de votre solution avec la manipulation de Qt capturant l'écran. – TheDarkKnight

+0

C'est vrai, je vais utiliser quelque chose de totalement différent. Je n'enverrai que lorsqu'il y aura un mouvement et que les pixels changeront à l'écran ... Ce serait mieux et plus efficace. – DevAndroid

0

Je résolu mon problème sur la façon de prendre capture d'écran avec DirectX, voici mon code:

int Screenshot::dxCaptureScreen() { 
int      ret = 0; 

IDirect3DDevice9  *g_pd3dDevice; 
D3DPRESENT_PARAMETERS d3dpp; 
IDirect3D9    *g_pD3D = NULL; 
IDirect3DSurface9  *pSurface; 
D3DLOCKED_RECT   lockedRect; 

g_pD3D = Direct3DCreate9(D3D_SDK_VERSION); 

if (g_pD3D == NULL) 
    return 0; 

ZeroMemory(&d3dpp, sizeof(d3dpp)); 

d3dpp.Windowed = TRUE; 
d3dpp.SwapEffect = D3DSWAPEFFECT_COPY; 
d3dpp.BackBufferFormat = D3DFMT_UNKNOWN; 
d3dpp.BackBufferCount = 1; 
d3dpp.MultiSampleType = D3DMULTISAMPLE_NONE; 
d3dpp.MultiSampleQuality = 0; 
d3dpp.EnableAutoDepthStencil = TRUE; 
d3dpp.AutoDepthStencilFormat = D3DFMT_D16; 
d3dpp.hDeviceWindow = hDesktopWnd; 
d3dpp.Flags = D3DPRESENTFLAG_LOCKABLE_BACKBUFFER; 
d3dpp.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT; 
d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT; 

if ((ret = g_pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hDesktopWnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &g_pd3dDevice)) != D3D_OK) 
    return ret; 
if ((ret = g_pd3dDevice->CreateOffscreenPlainSurface(_screenWidth, _screenHeight, D3DFMT_A8R8G8B8, D3DPOOL_SCRATCH, &pSurface, NULL)) != D3D_OK) 
    return ret; 
if ((ret = g_pd3dDevice->GetFrontBufferData(0, pSurface)) != D3D_OK) 
    return ret; 

pSurface->LockRect(&lockedRect, NULL, D3DLOCK_NO_DIRTY_UPDATE | D3DLOCK_NOSYSLOCK | D3DLOCK_READONLY); 
for (int i = 0; i < _screenHeight; i++) { 
    memcpy(pPixels + i * _screenWidth * 32/8, (BYTE*) lockedRect.pBits + i * lockedRect.Pitch, _screenWidth * 32/8); 
} 

Je l'ai remarqué pas très rapide ... Avec GDI Windows, il prend moins de temps.