屏幕截图桌面DirectX C /QT

Screenshot Desktop DirectX C++/QT

本文关键字:QT DirectX 桌面 屏幕截图      更新时间:2023-10-16

我正在尝试在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();
}

有人可以帮我吗?

我解决了有关如何使用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窗口,花费的时间更少。

如果您有一个qquickwindow和一个手柄,并且想捕获该窗口中可见的内容,则可以简单地执行此操作:

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