2017-04-20 45 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では...ない非常に速いことに気づきました。