2011-11-23 17 views
22

मैं स्क्रीनकास्टिंग में उपयोग के लिए स्क्रीन की एक छवि को कैप्चर करने की कोशिश कर रहा हूं। इस प्रकार मुझे एक तेज समाधान की आवश्यकता है, और आयात या xwd जैसे शैल कार्यक्रमों पर भरोसा नहीं कर सकता।xlib के साथ स्क्रीनशॉट को सही तरीके से कैसे लें?

यह कोड मैंने अभी तक लिखा है, लेकिन यह विफल रहता है और मुझे एक जंक छवि देता है, जो कि कई छवियों के टुकड़े दिखाता है, जिसमें अजीब रंग एक साथ फेंकते हैं।

http://s9.postimage.org/dqnkgkwr1/blah.png

मैं गलत क्या कर रहा हूँ पर कोई भी विचार?

printf("%ld %ld %u %u %u\n",x,y,pic.offset(x,y,0),pic.offset(x,y,1),pic.offset(x,y,2)); 

यह पैदावार (:

#include <X11/Xlib.h> 
#include <X11/X.h> 

#include <cstdio> 
#include <CImg.h> 
using namespace cimg_library; 

int main() 
{ 
    Display *display = XOpenDisplay(NULL); 
    Window root = DefaultRootWindow(display); 

    XWindowAttributes gwa; 

    XGetWindowAttributes(display, root, &gwa); 
    int width = gwa.width; 
    int height = gwa.height; 


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

    unsigned char *array = new unsigned char[width * height * 3]; 

    unsigned long red_mask = image->red_mask; 
    unsigned long green_mask = image->green_mask; 
    unsigned long blue_mask = image->blue_mask; 

    for (int x = 0; x < width; x++) 
     for (int y = 0; y < height ; y++) 
     { 
     unsigned long pixel = XGetPixel(image,x,y); 

     unsigned char blue = pixel & blue_mask; 
     unsigned char green = (pixel & green_mask) >> 8; 
     unsigned char red = (pixel & red_mask) >> 16; 

     array[(x + width * y) * 3] = red; 
     array[(x + width * y) * 3+1] = green; 
     array[(x + width * y) * 3+2] = blue; 
     } 

    CImg<unsigned char> pic(array,width,height,1,3); 
    pic.save_png("blah.png"); 

    printf("%ld %ld %ld\n",red_mask>> 16, green_mask>>8, blue_mask); 

    return 0; 
} 
+1

हाय @ लालैंडैंड क्या आप अपना अंतिम कोड साझा कर सकते हैं, क्या यह बहु मॉनीटर का समर्थन करता है? – Noitidart

+2

@ नोइटिडार्ट हां, मैंने एकाधिक मॉनीटर का समर्थन किया। मुझे लगता है कि https://github.com/Lalaland/ScreenCap/blob/master/src/screenCapturerImpl.cpp सही फ़ाइल हो सकती है। यद्यपि वर्षों में कोड को छुआ नहीं है। कोड खराब लिखा गया है, लेकिन यदि आप इसका उपयोग करना चाहते हैं, तो मैं वहां एक बीएसडी लाइसेंस फेंक दूंगा। – Lalaland

+0

उत्तर के लिए बहुत बहुत धन्यवाद @lalaland धन्यवाद! यदि आपके पास समय है तो यह ठीक है अगर मैंने आपके मुद्दों पर पोस्ट किया है तो मैं समझ सकता हूं कि यह बहु मॉनीटर – Noitidart

उत्तर

14

आप जिस तरह से array बारे में गलत, स्मृति में खर्च की गई थी के रूप में आप पाश से पहले img घोषित करने और अपने भीतर के पाश को यह printf जोड़कर पता कर सकते हैं कर रहे हैं

0 0 0 2304000 4608000 
0 1 1920 2305920 4609920 
0 2 3840 2307840 4611840 

और इतने पर, यह दर्शाता है कि लाल/हरी/नीले subimages तीन के बजाय रखा जाता है "एक साथ": मेरे 1920x1200 स्क्रीन पर) एक पिक्सेल के रंग घटकों को एक दूसरे के समीप होने के नाते।

builtin CImg accessors अपने कोड काम कर देगा:

pic(x,y,0) = red; 
pic(x,y,1) = green; 
pic(x,y,2) = blue; 
+0

जैसे कुछ फ़ंक्शंस को नहीं ढूंढ सकता था, आप सही थे :) – Lalaland

4

आप libpng

int code = 0; 
FILE *fp; 
png_structp png_ptr; 
png_infop png_info_ptr; 
png_bytep png_row; 

// Open file 
fp = fopen ("test.png", "wb"); 
if (fp == NULL){ 
    fprintf (stderr, "Could not open file for writing\n"); 
    code = 1; 
} 

// Initialize write structure 
png_ptr = png_create_write_struct (PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); 
if (png_ptr == NULL){ 
    fprintf (stderr, "Could not allocate write struct\n"); 
    code = 1; 
} 

// Initialize info structure 
png_info_ptr = png_create_info_struct (png_ptr); 
if (png_info_ptr == NULL){ 
    fprintf (stderr, "Could not allocate info struct\n"); 
    code = 1; 
} 

// Setup Exception handling 
if (setjmp (png_jmpbuf (png_ptr))){ 
    fprintf(stderr, "Error during png creation\n"); 
    code = 1; 
} 

png_init_io (png_ptr, fp); 

// Write header (8 bit colour depth) 
png_set_IHDR (png_ptr, png_info_ptr, width, height, 
    8, PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE, 
    PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); 

// Set title 
char *title = "Screenshot"; 
if (title != NULL){ 
    png_text title_text; 
    title_text.compression = PNG_TEXT_COMPRESSION_NONE; 
    title_text.key = "Title"; 
    title_text.text = title; 
    png_set_text (png_ptr, png_info_ptr, &title_text, 1); 
} 

png_write_info (png_ptr, png_info_ptr); 

// Allocate memory for one row (3 bytes per pixel - RGB) 
png_row = (png_bytep) malloc (3 * width * sizeof (png_byte)); 

// Write image data 
int x, y; 
for (y = 0; y < height; y++){ 
    for (x = 0; x < width; x++){ 
     unsigned long pixel = XGetPixel (image, x, y); 
     unsigned char blue = pixel & blue_mask; 
     unsigned char green = (pixel & green_mask) >> 8; 
     unsigned char red = (pixel & red_mask) >> 16; 
     png_byte *ptr = &(png_row[x*3]); 
     ptr[0] = red; 
     ptr[1] = green; 
     ptr[2] = blue; 
    } 
    png_write_row (png_ptr, png_row); 
} 

// End write 
png_write_end (png_ptr, NULL); 

// Free 
fclose (fp); 
if (png_info_ptr != NULL) png_free_data (png_ptr, png_info_ptr, PNG_FREE_ALL, -1); 
if (png_ptr != NULL) png_destroy_write_struct (&png_ptr, (png_infopp)NULL); 
if (png_row != NULL) free (png_row); 
0

छवि का उपयोग कर सकते हैं के रूप में R1R2R3R4R5R6 ...... G1G2G3G4G5G6 स्मृति में संग्रहीत ... .... B1B2B3B4B5B6। cimg storage

संबंधित मुद्दे