【问题标题】:How to take screenshot (high fps) in Linux (programming)如何在 Linux 中截屏(高 fps)(编程)
【发布时间】:2014-09-29 12:26:06
【问题描述】:

首先我想说的是,我已经阅读了很多关于这方面的内容,并且我已经学会了很多方法来做到这一点,但是我无法在 linux 中做到这一点。

我的项目是 arduino 的流光溢彩,所以我需要截取桌面的屏幕截图并分析其颜色。

一开始,我使用 Processing 2.0 和“java.awt”中的“Robot”类。最初我可以每秒拍摄 5 帧,然后我得到了 13fps。这行得通,但我想要更多的性能,所以我开始阅读。

在 Windows 或 Mac 中,您拥有可让您直接访问“frameBuffer”的库,因此您可以非常“轻松”且非常快速地截取屏幕截图。

在 Ubuntu 中,我尝试了 Python 与 Gtk、PIL、Qt...,最快的方法是 GTK,但我也只能有大约 15fps。

我的问题是:我想跨平台做,但我更喜欢我的程序一开始在 Linux 中运行,然后在 Windows 中运行(我不太喜欢它:P)。

那么,第一个问题:python 是否能够提供这种性能?因为我认为 C++ 可能是一个更好的选择。

第二个问题:我需要做什么?我已经阅读了有关 Xlib (X11) 的信息,但找不到让我截屏的文档。我也知道,例如 FFmpeg,它是一个强大的工具,但我不知道如何实现它。

我希望你能帮助我(如果我犯了任何错误,请原谅我)。

【问题讨论】:

  • manpages.ubuntu.com/manpages/hardy/man1/fbgrab.1.html你试过fbgrab吗?也许这会对你有所帮助,只是一个想法。
  • @cerkiewny 它可能很有用,但它是从终端启动并将 img 保存到我必须再次读取的文件中(它可能会更慢?),但我们可以阅读代码并看看如何做到了。
  • @pirobtumen 您可以通过简单的阅读直接访问 /dev/fb1,但是用户空间中的任何活动都需要从帧缓冲区复制大量内核空间数据。我同意你可以做得比保存到文件更好。
  • @cerkiewny 我可以尝试测量速度。

标签: python c++ linux ffmpeg screenshot


【解决方案1】:

使这项工作跨平台可能需要相当多的工作。如果您的最终目标是 windows,那么为什么不使用 amblone 项目,它似乎完全符合您的要求?

http://amblone.com/guide

无论如何,这里有一个非常快的 ffmpeg 和 graphicsmagick 解决方案(在我的 i7 8GB 笔记本电脑上)。 ffmpeg 只捕获一个屏幕,将其缩小到最小的正方形大小,将输出通过管道传输到 graphicsmagick convert,在此将其大小调整为 1x1 像素,然后报告图像 rgb 值。

#!/bin/bash

mkfifo /tmp/screencap.fifo

while true
    do
        # this version will send the info to a fifo
        # ffmpeg -y -loglevel error -f x11grab -s 1920x1080 -i :0.0 -s 32x32 \
        # -vframes 1 -f image2 -threads 2 - |  gm convert - -resize 1x1 \
        # txt:- > /tmp/screencap.fifo

        # this version will write out the info to the command line
        # and will show you what is going on.
        ffmpeg -y -loglevel error -f x11grab -s 1920x1080 -i :0.0 -s 32x32 \
         -vframes 1 -f image2 -threads 2 - |  gm convert - -resize 1x1 txt:-
    done
exit

这将为您提供以下内容:

0,0: ( 62, 63, 63) #3E3F3F
0,0: (204,205,203) #CCCDCB
0,0: ( 77, 78, 76) #4D4E4C

0,0 是被读取像素的位置。括号中的数字是各自的 R、G、B 值,最后的数字是典型的 html 式十六进制值。在上面的例子中,只有 1 个像素,但您可以(如果您想将基本方向作为通用 RGB 值)只需将上面的 -resize 1x1 部分更改为 -resize 3x3,您会得到类似的结果:

0,0: ( 62, 63, 65) #3E3F41
1,0: ( 90, 90, 91) #5A5A5B
2,0: (104,105,106) #68696A
0,1: ( 52, 51, 52) #343334
1,1: ( 60, 60, 59) #3C3C3B
2,1: ( 64, 64, 64) #404040
0,2: ( 49, 49, 50) #313132
1,2: ( 60, 60, 60) #3C3C3C
2,2: ( 65, 65, 65) #414141

我会留给您将该信息传递给您的 arduino。

ffmpeg 很棒,但您必须记住,无论您的 Windows 系统使用什么,都要切换屏幕捕获位(在我的示例中为 -f x11grab)。这是一个SO link,它更详细一点。

如果你真的坚持做跨平台的东西,那么我建议你深入使用 python 绑定的 openCV 并使用帧缓冲设备作为视频输入,将结果缩小到 1x1 像素并使用生成的颜色平均值来驱动你的pwm 通过某种类型的 UDP 广播。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-03-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-09
    • 2011-01-13
    • 1970-01-01
    相关资源
    最近更新 更多