libjpeg和X11试图保存屏幕截图的小问题

问题描述

我正在尝试按照this指南创建一个简单程序,以将屏幕快照保存在X11上。我知道这里有很多错误检查/内存管理的东西;我只是想在清理之前运行一些代码。该代码似乎可以正常工作,但是我的JPEG无法正确创建。我怀疑我在用row_pointer = (JSAMPROW) &buffer[cinfo.next_scanline * cinfo.input_components * cinfo.image_width];弄乱了东西,但我不确定到底是什么。知道有什么问题吗?任何帮助将不胜感激。

屏幕截图代码

int8_t* screen_capture(int16_t x,int16_t y,uint16_t width,uint16_t height) {
    display *disp;
    Window root;
    disp = XOpendisplay(NULL);
    if (disp != NULL) {
        root = DefaultRootwindow(disp);
    }

    XShmSegmentInfo shminfo;
    XImage *ximg = XShmCreateImage(disp,DefaultVisual(disp,0),DefaultDepth(disp,Zpixmap,NULL,&shminfo,width,height);

    shminfo.shmid = shmget(IPC_PRIVATE,ximg->bytes_per_line * ximg->height,IPC_CREAT | 0777);
    //FIXME shminfo.shmid >= 0 !
    shminfo.shmaddr = ximg->data = shmat(shminfo.shmid,0);
    shminfo.readOnly = False;

    XShmAttach(disp,&shminfo);
    XShmGetimage(disp,root,ximg,x,y,AllPlanes);

/*
    int8_t* buffer = (int8_t*) malloc(width * height * 3);
    memcpy(buffer,ximg->data,width * height * 3);

    XShmDetach(disp,&shminfo);
    XDestroyImage(ximg);
    shmdt(shminfo.shmaddr);
    shmctl(shminfo.shmid,IPC_RMID,0);

    return buffer;
*/
    return ximg->data;
}

Jpeg保存代码

void save_jpg(int8_t* buffer,uint16_t height) {
    struct jpeg_compress_struct cinfo;
    struct jpeg_error_mgr jerr;

    char * filename = "screenshot.jpg";
    FILE * outfile;
    if ((outfile = fopen(filename,"wb+")) == NULL) {
        fprintf(stderr,"can't open %s\n",filename);
        exit(1);
    }

    cinfo.err = jpeg_std_error(&jerr);
    jpeg_create_compress(&cinfo);

    jpeg_stdio_dest(&cinfo,outfile);

    cinfo.image_width      = width;
    cinfo.image_height     = height;
    cinfo.input_components = 3;
    cinfo.in_color_space   = JCS_RGB;

    jpeg_set_defaults(&cinfo);
    jpeg_set_quality (&cinfo,100,true);
    jpeg_start_compress(&cinfo,true);

    JSAMPROW row_pointer;
    while (cinfo.next_scanline < cinfo.image_height) {
        row_pointer = (JSAMPROW) &buffer[cinfo.next_scanline * cinfo.input_components * cinfo.image_width];
        jpeg_write_scanlines(&cinfo,&row_pointer,1);
    }

    jpeg_finish_compress(&cinfo);
}

简单的入口点:

int main() {
    int8_t* buffer = screen_capture(0,1024,768);
    save_jpg(buffer,768);

    return 0;
}

sample output

更新

好的,经过一番尝试和错误之后,我认为我已经确定了问题所在。我的screen_capture没有产生JCS_RBG数据,相反它似乎正在产生JCS_EXT_RGBA。我不确定为什么或是否可以更改。如果您碰巧知道SHM的工作原理,请给我评论。这些文档几乎不存在。

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)