写这个程序之前得了解一下BMP位图文件的一些基础知识
注意:存储位图像素数据时是从左下角像素开始,从左到右,从下到上,直至最右上的那个像素。
位图标志(BM: 2字节)、文件大小(4字节)、保留字节(保留4个字节,值为0)、第一个图像像素信息距离文件头的偏移植(4字节)。
信息头长度(4字节,一般值是40,即信息头长40字节)、图像的宽度(4字节,单位像素)、图像的高度(4字节,单位像素)、
目标设备颜色平面数(2字节,固定设置为2字节,固定设置值为1)、每像素所占的比特位数(2字节)、
图像数据压缩的类型(4字节,24位颜色值的位图一般该值为0,表示不压缩)、
图像所有像素占的字节数(4字节,一般为宽度 * 高度 * 每个像素所占的颜色字节数)、
水平分辨率(4字节,用像素/米表示,一般为0缺省)、垂直分辨率(4字节,用像素/米表示,一般为0缺省)、
颜色表中的颜色索引数(4字节,如果没用一般为0)、对图像显示有重要影响的颜色索引数(4字节,如果没用一般为0)。
左下角最后一行第一个像素(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; }