当前位置 : 主页 > 编程语言 > 其它开发 >

用c语言编程读取80*25分辨率的BMP图片中的文字图像以字符点阵的形式显示

来源:互联网 收集:自由互联 发布时间:2022-05-30
用c语言编程读取80*25分辨率的BMP图片中的文字图像以字符点阵的形式显示。 写这个程序之前得了解一下BMP位图文件的一些基础知识 前提知识:一、24位BMP(bitmap)文件基本结构:14字节文
用c语言编程读取80*25分辨率的BMP图片中的文字图像以字符点阵的形式显示。

写这个程序之前得了解一下BMP位图文件的一些基础知识

前提知识: 一、24位BMP(bitmap)文件基本结构: 14字节文件头 + 40字节信息头 + 位图像素数据(一个像素3个字节:蓝色分量(1字节)、绿色分量(1字节)、红色分量(1字节))。

注意:存储位图像素数据时是从左下角像素开始,从左到右,从下到上,直至最右上的那个像素。

14字节文件头:

​ 位图标志(BM: 2字节)、文件大小(4字节)、保留字节(保留4个字节,值为0)、第一个图像像素信息距离文件头的偏移植(4字节)。

40字节信息头:

​ 信息头长度(4字节,一般值是40,即信息头长40字节)、图像的宽度(4字节,单位像素)、图像的高度(4字节,单位像素)、

​ 目标设备颜色平面数(2字节,固定设置为2字节,固定设置值为1)、每像素所占的比特位数(2字节)、

​ 图像数据压缩的类型(4字节,24位颜色值的位图一般该值为0,表示不压缩)、

​ 图像所有像素占的字节数(4字节,一般为宽度 * 高度 * 每个像素所占的颜色字节数)、

​ 水平分辨率(4字节,用像素/米表示,一般为0缺省)、垂直分辨率(4字节,用像素/米表示,一般为0缺省)、

​ 颜色表中的颜色索引数(4字节,如果没用一般为0)、对图像显示有重要影响的颜色索引数(4字节,如果没用一般为0)。

位图像素数据(24位位图):由左下角像素开始,由左向右,由下向上,到最右上角的像素。

左下角最后一行第一个像素(3个字节:蓝色分量1字节、绿色分量1字节、红色分量1字节)、

左下角最后一行第二个像素(3个字节:蓝色分量1字节、绿色分量1字节、红色分量1字节)、

. . . . . .

左下角最后一行最后一个像素(3个字节:蓝色分量1字节、绿色分量1字节、红色分量1字节)、

. . . . . .

左上角第一行第一个像素(3个字节:蓝色分量1字节、绿色分量1字节、红色分量1字节)、

. . . . . .

右上角第一行最后一个像素(3个字节:蓝色分量1字节、绿色分量1字节、红色分量1字节)。

注意:位图数据中每个扫描行的字节数必须是4的倍数。如果不足要用0补齐。

程序实现:

使用到了命令行参数

int main(int argc,char* argv[])				
{
	/* 用c语言读取80*25点阵的24位的BMP位图然后在字符模式下显示*/
	
	FILE* fp;			//指向图像文件的文件指针
	int width, height;	//图像的宽度和高度(单位像素)
	char pix, blank;	//pix:存放读取的像素分量数据,
						//blank:存放图片的背景颜色(第一个读取出来的值作为背景,以后不是背景色的像素我们都画出来)
	if (argc != 2)
	{
		printf("传入参数个数错误");
		exit(0);
	}

	if ((fp = fopen(argv[1], "r")) == NULL)
	{
		printf("%s图像文件不存在!\n",argv[1]);
		exit(0);
	}
	
	fseek(fp, 18, SEEK_SET);//将文件读写指针移动到文件头偏移为18字节处
	fread(&width, sizeof(int), 1, fp);	//读取图像的宽度
	fread(&height, sizeof(int), 1, fp);	//读取图像的高度

	if (width != 80)
	{
		printf("图像宽度必须为80像素\n");
		exit(0);
	}

	fseek(fp, 54, SEEK_SET);	//跳过前面14字节文件头和40字节信息头,到达像素数据起始处
	blank = fgetc(fp);			//我们规定读取第一个字节的数据就是背景色

	for (int i = 0; i < height; ++i)
	{
		fseek(fp, 54, SEEK_SET);
		fseek(fp, (height - i - 1) * 3 * 80, SEEK_CUR);//跳过前height-1行的像素数据,因为文件存储时像素是左下角像素先存储,但是我要从左上角开始打印,所以得让文件指针指向对应像素的数据
														
		for (int j = 0; j < 80; ++j)	//打印一行
		{
			pix = fgetc(fp);
			if (pix == blank)
			{
				printf(" ");		//如果像素为背景色,则画出一个空格
			}
			else
			{
				printf(".");	//反之画出一个.
			}
			//注意,我们读完一个像素的一个字节数据后,还要跳过2个字节
			fseek(fp, sizeof(char) * 2, SEEK_CUR);
		}
		printf("\n");	//每打印完一行就换行
	}

	fclose(fp);

	system("pause");
	return 0;
}
原80* 25 BMP图片:

打印图片效果:

上一篇:Leetcode406/435/56之带排序的贪心
下一篇:没有了
网友评论