桌面截图DirectX C++/QT 我试图用C++编写一个简单的代码来进行屏幕截图,得到像素的缓冲区。 我正在使用DirectX,但我有一个分段错误。我找到了一些代码,但什么也没找到

桌面截图DirectX C++/QT 我试图用C++编写一个简单的代码来进行屏幕截图,得到像素的缓冲区。 我正在使用DirectX,但我有一个分段错误。我找到了一些代码,但什么也没找到,c++,qt,directx,screenshot,C++,Qt,Directx,Screenshot,这是我的密码: static void* pBits; static IDirect3DDevice9* g_pd3dDevice; void Screenshot::dxCaptureScreen() { IDirect3DSurface9* pSurface; g_pd3dDevice->CreateOffscreenPlainSurface(_screenWidth, _screenHeight, D3DFMT_A8R8G8B8, D3DPOOL_SCRATCH, &pSu

这是我的密码:

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

}
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);
}
static void*pBits;
静态IDirect3DDevice9*g_pd3dDevice;
无效屏幕截图::dxCaptureScreen(){
IDirect3DSurface9*pSurface;
g_pd3dDevice->CreateOffscreenPlainSurface(_屏幕宽度,_屏幕高度,D3DFMT_A8R8G8B8,D3DPOOL_划痕,&pSurface,NULL);//此处有故障。
g_pd3dDevice->GetFrontBufferData(0,pSurface);
D3DLOCKED_u-RECT lockedRect;
pSurface->LockRect(&lockedRect,NULL,D3DLOCK_NO_DIRTY_UPDATE | D3DLOCK_NOSYSLOCK | D3DLOCK_READONLY);
对于(int i=0;i<\u屏幕高度;i++){
memcpy((字节*)pBits+i*_屏幕宽度*32/8,(字节*)lockedRect.pBits+i*lockedRect.Pitch,_屏幕宽度*32/8);
}
pSurface->UnlockRect();
pSurface->Release();
}

有人能帮我吗?

如果您有一个QQuickWindow及其句柄,并且您想捕获该窗口中可见的内容,您可以简单地执行以下操作:

QQuickWindow* window = qobject_cast<QQuickWindow*>(mYourWindowHandle);
QPixmap screenshot = window->grabWindow(); 
QQuickWindow*window=qobject\u cast(mYourWindowHandle);
QPixmap屏幕截图=窗口->抓取窗口();

我解决了如何使用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();

}
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);
}
int屏幕截图::dxCaptureScreen(){
int-ret=0;
IDirect3DDevice9*g_pd3dDevice;
D3D当前参数d3dpp;
IDirect3D9*g_pD3D=NULL;
IDirect3DSurface9*pSurface;
D3DLOCKED_u-RECT lockedRect;
g_pD3D=Direct3DCreate9(D3D_SDK_版本);
如果(g_pD3D==NULL)
返回0;
零内存(&d3dpp,sizeof(d3dpp));
d3dpp.Windowed=TRUE;
d3dpp.SwapEffect=d3dswapeeffect\u拷贝;
d3dpp.BackBufferFormat=D3DFMT_未知;
d3dpp.BackBufferCount=1;
d3dpp.MultiSampleType=D3DMULTISAMPLE\u无;
d3dpp.MultiSampleQuality=0;
d3dpp.EnableAutoDepthStencil=TRUE;
d3dpp.AutoDepthStencilFormat=D3DFMT_D16;
d3dpp.hDeviceWindow=hDesktopWnd;
d3dpp.Flags=D3DPRESENTFLAG\u LOCKABLE\u BACKBUFFER;
d3dpp.FullScreen\u RefreshRateInHz=D3DPRESENT\u RATE\u默认值;
d3dpp.PresentationInterval=D3DPPresent\u INTERVAL\u默认值;
如果((ret=g_pD3D->CreateDevice(D3DAAPTER_默认值、D3DDEVTYPE_HAL、hDesktopWnd、D3DCREATE_软件_VERTEXPROCESSING、d3dpp和g_pd3dDevice))!=D3D_正常)
返回ret;
如果((ret=g_pd3dDevice->CreateOffscreenPlainSurface(_屏幕宽度、屏幕高度、D3DFMT_A8R8G8B8、D3DPOOL_划痕和pSurface、NULL))!=D3D_正常)
返回ret;
如果((ret=g_pd3dDevice->GetFrontBufferData(0,pSurface))!=D3D_OK)
返回ret;
pSurface->LockRect(&lockedRect,NULL,D3DLOCK_NO_DIRTY_UPDATE | D3DLOCK_NOSYSLOCK | D3DLOCK_READONLY);
对于(int i=0;i<\u屏幕高度;i++){
memcpy(像素+i*屏幕宽度*32/8,(字节*)lockedRect.pBits+i*lockedRect.Pitch,_屏幕宽度*32/8);
}

我注意到它不是很快…使用GDI Windows需要更少的时间。

谢谢你的回答。我知道在QT中使用这种方法,问题是我想经常调用此函数,并通过套接字发送图像以模拟其他设备中的镜像。所以我在寻找效率…我想使用DirectX@DevAndroid,您可能会发现发送图像和/或压缩它们将比屏幕截图花费更长的时间,并且在使用Qt处理捕获屏幕开发解决方案后,会更好地进行优化。这是真的,我将使用完全不同的东西。我将仅在屏幕上出现移动和像素变化时发送…这将更好、更有效古董。