2017-04-20 4 views
0

Ich versuche, einen einfachen Code in C++ zu machen, um einen Screenshot zu machen und den Puffer von Pixeln (RGB) zu bekommen. Ich verwende DirectX, aber ich habe einen Segmentierungsfehler. Ich folgte einem Code, den ich fand, aber nichts.Screenshot Desktop DirectX C++/QT

hier ist mein 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(); 

} 

Kann mir jemand helfen bitte?

Antwort

0

Wenn Sie einen QQuickWindow und einen Griff zu ihm haben, und Sie wollen, zu erfassen, was in diesem Fenster sichtbar ist, können Sie einfach tun:

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

Vielen Dank für Ihre Antwort. Ich kenne diesen Weg in QT, Problem ist, dass ich diese Funktion viel aufrufen und Bilder über Sockets senden möchte, um eine Spiegelung in einem anderen Gerät zu simulieren. Also ich bin auf der Suche nach Effizienz ... Ich wollte DirectX – DevAndroid

+0

@DevAndroid verwenden, Sie werden wahrscheinlich feststellen, dass das Senden und Komprimieren der Bilder viel länger dauert als der Screenshot und die Optimierung nach der Entwicklung Ihrer Lösung besser aussehen würde mit Qt-Handling, um den Bildschirm zu erfassen. – TheDarkKnight

+0

Das stimmt, ich werde etwas völlig anderes benutzen. Ich werde nur senden, wenn es eine Bewegung gibt und Pixel auf dem Bildschirm ändern ... Es wäre besser und effizienter. – DevAndroid

0

löste ich mein Problem, wie Screenshot machen mit DirectX, hier ist mein 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); 
} 

ich bemerkte es nicht sehr schnell ... Mit GDI Windows-es weniger Zeit in Anspruch nimmt.