12

我是这个 linux 帧缓冲区的新手,所以有人指导我在帧缓冲区中绘制线图。我有在 turbo c 中绘制图形的代码,但现在在 linux 中。所以请帮帮我。

谢谢你,拉胡尔

4

3 回答 3

19

open()/dev(例如)中的正确文件上使用/dev/fb0,然后使用mmap()将其映射到内存中。如果您不知道如何使用它们,联机帮助页将对这些系统调用有所帮助。

然后有一些结构和常数用于一些ioctl()s in <linux/fb.h>。像许多内核头文件一样,您只需浏览文件即可学到很多东西。

特别有趣的是FBIOGET_VSCREENINFO带有struct fb_var_screeninfo. 请注意,这有xresyres(分辨率)和bits_per_pixel。然后是FBIOGET_FSCREENINFOand struct fb_fix_screeninfowhich 有更多信息,例如typeand line_length

因此 (x, y) 处的像素可能位于mmap_base_address + x * bits_per_pixel/8 + y * line_length。像素的确切格式取决于您通过 ioctl 检索到的结构;决定如何读/写它们是你的工作。

自从我使用这个已经有一段时间了,所以我对更多细节有点模糊..

这是一个快速而肮脏的代码示例,只是为了说明它是如何完成的......我没有测试过这个。

#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/mman.h>

#include <linux/fb.h>

#include <unistd.h>
#include <fcntl.h>

#include <stdio.h>

int main()
{
   struct fb_var_screeninfo screen_info;
   struct fb_fix_screeninfo fixed_info;
   char *buffer = NULL;
   size_t buflen;
   int fd = -1;
   int r = 1;

   fd = open("/dev/fb0", O_RDWR);
   if (fd >= 0)
   {
      if (!ioctl(fd, FBIOGET_VSCREENINFO, &screen_info) &&
          !ioctl(fd, FBIOGET_FSCREENINFO, &fixed_info))
      {
         buflen = screen_info.yres_virtual * fixed_info.line_length;
         buffer = mmap(NULL,
                       buflen,
                       PROT_READ|PROT_WRITE,
                       MAP_SHARED,
                       fd,
                       0);
         if (buffer != MAP_FAILED)
         {
            /*
             * TODO: something interesting here.
             * "buffer" now points to screen pixels.
             * Each individual pixel might be at:
             *    buffer + x * screen_info.bits_per_pixel/8
             *           + y * fixed_info.line_length
             * Then you can write pixels at locations such as that.
             */

             r = 0;   /* Indicate success */
         }
         else
         {
            perror("mmap");
         }
      }
      else
      {
         perror("ioctl");
      }
   }
   else
   {
      perror("open");
   }

   /*
    * Clean up
    */
   if (buffer && buffer != MAP_FAILED)
      munmap(buffer, buflen);
   if (fd >= 0)
      close(fd);

   return r;
}
于 2009-12-02T05:40:25.730 回答
4

作为asveikau 的答案的替代方案,您可以使用DirectFB,它可以为您大大简化事情。

于 2009-12-02T06:12:13.550 回答
0

来自我在 Rasbian 上的 Synaptic:“DirectFB 是一个在设计时考虑到嵌入式系统的图形库。它以最少的资源使用和开销提供了最大的硬件加速性能。”

无论如何,我还没有在帧缓冲区中看到这项工作,但我希望它就像我做的大部分图形一样。您有一些线性地址空间,每个像素的高度 * 宽度 * 字节数。如果要写入特定的 x,y 位置,则该空间中的位置由 (y * width * bytes per pixel) + (x * 3) 给出。颜色是相邻的 RGB 字节(通常),这样可以获得红色像素的地址,绿色加 1,蓝色加 2。您 malloc(height * width * bytes per pixel) 一个地址空间,写入其中,然后选择您选择的 libpng、libjpeg、libtiff 将该缓冲区写入文件。如果您也想在其中放入文本,则必须自己滚动,所以我从旧的 libgif 中偷了一个。我已经达到了自己做这件事比学习别人认为应该如何做更容易的年龄和经验水平。 从 rtl_power 以 CSV 格式获取的数据

我一直在尝试使用http://raspberrycompote.blogspot.com/2014/04/low-level-graphics-on-raspberry-pi.html中所述的帧缓冲区,但出现了问题。我在 Pi 3 上,它可能是为 Pi 1 编写的,因为它是 2014 年,而不是 2017 年。但是 Pi 与传统的帧缓冲区不同,因为 GPU 运行该节目。使用这个方法:http ://elinux.org/RPi_Framebuffer

于 2017-07-24T01:04:36.343 回答