繁体   English   中英

在Linux上进行屏幕捕获的最快方法

[英]Fastest method for screen capturing on Linux

这个问题与此类似

最快的屏幕捕获方法

但是对于linux / X11。

更具体地说,我需要一种方法来捕获在X11显示器上运行的一个窗口(在windows中的alt-print屏幕的程序化等效物)的像素图像。

注意事项和要求:

1)即使在正在捕获的窗口顶部放置一个新窗口,像素图像仍应指向原始应用程序窗口而没有任何遮挡

2)不需要用户看到应用程序窗口,我只需要存储像素缓冲区/图像用于视频目的

我探索的其他替代方案是:

1)xvfb - 它可以工作,但它确实可以进行CPU渲染,这很慢并且浪费了很好的GPU

2)x11里面很多lxc - 理论上可以工作,但设置很复杂,我不确定它会很好地扩展,许多窗口被捕获

欢迎提出建议和想法

纯X11无法实现这一点。

您可以通过合成获得所需的内容,但仅限于支持它的服务器(大多数现代服务器都可以)。 这实际上与窗口管理器无关。 WM只是另一个客户端,虽然有一些特殊的能力,但那些与合成无关。 您可以使用相同的合成API。

man xcomposite应该让你开始。

这可以在具有硬件加速的服务器中使用VirtualGL 基本上只是适当地配置服务器,然后运行在同一台机器上或同一网络中的机器上

export DISPLAY=<your xvfb display>
vglrun <your_app>

这将具有以下优点:

1)您的应用程序将使用虚拟GL渲染,它将使用硬件

2)VirtualGL将在Xfvb显示内部显示您的3D上下文,这只会在CPU中呈现2D小部件

3)配置Xvfb渲染到帧缓冲区

4)利润!

您可以使用xwd(1)转储X11窗口(和xwud(1)来显示它)。 ImageMagickNetpbm工具知道如何处理XWD格式。 但这些并不是特别快。 他们不会透露窗户的隐藏部分。

我会抓住gnome-screenshot的源代码,或其他一些现有的开源工具,并弄清楚他们是如何做到这一点的。

你可以在这里找到Ubuntu使用的来源: http//packages.ubuntu.com/quantal/gnome-screenshot

但是,在剪切和粘贴大部分代码之前,不要忘记检查许可证!

我看过评论说这不能在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);
}

这只是一个疯狂的猜测,但我认为你可以使用x11vnc和-id [windowid](http://www.karlrunge.com/x11vnc/x11vnc_opts.html#opt-id)选项在VNC上传输单个窗口。 这将显示整个窗口,与主屏幕中的定位完全相同(可能会丢失一些弹出菜单),即使它被覆盖也是如此。 您可以从真正的X11屏幕获取窗口坐标。

Xpaint是一个使用MIT Athena小部件集构建的非常古老的X11实用程序。 “文件”>“拍摄快照”将从屏幕中抓取窗口或鼠标选定的矩形。

要么

MagiCapture是X Window系统的屏幕捕获和预览工具。 用户可以捕获单个窗口,具有装饰的单个窗口,显示器的矩形区域或整个显示器本身。 用户可以将捕获的图像保存到ImageMagick工具包支持的图形文件中,该工具包支持大多数(如果不是全部)流行的图形格式。 MagiCapture使用GLIB和GTK +库作为用户界面,使用ImageMagick和GdkMagick库进行所有图形处理。 需要ImageMagick。

要么

Zscreen : - 这款仅限Windows的屏幕截图应用程序具有大量功能。 它抓取活动窗口,选定窗口或整个屏幕的镜头。 获得图像后,在图像编辑器中自动打开图像或将其上传到Twitpic,YFrog,Flickr或其他几种受支持的服务之一。 ZScreen会缓存您的所有图像,甚至是剪贴板上的图像,因此您的屏幕截图始终都在触手可及。

在本地网络中使用棘手的黑客可以做的是使用X远程功能打开您的X侦听端口,然后使用env var将导出设置为X侦听端口,然后使用XscreenCapture

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM