如何使用c语言在framebuffer中绘制图形?

发布于 2024-08-13 07:49:54 字数 103 浏览 8 评论 0原文

我对这个 linux 帧缓冲区很陌生,所以有人指导我在帧缓冲区中绘制线图吗?我有在 Turbo C 中绘制图形的代码,但现在在 Linux 中。所以请帮帮我。

谢谢你, 拉胡尔

i am new to this linux framebuffer so do anybody guide me to draw the line-graph in framebuffer. And i have the code to draw graph in turbo c but now in linux. So please help me out.

Thank You,
Rahul

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

﹏雨一样淡蓝的深情 2024-08-20 07:49:54

中的右侧文件上使用 open() >/dev(例如/dev/fb0),然后使用mmap() 将其映射到内存中。如果您不知道如何使用这些系统调用,则联机帮助页将为您提供帮助。

然后是一些ioctl()的结构体和常量s 在 中。与许多内核头文件一样,您只需浏览该文件就可以学到很多东西。

特别有趣的是带有 struct fb_var_screeninfo 的 ioctl FBIOGET_VSCREENINFO。请注意,这有xresyres(分辨率)和bits_per_pixel。然后是 FBIOGET_FSCREENINFOstruct fb_fix_screeninfo,其中包含 typeline_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;
}

Use open() on the right file in /dev (eg. /dev/fb0), then use mmap() to map it into memory. Manpages will help for these syscalls if you do not know how to use them.

Then there are some structures and constants for some ioctl()s in <linux/fb.h>. Like many kernel headers, you can learn a lot simply browsing the file.

Particularly interesting is the ioctl FBIOGET_VSCREENINFO with struct fb_var_screeninfo. Note this has xres, yres (resolution) and bits_per_pixel. Then there's FBIOGET_FSCREENINFO and struct fb_fix_screeninfo which has further information like type and line_length.

So a pixel at (x, y) might be at mmap_base_address + x * bits_per_pixel/8 + y * line_length. The exact format of the pixels will depend on the structures you retrieve via ioctl; it's your job to decide how to read/write them.

It's been a while since I've worked with this so I'm a bit hazy on more details..

Here's a quick and dirty code sample just to illustrate how it's done... I haven't tested this.

#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;
}
没有伤那来痛 2024-08-20 07:49:54

作为 asveikau 的答案,您可以使用 DirectFB,可能会大大简化你的事情。

As an alternative to asveikau's answer, you could use DirectFB, which may greatly simplify things for you.

执笔绘流年 2024-08-20 07:49:54

来自我的 Synaptic on Rasbian:“DirectFB 是一个图形库,专为嵌入式系统而设计。它以最少的资源使用和开销提供最大的硬件加速性能。”

不管怎样,我还没有在帧缓冲区中看到这项工作,但我希望它就像我所做的大部分图形一样。你有一些线性地址空间,高度 * 宽度 * 每个像素的字节数。如果要写入特定的 x,y 位置,则该空间中的位置由 (y * 宽度 * 每像素字节数) + (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

From my Synaptic on Rasbian: "DirectFB is a graphics library which was designed with embedded systems in mind. It offers maximum hardware accelerated performance at a minimum of resource usage and overhead."

Anyway, I haven't seen this work in a frame buffer yet but I'm hoping it's like I do most of my graphics. You have some linear address space, height * width * bytes per pixel number of bytes. If you want to write to a particular x,y location, the position in that space is given by (y * width * bytes per pixel) + (x * 3). Colors are adjacent bytes RGB (usually) so that gets you the address of the red pixel, add 1 for green, 2 for blue. You malloc(height * width * bytes per pixel) an address space, write into it, then pick your choice of libpng, libjpeg, libtiff to write that buffer out to a file. If you want to put text in it too you have to roll your own, so I stole one from an old libgif. I've reached the age and experience level where it's easier to do it myself than learn how somebody else thought it should be done. My graphics come out like this:
data taken as CSV from rtl_power

I've been trying to use a framebuffer as described at http://raspberrycompote.blogspot.com/2014/04/low-level-graphics-on-raspberry-pi.html but something is wrong. I'm on a Pi 3, it was probably written for a Pi 1 since it was 2014, not 2017 then. But the Pi is different than traditional framebuffers because the GPU runs the show. Use this method: http://elinux.org/RPi_Framebuffer

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文