Linuxでの画面キャプチャの最速の方法
この質問はこれに似ています
ただし、linux/X11の場合。
具体的には、X11ディスプレイで実行されている1つのウィンドウ(プログラムではWindowsのAlt-Print画面に相当)のピクセル画像をキャプチャする方法が必要です。
注意事項と要件:
1)キャプチャされているウィンドウの上に新しいウィンドウが配置されている場合でも、ピクセル画像は元のアプリケーションウィンドウを指している必要があります。
2)アプリケーションウィンドウをユーザーに表示する必要はありません。ビデオ用にピクセルバッファ/画像を保存するだけです。
私が調査した他の選択肢は次のとおりです。
1)xvfb-動作しますが、CPUレンダリングを実行します。これは遅く、優れたGPUを無駄にします。
2)多くのlxc内のx11-理論的には機能する可能性がありますが、セットアップが複雑であり、多くのウィンドウがキャプチャされてもうまくスケーリングできるかどうかはわかりません
提案やアイデアは大歓迎です
これは、ハードウェアアクセラレーションを備えたサーバーで VirtualGL を使用して可能です。基本的には、サーバーを適切に構成してから、同じマシンまたは同じネットワーク内のマシンで実行します。
export DISPLAY=<your xvfb display>
vglrun <your_app>
これには次の利点があります。
1)アプリは、ハードウェアを使用するvirtualGLを使用してレンダリングします
2)VirtualGLはXfvbディスプレイ内に3Dコンテキストを表示し、CPUで2Dウィジェットのみをレンダリングします
3)フレームバッファーにレンダリングするようにXvfbを構成します
4)利益!
これは純粋なX11では不可能です。
合成で必要なものを取得できますが、それをサポートするサーバーでのみ使用できます(最新のサーバーのほとんどがサポートしています)。これは実際にはウィンドウマネージャーとは何の関係もありません。 WMは、いくつかの特別な機能はありますが、単なる別のクライアントですが、それらは合成とは関係ありません。同じ合成APIを使用できます。
man xcomposite
始めるべきです。
xwd(1) を使用してX11ウィンドウをダンプできます(そして xwud(1) を使用して表示できます)。 ImageMagick および Netpbmツール 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);
}
Xpaintは、MIT Athenaウィジェットセットを使用して構築された非常に古いX11ユーティリティです。ファイル>スナップショットを取得すると、ウィンドウまたはマウスで選択した長方形が画面から取得されます。
OR
MagiCaptureは、X WindowSystem用の画面キャプチャおよびプレビューユーティリティです。ユーザーは、単一のウィンドウ、装飾が施された単一のウィンドウ、ディスプレイの長方形の領域、またはディスプレイ自体全体をキャプチャできます。ユーザーは、キャプチャした画像をImageMagickツールキットでサポートされているグラフィックファイルに保存できます。このツールキットは、すべてではないにしても、ほとんどの一般的なグラフィック形式をサポートしています。 MagiCaptureは、ユーザーインターフェイスにGLIBおよびGTK +ライブラリを使用し、すべてのグラフィックス処理にImageMagickおよびGdkMagickライブラリを使用します。 ImageMagickが必要です。
OR
Zscreen :-このWindows専用のスクリーンキャプチャアプリにはたくさんの機能があります。アクティブなウィンドウ、選択したウィンドウ、または画面全体のショットを取得します。画像を取得したら、画像エディタで自動的に開くか、Twitpic、YFrog、Flickr、またはその他のサポートされているサービスの1つにアップロードします。 ZScreenは、クリップボードにあるものも含め、すべての画像をキャッシュするため、スクリーンショットの履歴がいつでもすぐに利用できます。
これは単なる推測ですが、x11vncを-id [windowid](http://www.karlrunge.com/x11vnc/x11vnc_opts.html#opt-id)オプションとともに使用して、VNCを介してその単一のウィンドウをストリーミングできると思います。 。これにより、ウィンドウが覆われている場合でも、メイン画面とまったく同じ位置でウィンドウ全体が表示されます(一部のポップアップメニューが失われる可能性があります)。真のX11画面からウィンドウ座標を取得できます。
ローカルネットワークでのトリッキーなハッキングでできることは、Xリモート機能を使用してXリッスンポートを開き、env varを使用してエクスポートをXリッスンポートに設定してから、XscreenCaptureを使用することです。