Как мне прочитать изображение, которое сейчас находится в буфере кадра в Qt/C?

Есть ли способ прочитать содержимое фреймбуфера в Qt или, во всяком случае, в C? Я читал, что можно записать содержимое /dev/fb0 в файл, а затем загрузить его. Но можно ли не сохранять его в памяти и просто скопировать в новую ячейку памяти для использования в Qt? Спасибо!


person Luca Carlon    schedule 18.08.2011    source источник
comment
Предположительно, вы говорите о доступе к какому-то снимку экрана низкого уровня для Qt, встроенного в linux концепцию фреймбуфера, и не говорите о реальном фреймбуфере Qt class< /i> для OpenGL... который просто имеет метод toImage()...? doc.qt.nokia.com/4.7-snapshot/qglframebufferobject.html# к изображению   -  person HostileFork says dont trust SE    schedule 18.08.2011
comment
Я никогда раньше не видел этот класс... кажется интересным :-) в любом случае я хотел бы сделать снимок экрана низкого уровня, независимо от того, что отрисовывалось в фреймбуфере. Я видел, что некоторые интересные структуры находятся в заголовке фреймбуфера, но я нигде не могу найти информацию о них.   -  person Luca Carlon    schedule 18.08.2011
comment
Если вам нужен этот низкий уровень, вы можете посмотреть исходный код fbgrab, который находится здесь: hem .bredband.net/gmogmo/fbgrab.   -  person Torp    schedule 18.08.2011
comment
На самом деле это может быть лучшим решением этой проблемы. Я не прошел, потому что уже решил прочитать ответы. Спасибо!   -  person Luca Carlon    schedule 19.08.2011


Ответы (2)


Обычный дистрибутив Qt вряд ли будет иметь специальную поддержку чтения фреймбуфера в Linux. Он накладывается поверх X11 и пытается обеспечить кроссплатформенность (поскольку такие вещи, как /dev/fb0, например, не будут иметь значения в Windows). Таким образом, вы должны использовать абстракции более высокого уровня, такие как QPixmap::grabWindow() на что указывает @BerkDemirkir ... вероятно, много переходов между слоями перед кадровым буфером.

(Примечание: если вы пишете обычное кросс-платформенное приложение Qt, предназначенное для работы в оконной среде, это, безусловно, тот путь, по которому вы пойдете для простой задачи захвата экрана!!)

С другой стороны, Qt/Embedded предназначен для Linux и для работы с QWS вместо X11. Мысль такова, что оконной системы нет, и ваше приложение владеет всем экраном. Он записывает напрямую в фреймбуфер через объект QScreen, у которого есть метод base(), который фактически может дать вам указатель на базовую память:

http://doc.qt.nokia.com/4.7-snapshot/qscreen.html#base

Это, вероятно, единственные способы "Qt" делать такие вещи. Если вам нужен API вместо того, чтобы напрямую обращаться к /dev/fb0, вы можете исследовать что-то вроде EZFB. (Я не копал достаточно глубоко, чтобы узнать, полезно это или нет, просто нашел его с запросом вроде «linux framebuffer API»)

http://freshmeat.net/projects/ezfb/

person HostileFork says dont trust SE    schedule 18.08.2011
comment
Просто чтобы уточнить, моя проблема заключалась в том, чтобы просто сделать снимок фреймбуфера. Меня устраивал любой способ, как на Qt, так и на простом C/C++. Решение, которое я принял, использует метод QApplication::desktopWidget() и предложенный QPixmap::grabWindow(). Я точно не знаю, как работают эти классы, но, похоже, они делают то, что мне нужно. Это довольно неожиданно, так как я пишу на экран, используя как OpenGL/EGL, так и QWS с собственной реализацией QScreen, которую я сделал. Один и тот же метод работает как в Qt/Embedded, так и в QT/X11. В любом случае, может быть интересно узнать, как это сделать, используя fb напрямую. Спасибо! - person Luca Carlon; 19.08.2011
comment
Говоря здесь, исходя из интуиции, я могу ошибаться, но: если вы пройдете через grabWindow(), вы не сможете с уверенностью сказать, что захватываете устройство фреймбуфера, которое показывается пользователю. Вероятно, X-сервер должен решить, что вам дать, в переводе с точки зрения его виртуализированного дисплея. В большинстве случаев это просто фреймбуфер. Но, например: это может быть виртуальный экран, намного больший, чем физический дисплей. Опять же, это все предположения, мои знания в основном исходят из старого оцепенения C-64 или ModeX. :) - person HostileFork says dont trust SE; 19.08.2011
comment
Меня больше интересует, что происходит в Qt/X11. Это интересно, принимая также во внимание, что OpenGL/EGL также захватывается. - person Luca Carlon; 19.08.2011
comment
Меня бы удивило, если бы сервер X11 не был достаточно осведомлен, чтобы захватить его. Но случались и более безумные вещи... Раньше у меня была карта декодирования DVD на ПК, куда вы подключали выход своей видеокарты, а затем снимали видео с новой карты. Приложение DVD-плеера просто поместило большой фиолетовый прямоугольник, а затем карта объединила изображение DVD-фильма в этот прямоугольник. Если бы вы попытались сделать снимок фильма, вы бы не смогли... просто фиолетовый прямоугольник! К счастью, OpenGL/EGL на X11, по-видимому, не так уж и плох! - person HostileFork says dont trust SE; 19.08.2011
comment
:-) единственная проблема в том, что я полностью провалил свое последнее сообщение... возможно, слишком поздно :-) Я имел в виду, что меня больше интересует Qt/Embedded. Вот почему я был очень удивлен, что в кадре появился OpenGL/EGL. - person Luca Carlon; 19.08.2011

Вы можете посмотреть этот пример, чтобы сделать скриншот из любое окно (даже рабочий стол). В примере используется функция QScreen::grabWindow() для создания снимка экрана.

person useraged    schedule 18.08.2011
comment
Первая ссылка мертва - person Tomilov Anatoliy; 22.11.2017
comment
Обновлено до Qt5 и новых ссылок qt.io. - person useraged; 22.11.2017