我想实现一个 RDP 客户端,C++
它能够获取屏幕所有像素的颜色值并将它们转储到文件中。我知道这在概念上与 RDP 的工作方式不同,但我的应用程序需要它。我正在尝试使用freerdp,但我不确定如何有效地编写一个简单地将所有像素转储到文件中的客户端。
到目前为止,我最好的尝试是使用该函数gdi_GetPixel_32bpp
,但当然为每个像素依次调用此函数远非高效。
使用另一个库的解决方案也将不胜感激。
这应该很容易使用 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() 以了解内部缓冲区的初始化。
那么你可以试试这个(免责声明未经测试的伪代码):
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
希望这至少对您有所帮助。
如果您运行 VNC X 服务器并在其中全屏启动 RDP 客户端(没有窗口管理器等),则绘图顺序应类似于:
所以开销应该只是 X11 协议,它固然笨重,但至少应该通过共享内存段发送。
老实说,我会先尝试这种零编码方法,看看性能是否真的是个问题。