2017-04-20 75 views
0

我想在C++中做一个简单的代码来制作截图并获得像素(RGB)的缓冲区。 我使用的是DirectX,但出现了分段错误。我遵循我发现的一些代码,但没有。截图桌面DirectX C++/QT

这里是我的代码:

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(); 

} 

有人能帮助我吗?

回答

0

如果你有QQuickWindow和它的句柄,和你想捕捉的是在该窗口可见,你可以简单地这样做:

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

谢谢你的回答。我在QT中知道这种方式,问题是我想调用这个函数很多,并通过套接字发送图像来模拟其他设备中的镜像。所以我在寻找效率......我想使用DirectX – DevAndroid

+0

@DevAndroid,你可能会发现发送图像和/或压缩它们将花费比截图更长的时间,并且在开发解决方案后会更好地考虑优化用Qt处理捕获屏幕。 – TheDarkKnight

+0

的确如此,我会用完全不同的东西。只有在屏幕上出现运动和像素变化时,我才会发送......这会更好,更高效。 – DevAndroid

0

我解决我如何采取截图与问题DirectX,这里是我的代码:

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); 
} 

我注意到它并不是非常快......使用GDI Windows需要更少的时间。