Linux上最快的屏幕捕获方法
Fastest method for screen capturing on Linux
这个问题与类似
屏幕捕获的最快方法
但适用于linux/X11。
更具体地说,我需要一种方法来捕捉X11 diplay上运行的一个窗口(相当于windows中alt打印屏幕的程序)的像素图像。
注意事项和要求:
1) 即使新窗口被放置在正在捕获的窗口的顶部,像素图像仍然应该指向原始应用程序窗口,而没有任何遮挡
2) 不需要用户看到应用程序窗口,我只需要存储用于视频目的的像素缓冲区/图像
我探索过的其他选择是:
1) xvfb-它可以工作,但它确实进行CPU渲染,这很慢浪费了一个好的GPU
2) x11在许多lxc中-理论上可以工作,但很复杂设置,我不确定它是否能很好地扩展许多窗口捕获的
建议和想法欢迎
在硬件加速的服务器中使用VirtualGL是可能的。基本上只需适当配置服务器,然后在同一台机器上或同一网络中的机器上运行
export DISPLAY=<your xvfb display>
vglrun <your_app>
这将具有以下优点:
1) 您的应用程序将使用virtualGL进行渲染,virtualGL将使用硬件
2) VirtualGL将在Xfvb显示器中显示您的3D上下文,这将只在CPU 中呈现2D窗口小部件
3) 配置Xvfb以渲染到帧缓冲区
4) 利润!
这在纯X11中是不可能的。
你可以通过合成获得你想要的东西,但只能在支持它的服务器上(大多数现代服务器都支持)。这实际上与窗口管理器无关。WM只是另一个客户,尽管有一些特殊的能力,但这些能力与合成无关。您可以使用相同的合成API。
man xcomposite
应该让你开始。
我看到评论说这在X11中无法完成,所以可能有一些我不理解的地方,但我可以使用以下代码捕获屏幕。
#include <X11/Xlib.h> //-lX11
#include <X11/Xutil.h>
#include <X11/Xmd.h>
#include <X11/Xatom.h>
#include <jpeglib.h> //-ljpeg
void CopyDesktopImage(std::string sFilePath_Name)
{
Display *dis=XOpenDisplay((char *)0);
Screen *scr = XDefaultScreenOfDisplay(dis);
Drawable drawable = XDefaultRootWindow(dis);
XImage *image = XGetImage(dis, drawable, 0, 0, scr->width, scr->height, AllPlanes, ZPixmap);
Save_XImage_to_JPG(image, sFilePath_Name.c_str(), 75);
XDestroyImage(image);
XCloseDisplay(dis);
}
void Save_XImage_to_JPG(XImage *image, std::string FileName, int Quality)
{
FILE* outfile = fopen(FileName.c_str(), "wb");
if(outfile == NULL) return;
jpeg_compress_struct cinfo;
jpeg_error_mgr jerr;
cinfo.err = jpeg_std_error(&jerr);
jpeg_create_compress(&cinfo);
jpeg_stdio_dest(&cinfo, outfile);
cinfo.image_width = image->width;
cinfo.image_height = image->height;
cinfo.input_components = image->bitmap_unit >> 3;
cinfo.in_color_space = JCS_EXT_BGRX;
jpeg_set_defaults(&cinfo);
/*set the quality [0..100] */
jpeg_set_quality(&cinfo, Quality, true);
jpeg_start_compress(&cinfo, true);
JSAMPROW row_pointer; /* pointer to a single row */
while (cinfo.next_scanline < cinfo.image_height)
{
row_pointer = (JSAMPROW) &image->data[cinfo.next_scanline*image->bytes_per_line];
jpeg_write_scanlines(&cinfo, &row_pointer, 1);
}
jpeg_finish_compress(&cinfo);
fclose(outfile);
}
您可以使用xwd(1)转储X11窗口(使用xwud(1)显示它)。ImageMagick和Netpbm工具知道如何处理XWD格式。但这些并不是特别快。而且它们不会暴露窗口的隐藏部分。
这只是一个猜测,但我认为您可以将x11vnc与-id[windowid]一起使用(http://www.karlrunge.com/x11vnc/x11vnc_opts.html#opt-id)选项,以通过VNC流式传输该单个窗口。这将显示整个窗口,与主屏幕中的位置完全相同(您可能会丢失一些弹出菜单),即使它被覆盖。您可以从真正的X11屏幕获取窗口坐标。
我会获取gnome-screenshot
或其他现有开源工具的来源,并找出它们是如何做到的。
你可以在这里找到Ubuntu使用的来源:http://packages.ubuntu.com/quantal/gnome-screenshot
但是,在剪切和粘贴大部分代码之前,不要忘记检查许可证!
Xpaint是一个非常古老的X11实用程序,使用MIT Athena小部件集构建。文件>拍摄快照将从屏幕上抓取窗口或鼠标选择的矩形。
或
MagiCapture是X Window系统的屏幕捕获和预览实用程序。用户可以捕捉单个窗口、带有装饰的单个窗口、显示器的矩形区域或整个显示器本身。用户可以将捕获的图像保存到ImageMagick工具包支持的图形文件中,该工具包支持大多数(如果不是全部的话)流行的图形格式。MagiCapture将GLIB和GTK+库用于用户界面,将ImageMagick和GdkMagick库用于所有图形处理。需要ImageMagick。
或
Zscreen:-这个仅限Windows的屏幕捕获应用程序有很多功能。它抓取活动窗口、选定窗口或整个屏幕的快照。一旦你得到了图像,就可以在图像编辑器中自动打开它,或者将它上传到Twitpic、YFrog、Flickr或其他一些受支持的服务中。ZScreen会缓存您的所有图像,甚至是剪贴板上的图像,因此您的屏幕截图历史记录总是触手可及。
在本地网络中使用X远程功能打开X侦听端口,然后使用env-var将导出设置为X侦听端口
- 为不同配置设置MSVC_RUNTIME_LIBRARY的正确方法是什么
- 通过方法访问结构
- 最小硬币更换问题(自上而下方法)
- C++为构建时间获取QDateTime的可靠方法
- 在C#中处理C++指针而不使用unsafe的最佳方法
- 处理多个异常集合的C++方法
- 如果C++类在类方法中具有动态分配,但没有构造函数/析构函数或任何非静态成员,那么它仍然是POD类型吗
- 有什么方法可以遍历结构吗
- 当类在C++中定义时,有什么方法可以"register"类吗?
- 在C++中,将大的无符号浮点数四舍五入为整数的最佳方法是什么
- 如何使用方法覆盖在输出屏幕上显示堆栈整数值
- 在MFC C++应用程序中在屏幕上绘制点的最快方法
- Linux上最快的屏幕捕获方法
- 将矩形绘制到屏幕的最有效方法
- 在窗口中的屏幕上获取坐标像素数据的简单方法
- 使用可可和C++时刷新屏幕上数据的正确方法是什么
- 告诉 PDCurses 以编程方式使窗口与物理屏幕大小相同的方法
- 加载屏幕更容易的方法?c++
- 是否有一种简单的方法可以用可互操作的代码在CLI中清理屏幕/保持输出窗口,避免conio.h和ncurses.h
- 重新绘制整个屏幕的正确方法