2017-04-20 9 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(); 

} 

누군가가 제발 도와 드릴까요 : 여기

내 코드? 당신이 QQuickWindow과 핸들을 가지고 있고, 그 창에서 볼 수 있습니다 무엇을 캡처 할 경우

답변

0

, 당신은 단순히이 작업을 수행 할 수 있습니다

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의 경우 시간이 오래 걸립니다.