我想在C++
中实现一个RDP客户端,它能够获取屏幕所有像素的颜色值并将它们转储到文件中。我知道这在概念上与RDP的工作方式不同,但我需要它用于我的应用程序。我正在尝试使用freerdp,但我不确定如何有效地编写一个只转储文件中所有像素的客户端。
到目前为止,我最好的尝试是使用函数gdi_GetPixel_32bpp
,但当然,依次为每个像素调用此函数远非有效。
使用其他库的解决方案也将受到高度赞赏。
答案 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客户端全屏(没有窗口管理器等),则绘图顺序应为:
所以开销应该只是X11协议,这无疑是笨重的,但至少应该通过共享内存段发送。
老实说,我首先尝试这种零编码方法,看看性能是否确实存在问题。
答案 3 :(得分:0)
WebRTC可能包含一些您可以查看的代码,例如screen capturer或window capturer。
桌面捕获器更复杂,因为它(1)进行差异捕获最小内容,(2)捕获鼠标。由于桌面只是一个特殊的“窗口”,使用::GetDesktopWindow()
检索,并且可以使用该窗口或DC
检索其GetDC(NULL)
,因此您可以使用窗口捕获器并忽略更复杂的比特。检查窗口捕获器的捕获功能以获取详细信息,以及有关处理Aero和其他合成/屏幕外问题的一些有用提示。