XGetImage 需要很多时间来运行

Ade*_*med 4 c linux x11 xlib

XGetImage 执行需要 3-4 秒并完全冻结 X11

Display *display;
    display = XOpenDisplay(NULL);
if (!display) {fprintf(stderr, "unable to connect to display");return 7;}
    Window w;
    int x,y,i;
    unsigned m;
    Window root = XDefaultRootWindow(display);
if (!root) {fprintf(stderr, "unable to open rootwindow");return 8;}
    //sleep(1);
    if(!XQueryPointer(display,root,&root,&w,&x,&y,&i,&i,&m))
{  printf("unable to query pointer\n"); return 9;}
    XImage *image;
    XWindowAttributes attr;
    XGetWindowAttributes(display, root, &attr);
    image = XGetImage(display,root,0,0,attr.width,attr.height,AllPlanes,XYPixmap);
    XCloseDisplay(display);
if (!image) {printf("unable to get image\n"); return 10;}
Run Code Online (Sandbox Code Playgroud)

在 Xorg 日志中:

[ 13234.693] AUDIT: Thu Jan  7 20:12:13 2016: 3856: client 45 connected from local host ( uid=500 gid=500 pid=12993 )
  Auth name: MIT-MAGIC-COOKIE-1 ID: 153
[ 13238.774] AUDIT: Thu Jan  7 20:12:18 2016: 3856: client 45 disconnected
Run Code Online (Sandbox Code Playgroud)
time:
real    0m4.080s
user    0m0.002s
sys 0m0.007s
Run Code Online (Sandbox Code Playgroud)

理想情况下,我希望此功能在 0.1 秒内运行

n. *_* m. 7

XYPixmap是一种非常专业的格式,没有太多用途。你应该ZPixmap几乎总是使用。

XYPixmap作品由平面的平面。这是什么意思?取每个像素的位 0,并将所有这些位紧密地打包在一个unsigned int. 那是你的平面 0。然后取每个像素的位 1,并将所有这些位打包到一个数组中。那是你的飞机 1。然后取每个像素的第 2 位...

   Framebuffer
   __________________________________________________________________
  / 
   Pixel 0                     Pixel 1                      Pixel 2
   [0][1][2][3][4][5][6][7]    [0][1][2][3][4][5][6][7]     [0][1][2]....
    |                           |                            |
    |  +------------------------+                            |
    |  |                                                     |
    |  |  +--------------------------------------------------+
    |  |  |
    v  v  v
   [0][0][0]..... \
   (Plane 0)      |
                  |
   [1][1][1]....  | Result
   (Plane 1)      |
   ....           |
   [7][7][7]....  |
   (Plane 7)      |
                  /
Run Code Online (Sandbox Code Playgroud)

如果您的帧缓冲区是这样存储的,这是大多数现代硬件的情况,那就是很多位操作!

图片显示了 8 位像素,但对于任何其他深度都是相同的。

ZPixmap 另一方面,获取整个像素并将它们填充到一个数组中:

   Framebuffer
   __________________________________________________________________
  / 
   Pixel 0                     Pixel 1                      Pixel 2
   [0][1][2][3][4][5][6][7]    [0][1][2][3][4][5][6][7]     [0][1][2]....
    |  |  |  |  |  |  |  |      |  |  |  |  |  |  |  |       |  |  |
    v  v  v  v  v  v  v  v      v  v  v  v  v  v  v  v       v  v  v
   [0][1][2][3][4][5][6][7]    [0][1][2][3][4][5][6][7]     [0][1][2]....
  \_____________________________________________________________________
    Result
Run Code Online (Sandbox Code Playgroud)

这是简单的直接复制,应该非常快。

  • 太好了,我试过四处寻找那种解释,但没有找到,这非常有用,非常感谢 (2认同)
  • 关于 XGetImage、struct XImage 以及特别是 XYPixmap、平面蒙版等的可用信息很少。天哪,我不得不谷歌一个小时才能找到这么有用的信息!(手册页几乎没有告诉你......) (2认同)