截图Desktop DirectX C ++ / QT

时间:2017-04-20 22:59:14

标签: c++ qt directx screenshot

我正在尝试在C ++中创建一个简单的代码来制作屏幕截图并获取像素缓冲区(RGB)。 我正在使用DirectX但是我遇到了分段错误。我遵循了一些我发现的代码,但没有。

这是我的代码:

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

}

有人能帮助我吗?

2 个答案:

答案 0 :(得分:0)

如果你有一个QQuickWindow及其句柄,并且想要捕获该窗口中可见的内容,你可以这样做:

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

答案 1 :(得分: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需要的时间更少。