如何从Linux framebuffer获取RGB像素值?

我希望使用Linux以最有效的方式获得屏幕像素的RGB值。 所以我决定使用C( fb.h )中的framebuffer库来访问framebuffer设备( / dev / fb0 )并直接读取它。

这是代码:

#include  #include  #include  #include  #include  #include  #include  #include  int main() { int fb_fd; struct fb_fix_screeninfo finfo; struct fb_var_screeninfo vinfo; uint8_t *fb_p; /* Open the frame buffer device */ fb_fd = open("/dev/fb0", O_RDWR); if (fb_fd < 0) { perror("Can't open /dev/fb0\n"); exit(EXIT_FAILURE); } /* Get fixed info */ if (ioctl(fb_fd, FBIOGET_FSCREENINFO, &finfo) < 0) { perror("Can't get fixed info\n"); exit(EXIT_FAILURE); } /* Get variable info */ if (ioctl(fb_fd, FBIOGET_VSCREENINFO, &vinfo) < 0) { perror("Can't get variable info\n"); exit(EXIT_FAILURE); } /* To access to the memory, it can be mapped*/ fb_p = (uint8_t *) mmap(0, finfo.smem_len, PROT_READ | PROT_WRITE, MAP_SHARED, fb_fd, 0); if (fb_p == MAP_FAILED) { perror("Can't map memory\n"); exit(EXIT_FAILURE); } /* Print each byte of the frame buffer */ for (int i = 0; i < finfo.smem_len; i++) { printf("%d\n", *(fb_p + i)); // for (int j = 0; j < 500000000; j++); /* Delay */ } munmap(fb_p, 0); close(fb_fd); return 0; } 

但是当我打印出价值观时,我得不到我所期待的……

如果我用像grabc这样的工具选择像素(0,0)的RGB值,我得到这个:

 #85377e 133,55,126 

但我的代码的第一次打印是:

 126 145 198 ... 

看起来我很好地获得了第一个像素的第一个值,对应于蓝色,但其余的都是错误的。

在使用fbdev的一些罕见的错误设备中,您可能需要将mmap返回的指针对齐到下一个系统页面才能正确获取第一个像素,这样做可能还需要再绘制一个页面。

我不认为这是你的情况,似乎你试图通过使用linux fbdev来获取xserver桌面像素,除非你的xserver被配置为使用fbdev驱动程序(即便如此我不确定会工作)isn不会工作的。 如果读取桌面像素是您的目标,您应该查看一些屏幕截图工具。

此外,fbdev驱动程序通常是基本的,是一种低级访问,但没有关于映射和读取像素的效率,Xlib或任何更高级别的图形系统可能知道并支持您的图形卡加速并且效率更高(可能使用DMA将整个帧缓冲区读取到系统内存而不加载cpu)。

如果你看看抓取源代码( https://www.muquit.com/muquit/software/grabc/grabc.html ),你会发现他正在查询X Windows(而不是硬件帧缓冲本身)。

 root_window=XRootWindow(display,XDefaultScreen(display)); target_window=selectWindow(display,&x,&y); ... ximage=XGetImage(display,target_window,x,y,1,1,AllPlanes,ZPixmap); ... color->pixel=XGetPixel(ximage,0,0); XDestroyImage(ximage); 

无论它的价值如何 – 出于几个不同的原因 – 我强烈建议你考虑做同样的事情。

你也可能对此有兴趣:

  • 介绍Linux上的低级图形

  • DirectFB的

在iOS上工作有一个私有框架iOMobileFrameBuffer,并为屏幕创建了一个可爱的录制软件。 我之前已经涉足过,所以我会告诉你我所知道的。 iOS明显不同于Linux FrameBuffer(缺少文档很相似……)但我个人会看看这个答案。 虽然这个问题不符合您的要求,但该答案解释了PixelBuffer以及您提出的确切问题的一个小例子。 给它一个阅读和回答任何问题,我会尽我所能回答。