6

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

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

使用另一个库的解决方案也将不胜感激。

4

4 回答 4

2

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

于 2014-03-25T19:05:40.503 回答
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->data 的大小如下:memBM->width * memBM->height * memBM->bytesPerPixel

希望这至少对您有所帮助。

于 2014-01-06T14:58:03.453 回答
0

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

  1. RDP 客户端从远程会话接收更新
  2. RDP 客户端将更新转换为 X11 消息,很可能通过共享内存传输发送
  3. VNC 服务器接收 X11 请求并使用它们来渲染位图

所以开销应该只是 X11 协议,它固然笨重,但至少应该通过共享内存段发送。

老实说,我会先尝试这种零编码方法,看看性能是否真的是个问题。

于 2014-01-06T15:02:36.267 回答
0

WebRTC 可能有一些代码可以帮助您查看,例如屏幕捕获器或窗口捕获器

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

于 2014-01-07T04:37:41.380 回答