如何在Linux中编程截图(高fps)(编程)

时间:2014-08-06 14:08:40

标签: python c++ linux ffmpeg screenshot

首先,我想说我已经阅读了很多关于此的内容,并且我已经学到了许多方法,但我还没有能够在linux中做到这一点。

我的项目是一个带有arduino的流光溢彩,所以我需要截取桌面的截图并分析它的颜色。

一开始我使用了处理2.0和类#Robot;#39;来自' java.awt'。最初我可以每秒拍摄5帧,然后我得到13帧。这有效,但我想要更多性能,所以我开始阅读。

在Windows或Mac中,您可以使用图书馆直接访问“FrameBuffer”,这样您就可以轻松获取屏幕截图'而且非常快。

在Ubuntu中,我尝试过使用Gtk,PIL,Qt的python ......最快的方法是GTK,但我也只能有大约15fps。

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

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

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

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

1 个答案:

答案 0 :(得分:1)

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

http://amblone.com/guide

无论如何,这是一个ffmpeg& amp; 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-esque十六进制值。在上面的例子中,只有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并使用framebuffer设备作为视频输入,将结果缩小到1x1像素并使用生成的颜色平均值来驱动你的pwm通过某种类型的UDP广播。