编写一个转储屏幕像素的RDP客户端

时间:2014-01-03 14:17:50

标签: c++ rdp freerdp

我想在C++中实现一个RDP客户端,它能够获取屏幕所有像素的颜色值并将它们转储到文件中。我知道这在概念上与RDP的工作方式不同,但我需要它用于我的应用程序。我正在尝试使用freerdp,但我不确定如何有效地编写一个只转储文件中所有像素的客户端。

到目前为止,我最好的尝试是使用函数gdi_GetPixel_32bpp,但当然,依次为每个像素调用此函数远非有效。

使用其他库的解决方案也将受到高度赞赏。

4 个答案:

答案 0 :(得分:1)

你可以尝试这个(免责声明未经测试的伪代码):

HGDI_DC memDC = gdi_CreateCompatibleDC ( hDC );
HGDI_BITMAP memBM = gdi_CreateCompatibleBitmap ( hDC, screenWidth, screenHeight );
gdi_SelectObject ( memDC, memBM );
gdi_BitBlt(memDC, 0, 0, screenWidth, screenHeight, hDC, 0, 0, GDI_SRCCOPY);

现在你应该在memBM->data中拥有完整的像素数据数组。 memBM->数据具有以下大小:memBM->width * memBM->height * memBM->bytesPerPixel

希望这至少可以帮助你。

答案 1 :(得分:1)

使用libfreerdp-gdi以非常有效的方式进行此操作应该相当容易。 FreeRDP可以将所有内容呈现给软件缓冲区,然后您可以将其转储到文件中,如果您愿意,可以在内存中完全执行此操作,而无需X11环境。由于提到Linux,一个快速入门的方法是使用xfreerdp和/ gdi:sw选项来使用libfreerdp-gdi(默认是使用基于X11的实现)然后将像素转储为更新你可以把自己挂钩到xf_sw_end_paint中,它在更新数组的末尾被调用。您可以访问无效区域和像素缓冲区(全部在rdpGdi * gdi结构下)。重要的字段是gdi-> primary_buffer,gdi-> dstBpp,gdi-> bytesPerPixel,gdi-> width和gdi-> height。在大多数情况下,您将获得一个易于处理的XRGB32缓冲区。有疑问,请查看gdi_init()以初始化内部缓冲区。

答案 2 :(得分:0)

如果您运行VNC X服务器并在其中启动RDP客户端全屏(没有窗口管理器等),则绘图顺序应为:

  1. RDP客户端从远程会话接收更新
  2. RDP客户端将更新转换为X11消息,最有可能通过共享内存传输
  3. 发送
  4. VNC服务器接收X11请求并使用它们呈现位图
  5. 所以开销应该只是X11协议,这无疑是笨重的,但至少应该通过共享内存段发送。

    老实说,我首先尝试这种零编码方法,看看性能是否确实存在问题。

答案 3 :(得分:0)

WebRTC可能包含一些您可以查看的代码,例如screen capturerwindow capturer

桌面捕获器更复杂,因为它(1)进行差异捕获最小内容,(2)捕获鼠标。由于桌面只是一个特殊的“窗口”,使用::GetDesktopWindow()检索,并且可以使用该窗口或DC检索其GetDC(NULL),因此您可以使用窗口捕获器并忽略更复杂的比特。检查窗口捕获器的捕获功能以获取详细信息,以及有关处理Aero和其他合成/屏幕外问题的一些有用提示。