I am trying to capture an image of the screen for use in screencasting. Thus I need a fast solution, and cannot rely on shell programs such as import or xwd.
This is the code I have written so far, but it fails and gives me a junk image, which just seems to show fragments of several images with odd colors tossed together.
Any ideas on what I am doing wrong?
#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
",red_mask>> 16, green_mask>>8, blue_mask);
return 0;
}
See Question&Answers more detail:os