2012-11-30 19 views
5

के लिए विफल रहता है यह एक बहुत बड़ा अनुसंधान परियोजना के एक उप परियोजना है। मैं प्रत्येक 100ms सक्रिय विंडो (ब्राउज़र) के स्क्रीनशॉट लेने की कोशिश कर रहा हूं, जिसे ओपनसीवी प्रसंस्करण के लिए स्मृति में संग्रहीत किया जाता है। मुझे एक समान प्रश्न से एक स्क्रीनशॉट लेने का एक समाधान मिला, और मैं वर्तमान में कोड के साथ खेल रहा हूं यह देखने के लिए कि क्या मैं इसका उपयोग कर सकता हूं। ऐसा लगता है कि एक संपूर्ण डेस्कटॉप स्क्रीनशॉट, या एक विशिष्ट विंडो स्क्रीनशॉट लेने पर निम्न स्निपेट काम कर रहा है, लेकिन यह जीटीके विंडोज़ के लिए काम नहीं करता है। मैंने डेवियन निचोड़ पर Iceweasel & नॉटिलस का एक स्क्रीनशॉट लेने का प्रयास किया है, और यह बस काम नहीं करता है। मैं एक्स 11 में कुल नोब हूं, और यह नहीं जानता कि त्रुटियों की जांच कैसे करें, या अगर कुछ ऐसा है जो मैं जीटीके के लिए गायब हूं, क्योंकि यह क्यूटी विंडोज़ के लिए काम करता है।X11 स्क्रीनशॉट जीटीके खिड़कियों

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; 
} 

उपरोक्त कोड या तो पूर्ण डेस्कटॉप स्क्रीनशॉट या क्यूटी के लिए काम करता है। मुझे कोई त्रुटि नहीं है (पता नहीं है कि मैं उन्हें सही तरीके से संभालने में सक्षम हूं)। कुछ बाइट्स की बस एक खाली तस्वीर, जो मुझे लगता है कि एक्स फ़ंक्शन में से एक विफल रहता है (XGetInputFocus, XGetWindowAttributes, XGetImage), XGetFocus पर मेरी शर्त के साथ ठीक से काम नहीं कर रहा है। यह क्या है कि मैं याद कर रहा हूं, या, इसका कोई विकल्प है? कृपया ध्यान दें कि यदि मैं किसी भी महत्व का है तो मैं केडीई (4.4.5) चला रहा हूं।

अद्यतन:

मैं एक स्क्रीनशॉट क्यूटी 4 का उपयोग कर लेने की कोशिश की है, और जब यह ठीक काम करता है, यह जब X11 से ध्यान केंद्रित खिड़कियों प्राप्त करने की कोशिश एक ही समस्या में चलाता है:

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(); 
} 

मैं कर रहा हूँ इसलिए आश्वस्त है कि यह XGetInputFocus() है जो किसी भी तरह विफल रहता है।

उत्तर

7

जब से मैं अभी तक कोई जवाब नहीं मिला है, और साईस मैं एक पूरे एक समाधान की तलाश में दिन के अधिकतर हिस्से तक खर्च किया है, मैंने सोचा था कि मैं साझा करते हैं कि कैसे मैं इस काम के पाने में कामयाब रहे। सिस्टम डेबियन निचोड़ है, जो केडीई 4.4.5 चला रहा है। जाहिर है केडीई और जीटीके ऐप्स एक दूसरे के साथ अच्छा नहीं खेलते हैं। स्टैक ओवरफ्लो और इंटरनेट पर सामान्य रूप से अन्य पोस्टों से लोगों को उद्धृत करते हुए, एक गैर-केडीई आवेदन _NET_WM_STATE का सम्मान नहीं कर सकता है, या यह कुछ और हो सकता है, मुझे वास्तव में पता नहीं है। लेकिन तथ्य यह है कि मैंने जिन जीटीके ऐप्स को आजमाया था, वे कोड के टुकड़े के साथ काम नहीं करते थे, जो कि सभी क्यूटी 4 ऐप्स काम करते थे, रिपोर्टिंग के कुछ रूप से संबंधित किसी मुद्दे पर संकेत देते हैं। शुद्ध बिंदु पर पाया जाने वाला कुछ दुर्लभ (और मुझे वास्तव में दुर्लभ मतलब) समाधान हो सकता है कि सक्रिय विंडो खोजने के लिए शायद एक्स 11 विंडोज़ पेड़ को पार किया जा सकता है, लेकिन यह मेरे लिए बहुत जटिल लग रहा था, और मैंने लोगों के पदों को सफल परिणाम प्राप्त नहीं किया। क्या मैं के साथ (जो बिट और ऑनलाइन पाया के टुकड़े के टुकड़े है) 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; 

जीटीके & केडीई एप्लिकेशन के साथ ऊपर काम करता है, मैं वास्तव में आशा है कि यह मदद मिल सकती है इस पर फंस गया क्योंकि इस पर बहुत कम पोस्ट लगती हैं।

+0

मैंने इसका परीक्षण किया लेकिन यह इस कार्यक्रम पर लागू होने पर मेरे लिए नॉटिलस विंडो के लिए काम नहीं करता है: http://stackoverflow.com/questions/22749444/listening-to-keyboard-events-without-consuming-them-in- X11-कुंजीपटल-hooking – user2029077