LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 5439|回复: 16

如何使用framebuffer,在文本模式下显示图片??

[复制链接]
发表于 2005-6-15 23:36:00 | 显示全部楼层 |阅读模式
我想读入硬盘上的一张图片,然后在文本模式下显示出来,有没有朋友有相关资料阿,我在网上搜索了一下发觉framebuffer的资料很少~请各位帮帮忙 ,能给出代码最好了:help  :help  :help

先谢谢了!
发表于 2005-6-16 10:07:54 | 显示全部楼层
This document was last updated June 11th, 1999. (Corrections from Joerg Beyer
& Ian Thompson-Bell)

Part One:

First of all, configure your system for the framebuffer console device. It may
come in handy. Note that the device is only available for graphics cards that
implement VESA 2.0. Fortunately, virtually all recent cards out there do this
.

When you have got high-res textmodes, then you can start experimenting. You wi
ll have a device /dev/fb0 that you can look at like any normal file. To take a
screenshot, all you have to do is

cat /dev/fb0 > ~/sshot

And you will have a pretty big file with the contents of your graphics card's
memory inside. Now, if you clear the screen, and type

cat ~/sshot > /dev/fb0

You should have a display that looks exactly like before. Of course, the secon
d you start typing the display reverts to normal.

Part Two:

So now, we can move on to using the device in a C program. Take a look at the
following code:

#include <unistd.h>
#include <stdio.h>
#include <fcntl.h>
int main()
{
        int fbfd = 0;

        fbfd = open("/dev/fb0", O_RDWR);
        if (!fbfd) {
        printf("Error: cannot open framebuffer device.\n");
        exit(1);
        }
        printf("The framebuffer device was opened successfully.\n");

        close(fbfd);
        return 0;
}

All in all, a pretty simple program. We open the framebuffer device file using
the low-level open(), because the buffered, higher level fopen() is unsuitabl
e for our needs.
Next, we test the file descriptor to make sure that we were successful, and pr
int a message out that tells the user what happened.
Note that if you #include <errno.h>, then you will be able to find out exactly
why the open() call fails. Check the man page for open() for more information
on this
Finally, we clean up by closing the file descriptor and returning.

Part Three:

Using the newly created file descriptor, we can perform operations on the fram
ebuffer with the ioctl() function. This function is used to talk to special de
vice files in ways that are particular to that device. In this case, we can us
e it to obtain information on the video card. We can also use the file descrip
tor to map the file into memory, and use a pointer to access it, which is more
efficient and easier on us. This is done using the mmap() function. If you ha
ven't used this before, here is some sample code:

#include <unistd.h>
#include <stdio.h>
#include <fcntl.h>
#include <linux/fb.h>
#include <sys/mman.h>

int main()
{
        int fbfd = 0;
        struct fb_var_screeninfo vinfo;
        struct fb_fix_screeninfo finfo;
        long int screensize = 0;
        char *fbp = 0;

        fbfd = open("/dev/fb0", O_RDWR);
        if (!fbfd) {
                printf("Error: cannot open framebuffer device.\n");
                exit(1);
        }
        printf("The framebuffer device was opened successfully.\n");

        if (ioctl(fbfd, FBIOGET_FSCREENINFO, &finfo)) {
        printf("Error reading fixed information.\n");
        exit(2);
        }

        if (ioctl(fbfd, FBIOGET_VSCREENINFO, &vinfo)) {
                printf("Error reading variable information.\n");
        exit(3);
        }

        screensize = vinfo.xres * vinfo.yres * vinfo.bits_per_pixel / 8;
        fbp = (char *)mmap(0, screensize, PROT_READ | PROT_WRITE, MAP_SHARED,
                fbfd, 0);
        if ((int)fbp == -1) {
                printf("Error: failed to map framebuffer device to memory.\n");
                exit(4);
        }
        printf("The framebuffer device was mapped to memory successfully.\n");
        munmap(fbp, screensize);
        close(fbfd);
        return 0;
}

As you can see, we have to #include an extra header file to deal with mmap().
We use the information returned by the ioctl()s to figure out how much memory
to map. The members of fb_var_screeninfo that are used are xres, yres, and bit
s_per_pixel.
Note that there is also what is known as the virtual screen size, which can be
utilised for scrolling, etc, but that is beyond the scope of this document. H
owever, if you are planning on using scrolling, you will probably want to use
xres_virtual and yres_virtual to calculate how much memory to map.
Finally, remember to munmap() the memory you have mapped for use with the fram
ebuffer.

Part Four:

In this section we finally get to plot a pixel on the screen. First of all, we
need to know in what format we should put the data. As it is the most common,
and also the only type I have access to, I will be talking about the type of
framebuffer that utilises packed pixels. All that is necessary to put a pixel
on the screen, is to put bytes corresponding to the colours blue, green, red a
nd transparency, in that order, at the correct location in memory, starting at
0 for x = 0, y = 0, and increasing by four bytes for every x, and y * the len
gth of the line in bytes for every y. Standard graphics stuff; people used to
the good ol' days back in mode 13h programming in DOS will catch on quickly. A
nyway, here's the code:

#include <unistd.h>
#include <stdio.h>
#include <fcntl.h>
#include <linux/fb.h>
#include <sys/mman.h>

int main()
{
        int fbfd = 0;
        struct fb_var_screeninfo vinfo;
        struct fb_fix_screeninfo finfo;
        long int screensize = 0;
        char *fbp = 0;
        int x = 0, y = 0;
        long int location = 0;

        /* Open the file for reading and writing */
        fbfd = open("/dev/fb0", O_RDWR);
        if (!fbfd) {
                printf("Error: cannot open framebuffer device.\n");
                exit(1);
        }
        printf("The framebuffer device was opened successfully.\n");

        /* Get fixed screen information */
        if (ioctl(fbfd, FBIOGET_FSCREENINFO, &finfo)) {
                printf("Error reading fixed information.\n");
        exit(2);
        }

        /* Get variable screen information */
        if (ioctl(fbfd, FBIOGET_VSCREENINFO, &vinfo)) {
                printf("Error reading variable information.\n");
                exit(3);
        }

        /* Figure out the size of the screen in bytes */
        screensize = vinfo.xres * vinfo.yres * vinfo.bits_per_pixel / 8;

        /* Map the device to memory */
        fbp = (char *)mmap(0, screensize, PROT_READ | PROT_WRITE, MAP_SHARED,fbfd, 0);
        if ((int)fbp == -1) { printf("Error: failed to map
                framebuffer device to memory.\n"); exit(4);
        }
        printf("The framebuffer device was mapped to memory successfully.\n");


        x = 100; y = 100; /* Where we are going to put the pixel */

        /* Figure out where in memory to put the pixel */
        location = (x+vinfo.xoffset) * (vinfo.bits_per_pixel/8) +(y+vinfo.yoffset) * finfo.line_length;

        *(fbp + location) = 100; /* Some blue */
        *(fbp + location + 1) = 15; /* A little green */
        *(fbp + location + 2) = 200; /* A lot of red */
        *(fbp + location + 3) = 0; /* No transparency */

        munmap(fbp, screensize);
        close(fbfd);
        return 0;
}
回复 支持 反对

使用道具 举报

发表于 2005-6-16 10:11:10 | 显示全部楼层
以上是最原始的对framebuffer支持的screen画上一个有颜色点的程序。
对于你想显示的图片,得到他们每个象素点的RGB值加以循环就可以得到你所要的结果了。
当然如果你懂Gcc内联汇编,用一些MMX或者SSE指令进行加速的话,效果会更好。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2005-6-16 11:32:23 | 显示全部楼层

多谢楼上的朋友帮忙!

十分感谢给出实现思想!!!!谢谢!!!!!!!!!
回复 支持 反对

使用道具 举报

发表于 2005-6-17 14:21:52 | 显示全部楼层
正好要研究这个东西,谢谢两位!谢谢!
回复 支持 反对

使用道具 举报

发表于 2005-6-17 23:11:19 | 显示全部楼层
framebuffer只是一个提供显示内存和显示芯片寄存器从物理内存映射到进程地址空间的抽象设备,想要在其上进行图形编程,还需要完成其他许多工作。

还不如使用更高级一点儿的库,比如sdl,就可以轻易地在framebuffer环境下实现图形绘制。
回复 支持 反对

使用道具 举报

发表于 2005-6-20 11:48:01 | 显示全部楼层
可不可以多做些介绍,真的很想知道。
回复 支持 反对

使用道具 举报

发表于 2005-6-20 18:51:22 | 显示全部楼层
请问sdl如何使用?
回复 支持 反对

使用道具 举报

发表于 2005-6-21 00:41:52 | 显示全部楼层
apt-get source zgv
一共大约17211行C代码,认真点看的话,一个周就能搞个大概。对你肯定有超大帮助。
回复 支持 反对

使用道具 举报

发表于 2005-6-22 16:32:45 | 显示全部楼层
zgv (一个控制台字符界面下看图的软件)是用 svgalib 库开发而非SDL库。
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表