Напишите RDP-клиент, который выводит пиксели экрана

Я хотел бы реализовать клиент RDP в C++ который может получить значение цвета всех пикселей экрана и вывести их в файл. Я знаю, что это концептуально отличается от того, как работает RDP, но мне это нужно для моего приложения. Я пытаюсь использовать freerdp но я не уверен, как эффективно написать клиент, который просто сбрасывает все пиксели в файле.

Пока что моя лучшая попытка — использовать функцию gdi_GetPixel_32bpp но, конечно, вызов этой функции для каждого пикселя по очереди далеко не эффективен.

Решение, которое использует другую библиотеку, также будет высоко ценится.

6

Решение

Ну, вы можете попробовать это (отказ от проверки непроверенного псевдокода):

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

Надеюсь, что это поможет вам хотя бы в некоторой степени.

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 () для инициализации внутреннего буфера.

1

Если вы запустите VNC X-сервер и запустите на нем полноэкранный клиент RDP (без оконного менеджера и т. Д.), Последовательность рисования должна выглядеть примерно так:

  1. RDP-клиент получает обновление от удаленного сеанса
  2. RDP-клиент преобразует обновление в сообщения X11, скорее всего, отправленные через транспорт с общей памятью
  3. VNC-сервер получает запросы X11 и использует их для отображения растрового изображения

таким образом, накладные расходы должны быть просто протоколом X11, который по общему признанию неуклюж, но должен по крайней мере быть послан через сегмент совместно используемой памяти.

Честно говоря, я сначала попробую этот подход с нулевым кодированием и посмотрим, действительно ли проблема в производительности.

0

WebRTC может иметь некоторый код, на который вы можете посмотреть, чтобы помочь, например, захват экрана или же захватчик окон.

Устройство захвата рабочего стола является более сложным, потому что оно выполняет (1) дифференцирование для захвата минимального содержимого, и (2) также захватывает мышь. Поскольку рабочий стол — это просто специальное «окно», как ::GetDesktopWindow(), И его DC можно получить с помощью этого окна или просто GetDC(NULL)Вы можете использовать средство захвата окна и игнорировать более сложные биты. Проверьте функцию захвата оконного захвата для деталей, а также некоторые полезные советы по обработке Aero и другие вопросы композитинга / за кадром.

0
По вопросам рекламы [email protected]