2012-11-30 4 views
5

これははるかに大きな研究プロジェクトのサブプロジェクトです。私は100msごとにアクティブなウィンドウ(ブラウザ)のスクリーンショットを取ろうとしており、OpenCV処理のためにメモリに保存されます。私は同様の質問からスクリーンショットを撮るという解決策を見つけました。私は現在、コードを使って私がそれを使用できるかどうか確認しています。次のスニペットは、デスクトップのスクリーンショット全体または特定のWindowのスクリーンショットを撮るときに動作しているようですが、GTKウィンドウでは機能しません。私はDebian SqueezeでIceweasel & Nautilusのスクリーンショットを撮ろうとしましたが、うまくいきません。私はX11のトータルのnoobです。エラーをチェックする方法がわからない、またはQTウィンドウでうまくいくようにGTKに欠けているものがあるかどうかはわかりません。アクティブウィンドウのX11スクリーンショットがGTKウィンドウで失敗する

typedef int (*handler)(Display *, XErrorEvent *); 

int handleX11Error(Display *d, XErrorEvent *er) 
{ 
    std::cout << "X11 Error: " << er->error_code << std::endl; 
} 

int main() 
{ 
    std::cout << "Sleeping 5 seconds" << std::endl; 
    // we may need to sleep if we want to focus another window. 
    sleep(5); 
    std::cout << "taking screenshot" << std::endl; 

    Display *display = XOpenDisplay(NULL); 
    //Window root = DefaultRootWindow(display); 
    XWindowAttributes gwa; 
    int revert = RevertToNone; 
    Window active; 
    XErrorEvent *error; 
    handler myHandler = &handleX11Error; 
    XSetErrorHandler(myHandler); 

    // X11 - Get Window that has focus 
    XGetInputFocus(display,&active,&revert); 

    //XGetWindowAttributes(display, root, &gwa); 
    if (!XGetWindowAttributes(display, active, &gwa)) 
    std::cout << "XGetWindowAttributes failed" << std::endl; 

    int width = gwa.width; 
    int height = gwa.height; 

    //XImage *image = XGetImage(display,root, 0,0 , width,height,AllPlanes, ZPixmap); 
    XImage *image = XGetImage(display,active, 0,0 , width,height,XAllPlanes(), ZPixmap); 

    unsigned char *array = new unsigned char[width * height * 3]; 
    CImg<unsigned char> pic(array,width,height,1,3); 

    for (int x = 0; x < width; x++){ 
     for (int y = 0; y < height ; y++){ 
    pic(x,y,0) = (XGetPixel(image,x,y) & image->red_mask) >> 16; 
    pic(x,y,1) = (XGetPixel(image,x,y) & image->green_mask) >> 8; 
    pic(x,y,2) = XGetPixel(image,x,y) & image->blue_mask; 
     } 
    } 
    delete[] array; 
    pic.save_png("blah.png"); 
    std::cout << "Finished" << std::endl; 
    return 0; 
} 

上記のコードは、フルデスクトップスクリーンショットまたはQTのいずれかで動作します。私はエラーを受け取りません(正しく処理しているかどうかわかりません)。何バイトかの空の絵があるので、XGetFocusがうまく動作していないと思うので、X関数の1つ(XGetInputFocus、XGetWindowAttributes、XGetImage)が失敗すると思います。 私には何が欠けているのですか?これに代わる方法はありますか? KDE(4.4.5)が重要であれば実行しています。

UPDATE:

int main(int argc, char **argv) 
{ 
    sleep(5); 
    Display *display = XOpenDisplay(NULL); 
    int revert = RevertToNone; 
    Window active; 
    XGetInputFocus(display,&active,&revert); 
    QApplication app(argc, argv);  
    QPixmap pixmap = QPixmap::grabWindow(active); 
    pixmap.save("test.png","PNG"); 
    QPushButton quit("Quit"); 
    quit.resize(75, 30); 
    quit.setFont(QFont("Times", 18, QFont::Bold)); 
    QObject::connect(&quit, SIGNAL(clicked()), &app, SLOT(quit())); 
    quit.show(); 
    return app.exec(); 
} 

私は:私はQt4をを使用してスクリーンショットを撮ってみましたが、それが正常に動作しながら、X11から焦点を当てたウィンドウを取得しようとしたとき、それは同じ問題に実行されます

したがって、XGetInputFocus()は何とか失敗すると確信しています。

答えて

7

私はまだ答えが得られていないので、私は一日のうちに解決策を探していました。私はこの仕組みをどうやって管理したか分かりました。 システムはDebian Squeezeで、KDE ​​4.4.5を実行しています。 明らかに、KDEとGTKのアプリケーションはお互いにうまくやっていません。 stackoverflowとインターネットで一般的に他の投稿から引用すると、kde以外のアプリケーションは_NET_WM_STATEを尊重しないかもしれません。そうでなければsomethigかもしれません。しかし、私が試したGTKアプリケーションが、すべてのQt4アプリケーションが動作するコード部分ではうまくいかなかったという事実は、何らかの形式の報告に関連する問題を暗示しています。おそらくX11のウィンドウツリーがアクティブなウィンドウを見つけるために横断する可能性があるネットポイント上に見つかったいくつかのまれな(そして本当にまれな)解決策ですが、それは私にとっては複雑すぎるように思えました。 私は(オンラインで見つけるスニペットのこまごまとしている)を思い付いたことXDO(Debianの上libxdo)を使用して、以下の通りです:

Display *display = XOpenDisplay(NULL); 
    Window active; 
    XWindowAttributes gwa; 

    // Use xdo to find the active window - care on the display ! 
    xdo_t* xdocontext = xdo_new(0); 
    xdo_window_get_active(xdocontext, &active); 
    if(active){ 
     XGetWindowAttributes(display, active, &gwa); 
     XImage *image = XGetImage(display,active, 0,0 , gwa.width,gwa.height,XAllPlanes(), ZPixmap); 
     unsigned char *array = new unsigned char[gwa.width * gwa.height * 3]; 
     CImg<unsigned char> pic(array,gwa.width,gwa.height,1,3); 

     for (int x = 0; x < gwa.width; x++){ 
     for (int y = 0; y < gwa.height ; y++){ 
      pic(x,y,0) = (XGetPixel(image,x,y) & image->red_mask) >> 16; 
      pic(x,y,1) = (XGetPixel(image,x,y) & image->green_mask) >> 8; 
      pic(x,y,2) = XGetPixel(image,x,y) & image->blue_mask; 
     } 
     } 
     delete[] array; 
     pic.save_png("blah.png"); 
    } else std::cout << "xdo failed to get active window" << std::endl; 

GTK & KDEアプリケーションで上記の作品を、私は本当にそれが役立つことを願って誰かがこれに気づいていないようです。

+0

私はそれをテストしましたが、このプログラムに適用するとノーチラスのウィンドウではうまくいきません:http://stackoverflow.com/questions/22749444/listening-to-keyboard-events-without-consuming-them-in- x11-キーボードフック – user2029077

関連する問題