帧缓冲 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;
	}
	return ;
}

2 横线

void draw_h_line(int x, int y, int len, unsigned int col)
{
	for (int i = x; i < x+len; i++)
	{
		draw_point(i, y, col);
	}
}

3 数线

void draw_s_line(int x, int y, int len, unsigned int col)
{
	for (int i = y; i < y+len; i++)
	{
		draw_point(x, i, col);
	}
}

4 斜线

void draw_x_line(int x1, int y1, int x2, int y2, unsigned int col)
{
	
	int x = 0;
	int y = 0;

	if (x1 == x2)
	{
		if (y2 > y1)
		{
			draw_s_line(x1, y1, y2-y1, col);
		}
		else
		{
			draw_s_line(x2, y2, y1-y2, col);		
		}
	}

	double k = (double)(y2-y1)/(double)(x2-x1);
	double b = y1 - k*x1;
   

	for (int x = (x1 > x2 ? x2 : x1); x <= (x1 > x2 ? x1 : x2); x++)
	{
		y = x * k + b;
		draw_point(x, y, col);
	}
	
	return ;
}

5 矩形

void draw_rectangle(int x, int y, int w, int h, unsigned int col)
{
	draw_h_line(x, y, w, col);
	draw_s_line(x, y, h, col);
	draw_s_line(x+w, y, h, col);
	draw_h_line(x, y+h, w, col);
}

6 圆

void draw_circle(int x0, int y0, int r, unsigned int col)
{
	int x = 0;
	int y = 0;
	for (double si = 0; si <= 360; si+=0.01)
	{
		x = r * cos(2 * 3.14159/360 *si) + x0;
		y = r * sin(2 * 3.14159/360 *si) + y0;
		draw_point(x, y, col);
		draw_point(x-1, y, col);
		draw_point(x+1, y, col);
		draw_point(x, y-1, col);
		draw_point(x, y+1, col);
	}
}

7 图片

void draw_bmp(int x, int y, char *picname, int w, int h)
{
	int fd = open(picname, O_RDONLY);
	if (-1 == fd)
	{
		perror("fail open bmp");
		return ;
	}
	
	lseek(fd, 54, SEEK_SET);

	unsigned char r, g, b;

	unsigned char *buff = malloc(w*h*3);
	read(fd, buff, w*h*3);
	
	unsigned char *p = buff;
	for (int j = h-1; j >= 0; j--)
	{
		for (int i = 0; i < w; i++)
		{

			b = *p; p++;
			g = *p; p++;
			r = *p; p++;
			if (vinf.bits_per_pixel == RGB888_FMT)
			{
				unsigned int col = (r << 16) | (g << 8) | (b << 0);
				draw_point(i+x, j+y, col);
			}
			else if (vinf.bits_per_pixel == RGB565_FMT)
			{
				unsigned short col = ((r >> 3) << 11) | ((g >> 2) << 5) | ((b >> 3) << 0);
				draw_point(i+x, j+y, col);
			}
		}
	}

	free(buff);
	close(fd);
}

8 文字

void draw_word(int x,int y,unsigned char *word,int w,int h,unsigned int col)
{
    for(int j = 0;j < h;j++)
    {
        for(int i = 0;i < w;i++)
        {
            unsigned char tmp = word[i + j*w];
            for(int k = 0;k < 8;k++)
            {
                if(tmp & 0x80)
                {
                    draw_point(i*8 + k + x,j + y,col);
                }
                tmp = tmp << 1;
            }
        }
    }
}

9 清屏

void draw_clear(unsigned int col)
{
	for (int j = 0; j < vinf.xres; j++)
	{
		for (int i = 0; i < vinf.yres; i++)
		{
			draw_point(i, j, col);
		}
	}
}
  • 5
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值