实现在X11下抓屏

-- TOC --

下面这段代码,实现了在X11下的抓屏功能,编译后运行,自动将抓屏数据生成ppm和bgra两个文件。

#include <stdio.h>
#include <X11/Xlib.h>
#include <X11/extensions/XShm.h>


void save2ppm(XImage *image, char *filename) {
    FILE *file = fopen(filename, "wb");
    if (!file) {
        fprintf(stderr, "Error opening file for writing %s\n", filename);
        return;
    }

    int width = image->width;
    int height = image->height;

    // Write the PPM header
    fprintf(file, "P6\n%d %d\n255\n", width, height);

    // Write the pixel data (in RGB format)
    // Raw data is in BGRA format
    for (int i=0; i<height; ++i) {
        for (int j=0; j<width; ++j) {
            unsigned int pixel = *(unsigned int*)\
                                  (image->data+(i*width+j)*4);
            unsigned char r = (pixel >> 16) & 0xFF;
            unsigned char g = (pixel >> 8) & 0xFF;
            unsigned char b = pixel & 0xFF;
            fputc(r, file);
            fputc(g, file);
            fputc(b, file);
        }
    }

    fclose(file);
}


void save2bgra(XImage *image, char *filename) {
    FILE *file = fopen(filename, "wb");
    if (!file) {
        fprintf(stderr, "Error opening file for writing %s\n", filename);
        return;
    }

    int width = image->width;
    int height = image->height;
    fwrite(image->data, width*height*4, 1, file);
    fclose(file);
}


int main(int argc, char **argv){
    if(argc != 2){
        fprintf(stderr, "Usage: screen_saver <filename_without_suffix>\n");
        return -1;
    }

    char ppm_fname[128] = {};
    char bgra_fname[128] = {};
    sprintf(ppm_fname, "%s.ppm", argv[1]);
    sprintf(bgra_fname, "%s.bgra", argv[1]);

    Display *display = XOpenDisplay(NULL);
    if(!display){
        fprintf(stderr, "XOpenDisplay error\n");
        return -1;
    }

    Window root = RootWindow(display, DefaultScreen(display));
    if(!root){
        fprintf(stderr, "RootWindow error\n");
        return -1;
    }

    int width = DisplayWidth(display, 0);
    int height = DisplayHeight(display, 0);
    XImage *img = XGetImage(display, root,
                            0, 0, width, height,
                            AllPlanes, ZPixmap);
    if(!img){
        fprintf(stderr, "XGetImage error\n");
        return -1;
    }

    save2ppm(img, ppm_fname);
    save2bgra(img, bgra_fname);

    return 0;
}

本文链接:https://cs.pynote.net/sf/linux/prog/202304241/

-- EOF --

-- MORE --