2011-11-23 15 views
22

スクリーンキャスティングで使用するために、画面のイメージをキャプチャしようとしています。したがって、私は高速なソリューションが必要であり、importや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

こんにちは@lalalandあなたの最終的なコードを共有してください、これはマルチモニタをサポートしていますか? – Noitidart

+2

@Noitidartはい、私は複数のモニターをサポートしました。私はhttps://github.com/Lalaland/ScreenCap/blob/master/src/screenCapturerImpl.cppが正しいファイルかもしれないと思う。しかし、何年もコードに触れていない。コードは記述が不十分ですが、使用したい場合はそこにBSDライセンスを送ります。 – Lalaland

+0

大変ありがとうございました。あなたの問題のページに投稿して、それがマルチモニタでどのように動作するのか理解できる時間があれば、どうかしてください。 – Noitidart

答えて

14

はあなたがループの前にimgを宣言し、あなたの内側のループにこのprintfを追加することで見つけることができますように、メモリ内にレイアウトされている方法arrayについて間違っています私の1920x1200画面)上:

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

など、赤/緑/青の部分画像ではなく3の「一緒に」維持されることを示します1つの画素の色成分は互いに隣接している。

組み込みCIMGアクセサは、あなたのコードの作業を行います。

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

あなたはそうでした:) – Lalaland

4

あなたは

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としてメモリに格納しているのlibpngを使用することができます... .... B1B2B3B4B5B6。 cimg storage

関連する問題