帧缓冲 framebuffer

一、基本概念

framebuffer: 帧缓存、帧缓存(显示设备)

Linux内核为显示提供的一套应用程序接口。(驱动内核支持)

分辨率:

像素点

显示屏:800 * 600(横向有800个像素点,纵向有600个像素点)

显卡(显存(保存像素点的值))

RGB

888(8个bitR,8个bit G,8个bit B)

PC ,4412(RGB888)

RGB565(S3C2440)

为了提高代码的书写效率(将RGB扩充到4字节)

二、解决显存空间不能直接被用户访问

根据显存的大小的多少,来申请空间

1、打开显示设备(/dev/fb0)

2、获取显示设备相关参数(分辨率、位深度......)

3、建立内存映射

4、写入RGB颜色值

5、解除映射

6、关闭显示设备

三、framebuffer常问话术

framebuff(是什么,具体原理、怎么做、)

是什么:Linux内核为显示提供的一套应用程序接口。(驱动内核支持)

具体原理:通过内存映射技术向显存空间写入RGB值

1、打开显示设备(/dev/fb0)

2、获取显示设备相关参数(分辨率、位深度......)

3、建立内存映射

4、写入RGB颜色值

5、解除映射

6、关闭显示设备

四、framebuffer绘制图片

jpg png(已压缩、有损的图像处理)

bmp:位图(未压缩的,无损的)

  • 位图格式,通常未压缩,因此文件较大,保存了图像的所有细节。
  • 用途:常用于Windows操作系统中的图像存储,适合不需要压缩的场合。
  • 缺点:由于文件大小较大,不适合网络传输。

54个字节是头部信息,前14字节是文件相关信息,40字节是图像相关信息。

修改为bmp

用画图工具另存为.bmp格式,不要修改文件的后缀名,每一个格式都有自己的具体格式。

每一个格式都有自己的具体格式

标准IO fseek

文件IO seek

为了提升效率直接将想要读的数据直接读到内存中

bmp里面存储的数据是 rgb实际上是bgr,所以我们需要进行数据转换,所以我们需要进行数据的格式进行向前移动。

指针进行偏移,进行指向,第一个是b,g,r

向将高位进行移动,然后将后面的格式向前移动,进行拼接,按位或,根据不同的格式,进行不同的移动,对于不同 的格式,我们进行不同的位运算

显示文字

我们的文字显示是在矩阵当中,所以进行矩阵进行点亮

显示文字的时候我们用行的话字节进行提取,按位进行判断那一位应该备置起来

四、常见画图操作

1、画一个点

void draw_point(int x,int y,unsigned int col)
{
    if(x >= vinf.xres || y>= vinf.yres)
    {
        return;
    }
    if(vinf.bits_per_pixel == RGB888_FMT)
    {
        unsigned int *p = pmem;
        *(p + y * vinf.xres_virtual + x) = col;
    }
    else if(vinf.bits_per_pixel == RGB565_FMT)
    {
        unsigned short *p = pmem;
        *(p + y * vinf.xres_virtual + x) = col;

    }
}

2、画一条竖线,横线,斜线

void draw_line(int x0,int y0,int x1,int y1,unsigned int col)
{
    if(x0 >= vinf.xres|| y0 >= vinf.yres|| x1 >= vinf.xres || y1 >= vinf.yres)
    {
        return;
    }
    if(vinf.bits_per_pixel == RGB888_FMT)
    {
        int xmax = x0 > x1 ? x0 : x1;
        int xmin = x0 < x1 ? x0 : x1;
        if(x0 == x1)
        {
            int ymax = y0 > y1 ? y0 : y1;
            int ymin = y0 < y1 ? y0 : y1;
            for(int y = ymin;y < ymax;++y)
            {
                draw_point(x0,y,col);
            }
        }
        else if(y0 == y1)
        {
            for(int x = xmin;x < xmax;++x)
            {
                draw_point(x,y0,col);
            }
        }
        else
        {
            for(int x = xmin;x < xmax;++x)
            {
                int y = (y1 - y0)/(x1 - x0) * (x - x0) + y0;
                draw_point(x,y,col);

            }
        }
    }
    
}

3、画一个圆

void draw_circle(int x,int y,int r,unsigned int col)
{
    int xc = 0;
    int yc = r;
    int p = 3 - 2 * r;
    while(xc <= yc)
    {
        draw_point(x + xc ,y+yc,col);
        draw_point(x - xc ,y+yc,col);
        draw_point(x + xc ,y-yc,col);
        draw_point(x - xc ,y-yc,col);
        draw_point(x + yc ,y+xc,col);
        draw_point(x - yc ,y-xc,col);
        draw_point(x + yc ,y-xc,col);
        draw_point(x - yc ,y-xc,col);
        xc++;

        if(p < 0)
        {
            p += 4 *xc + 6;
        }
        else
        {
            yc--;
            p += 4 *(xc - yc) + 10;
        }

    }
}

4、画一个矩形

void draw_rectangle(int x,int y,int x0,int y0,unsigned int col)
{
    if(x >= vinf.xres || y>= vinf.yres)
    {
        return;
    }
    for(int i = x;i <= x0;++i)
    {
        draw_point(i,y,col);
    }
    for(int i = x;i <= x0;++i)
    {
        draw_point(i,y0,col);
    }
    for(int i = y;i <= y0;++i)
    {
        draw_point(x,i,col);
    }
    for(int i = y;i < y0;++i)
    {
        draw_point(x0,i,col);
    }

       
}

5、清屏

void clear_watch(unsigned int col)
{
    int i = 0;
    int j = 0;
    for(i = 0;i < vinf.xres;++i)
    {
        for(j = 0;j < vinf.yres;++j)
        {
            draw_point(i,j,col);
        }
    }
}

  • 15
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值