如何在Linux(编程)中拍摄截图(高帧频) [英] How to take screenshot (high fps) in Linux (programming)

查看:167
本文介绍了如何在Linux(编程)中拍摄截图(高帧频)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

首先我想说的是,我一直在阅读很多关于这一点,我已经学到了很多方法来做,但是我还没有在linux中做到这一点。



我的项目是arduino的氛围,所以我需要拍摄桌面的屏幕截图并分析其颜色。



我使用Processing 2.0与'java.awt'类'Robot'。最初我可以每秒拍5帧,然后我得到13fps。这个工作,但我想要更多的性能,所以我开始阅读。



在Windows或Mac中,您有可以直接访问frameBuffer的库,因此您可以截图真的很容易,真的很快。



在Ubuntu中,我尝试过使用Gtk,PIL,Qt的python,而最快的方式是GTK,但我只能我的问题是:我想做跨平台,但是我更喜欢我的程序在Linux中开始,然后在Windows中工作(我没有'太好了:P)。



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



第二个问题:我需要做什么?我已经阅读过Xlib(X11),但是我找不到让我拍摄截图的文档。另外我知道,例如,FFmpeg这是一个强大的工具,但我不知道如何实现它。



我希望你能帮助我如果我犯了错误的话)。

解决方案

使这个工作跨平台有可能是相当多的工作。如果你的最终目标是Windows,那么为什么不使用这个似乎完全符合你想要的安腾项目呢?



http://amblone.com/guide



无论如何,这里是一个ffmpeg& ; graphicsmagick是非常快的(在我的i7 8GB笔记本电脑)。 ffmpeg 仅捕获一个屏幕,将其缩小到最小的正方形尺寸,将输出管道传输到graphicsmagick转换,将其调整为1x1像素,然后报告图像rgb值。

 #!/ bin / bash 

mkfifo /tmp/screencap.fifo

while true
do
#此版本将信息发送到fifo
#ffmpeg -y -loglevel错误-f x11grab -s 1920x1080 -i:0.0 -s 32x32 \
#-vframes 1 -f image2 -threads 2 - | gm convert - -resize 1x1 \
#txt: - > /tmp/screencap.fifo

#这个版本会写出命令行
#的信息,并显示你正在发生的事情。
ffmpeg -y -loglevel错误-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 很棒,但是你必须记住切换屏幕捕获位(在我的示例中为这个例子 -f x11grab )与无论您的Windows系统使用什么以下是 SO链接,详细内容。



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


First of all I want to say that I've been reading a lot about this and I've learnt many ways to do it, but I haven't been able to do it in linux.

My project is an ambilight with arduino, so I need to take a screenshot of the desktop and analyze its colour.

At the beginning I used Processing 2.0 with the class 'Robot' from 'java.awt'. Initially I could take 5 frames per second and then I got 13fps. This works but I want more perfomance, so I start reading.

In Windows or Mac you have libraries that let you access directly to the 'frameBuffer', so you can take screenshot really 'easy' and really fast.

In Ubuntu I have tried python with Gtk, PIL, Qt... and the fastest way is GTK but I can only have about 15fps too.

My problem is: I want to do it cross platform but I prefer that my program work in Linux at the beginning and then in Windows (I don't like it too much :P).

So, the first question: is python able to offer that perfomance? Because I think that C++ can be a better option.

And the second question: what do I need to do it? I've read about Xlib (X11) but I can't find documentation that let me take a screenshot. Also I know, for example, FFmpeg which is a powerful tool but I don't know how to implement it.

I hope that you could help me (and excuse me if I've made any mistakes).

解决方案

Making this work cross platform is likely to be quite a bit of work. If your final target is windows, then why not use the amblone project, which seems to do exactly what you want?

http://amblone.com/guide

At any rate, here is a solution with ffmpeg & graphicsmagick that is pretty fast (on my i7 8GB laptop). ffmpeg captures exactly one screen, reduces it to the smallest square size that it can, pipes the output to graphicsmagick convert, where it is resized to 1x1 pixel and then reports the image rgb values.

#!/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

This will give you something like the following:

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

The 0,0 is the location of the pixel being read. The numbers in parenthesis are the respective R,G,B values, and the numbers at the end are your typical html-esque hex values. In the case above there is only 1 pixel, but you could (if you wanted to have the cardinal directions as generalized RGB values) simply change the -resize 1x1 part above to -resize 3x3 and you'll get something like:

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

I'll leave it to you to pass that information to your arduino.

ffmpeg is great, but you'll have to remember to switch out the screen-capture bit (here in my example -f x11grab) with whatever your windows system uses. Here is a SO link that goes into a bit more detail.

If you really insist on making something cross-platform, then I would recommend diving into openCV with python bindings and using the framebuffer device as a video input, scaling the result down to 1x1 pixel and using the resulting color average to drive your pwm through some type of UDP broadcast.

这篇关于如何在Linux(编程)中拍摄截图(高帧频)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆