简体   繁体   English

使用DirectX在Windows上捕获屏幕

[英]Using DirectX to capture screen on Windows

I was experimenting with ways to capture screen on windows and consequently deciding on the fastest way to do so. 我正在尝试在窗口上捕获屏幕的方法,从而决定最快的方法。 The most common is obviously the GDI way. 最常见的是GDI方式。 And it is decent in performance as well. 而且性能也不错。 Depending on the system load and static/non-static screen content, the screen capture rate ranged from 27-47 fps (Windows 7, Intel i5@2.6 GHz, 8 GB RAM). 根据系统负载和静态/非静态屏幕内容,屏幕捕获率范围为27-47 fps(Windows 7,Intel i5 @2.6 GHz,8 GB RAM)。

Now, with DirectX front buffer approach(using the GetFrontBufferData() API), the performance was comparable but slightly on the slower side(I couldn't reach as high as 48 fps). 现在,使用DirectX前端缓冲区方法(使用GetFrontBufferData()API),性能相当,但稍微偏慢(我无法达到48 fps)。

I went through this post: Fastest method of screen capturing and the tried out the way suggested in the accepted answer using getRenderTarget() and getRenderTargetData(), but as suggested in the comments, all I get is a black image. 我仔细阅读了这篇文章: 屏幕截图的最快方法,并尝试使用getRenderTarget()和getRenderTargetData()在接受的答案中建议的方式,但正如评论中所建议的,我得到的只是一个黑色图像。 Here is my complete code including initial configurations for the device: 这是我的完整代码,包括设备的初始配置:

    IDirect3DSurface9* pRenderTarget=NULL;
    IDirect3DSurface9* pDestTarget=NULL;
    // sanity checks.
    if (g_pd3dDevice == NULL){
      return;
    }
    HRESULT hr;
    // get the render target surface.
    hr = g_pd3dDevice->GetRenderTarget(0, &pRenderTarget);
    // get the current adapter display mode.
    //hr = pDirect3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT,&d3ddisplaymode);

    // create a destination surface.
    hr = g_pd3dDevice->CreateOffscreenPlainSurface(1600, 900, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &pDestTarget, NULL);
   //copy the render target to the destination surface.
   hr = g_pd3dDevice->GetRenderTargetData(pRenderTarget, pDestTarget);

   D3DLOCKED_RECT lockedRect;
   hr =pDestTarget->LockRect(&lockedRect,NULL, D3DLOCK_NO_DIRTY_UPDATE|D3DLOCK_NOSYSLOCK|D3DLOCK_READONLY);

    for( int i=0 ; i < 900 ; i++)
    {
        for(int j=0; j < 1600; j++){
            memcpy( (BYTE*) data + i * 1600 * 3 + j * 3, (BYTE*) lockedRect.pBits + i* lockedRect.Pitch + j * 4,  3);
        }
    }
    pDestTarget->UnlockRect();
   // clean up.
   pRenderTarget->Release();
   pDestTarget->Release();

And for the device Initialization part: 对于设备初始化部分:

g_pDirect3D = Direct3DCreate9(D3D_SDK_VERSION); 
D3DPRESENT_PARAMETERS PresentParams; 
memset(&PresentParams, 0, sizeof(D3DPRESENT_PARAMETERS)); 
PresentParams.Windowed = TRUE; 
PresentParams.SwapEffect =D3DSWAPEFFECT_DISCARD;
g_pDirect3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL ,GetDesktopWindow(),D3DCREATE_SOFTWARE_VERTEXPROCESSING, &PresentParams,&g_pd3dDevice);

Please point out the mistake in the above code. 请在上面的代码中指出错误。 Any suggestions are welcome. 欢迎任何建议。 I also tried the GetBackBuffer() API but I couldn't get hold of the image data. 我也尝试了GetBackBuffer()API,但我无法获取图像数据。

EDIT: 编辑:

My use case was to capture desktop screen which seems to be done only using GetFrontBufferData() via directX. 我的用例是捕获桌面屏幕,这似乎只能通过directX使用GetFrontBufferData()来完成。 GetBackBuffer()/GetRenderTargetData() is not the correct API to call for this case. GetBackBuffer()/ GetRenderTargetData()不是调用此案例的正确API。 Reference: The desktop capture with DirectX does not work and How to get the screenshot of the desktop from back buffer with DirectX . 参考: 使用DirectX的桌面捕获不起作用以及如何使用DirectX从后台缓冲区获取桌面的屏幕截图

However, any suggestions to a faster method for capturing desktop screen or optimizing the GDI way are welcome. 但是,欢迎任何有关捕获桌面屏幕或优化GDI方式的更快方法的建议。

Did you render anything before taking the screenshot? 在拍摄截图之前你有没有渲染过什么?

  • GetFrontBufferData - this function get the data of the screen GetFrontBufferData - 此函数获取屏幕数据
  • GetRenderTargetData - this function get the data from render target GetRenderTargetData - 此函数从渲染目标获取数据

So if you didn't render anything, you definitely will got a blank image. 因此,如果你没有渲染任何东西,你肯定会得到一个空白的图像。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM