c++ 读写bmp

来源:互联网 发布:linux统计指定文件行数 编辑:程序博客网 时间:2024/05/16 18:19
 1 #include<math.h>
2 #include <iomanip.h>
3 #include <stdlib.h>
4 #include <windows.h>
5 #include <stdio.h>
6 #include <stdlib.h>
7 #include <iostream.h>
8 #include <fstream.h>
9
10 //---------------------------------------------------------------------------------------
11 //以下该模块是完成BMP图像(彩色图像是24bit RGB各8bit)的像素获取,并存在文件名为xiang_su_zhi.txt中
12 unsignedchar *pBmpBuf;//读入图像数据的指针
13
14 int bmpWidth;//图像的宽
15 int bmpHeight;//图像的高
16 RGBQUAD*pColorTable;//颜色表指针
17
18 int biBitCount;//图像类型,每像素位数
19
20 //-------------------------------------------------------------------------------------------
21 //读图像的位图数据、宽、高、颜色表及每像素位数等数据进内存,存放在相应的全局变量中
22 bool readBmp(char*bmpName)
23 {
24 FILE *fp=fopen(bmpName,"rb");//二进制读方式打开指定的图像文件
25
26 if(fp==0)
27 return0;
28
29 //跳过位图文件头结构BITMAPFILEHEADER
30
31 fseek(fp,sizeof(BITMAPFILEHEADER),0);
32
33 //定义位图信息头结构变量,读取位图信息头进内存,存放在变量head中
34
35 BITMAPINFOHEADER head;
36
37 fread(&head,sizeof(BITMAPINFOHEADER),1,fp); //获取图像宽、高、每像素所占位数等信息
38
39 bmpWidth= head.biWidth;
40
41 bmpHeight= head.biHeight;
42
43 biBitCount= head.biBitCount;//定义变量,计算图像每行像素所占的字节数(必须是4的倍数)
44
45 int lineByte=(bmpWidth* biBitCount/8+3)/4*4;//灰度图像有颜色表,且颜色表表项为256
46
47 if(biBitCount==8)
48 {
49
50 //申请颜色表所需要的空间,读颜色表进内存
51
52 pColorTable=new RGBQUAD[256];
53
54 fread(pColorTable,sizeof(RGBQUAD),256,fp);
55
56 }
57
58 //申请位图数据所需要的空间,读位图数据进内存
59
60 pBmpBuf=new unsignedchar[lineByte* bmpHeight];
61
62 fread(pBmpBuf,1,lineByte* bmpHeight,fp);
63
64 fclose(fp);//关闭文件
65
66 return1;//读取文件成功
67 }
68
69 //-----------------------------------------------------------------------------------------
70 //给定一个图像位图数据、宽、高、颜色表指针及每像素所占的位数等信息,将其写到指定文件中
71 bool saveBmp(char*bmpName, unsignedchar *imgBuf, int width,int height,int biBitCount, RGBQUAD*pColorTable)
72 {
73
74 //如果位图数据指针为0,则没有数据传入,函数返回
75
76 if(!imgBuf)
77 return0;
78
79 //颜色表大小,以字节为单位,灰度图像颜色表为1024字节,彩色图像颜色表大小为0
80
81 int colorTablesize=0;
82
83 if(biBitCount==8)
84 colorTablesize=1024;
85
86 //待存储图像数据每行字节数为4的倍数
87
88 int lineByte=(width* biBitCount/8+3)/4*4;
89
90 //以二进制写的方式打开文件
91
92 FILE *fp=fopen(bmpName,"wb");
93
94 if(fp==0)
95 return0;
96
97 //申请位图文件头结构变量,填写文件头信息
98
99 BITMAPFILEHEADER fileHead;
100
101 fileHead.bfType= 0x4D42;//bmp类型
102
103 //bfSize是图像文件4个组成部分之和
104
105 fileHead.bfSize=sizeof(BITMAPFILEHEADER)+ sizeof(BITMAPINFOHEADER)+ colorTablesize+ lineByte*height;
106
107 fileHead.bfReserved1= 0;
108
109 fileHead.bfReserved2= 0;
110
111 //bfOffBits是图像文件前3个部分所需空间之和
112
113 fileHead.bfOffBits=54+colorTablesize;
114
115 //写文件头进文件
116
117 fwrite(&fileHead,sizeof(BITMAPFILEHEADER),1, fp);
118
119 //申请位图信息头结构变量,填写信息头信息
120
121 BITMAPINFOHEADER head;
122
123 head.biBitCount=biBitCount;
124
125 head.biClrImportant=0;
126
127 head.biClrUsed=0;
128
129 head.biCompression=0;
130
131 head.biHeight=height;
132
133 head.biPlanes=1;
134
135 head.biSize=40;
136
137 head.biSizeImage=lineByte*height;
138
139 head.biWidth=width;
140
141 head.biXPelsPerMeter=0;
142
143 head.biYPelsPerMeter=0;
144
145 //写位图信息头进内存
146
147 fwrite(&head,sizeof(BITMAPINFOHEADER),1, fp);
148
149 //如果灰度图像,有颜色表,写入文件
150
151 if(biBitCount==8)
152 fwrite(pColorTable,sizeof(RGBQUAD),256, fp);
153
154 //写位图数据进文件
155
156 fwrite(imgBuf, height*lineByte,1, fp);
157
158 //关闭文件
159
160 fclose(fp);
161
162 return1;
163
164 }
165
166 //----------------------------------------------------------------------------------------
167 //以下为像素的读取函数
168 void doIt()
169 {
170
171 //读入指定BMP文件进内存
172
173 char readPath[]="nv.BMP";
174
175 readBmp(readPath);
176
177 //输出图像的信息
178
179 cout<<"width="<<bmpWidth<<" height="<<bmpHeight<<" biBitCount="<<biBitCount<<endl;
180
181 //循环变量,图像的坐标
182
183 //每行字节数
184
185 int lineByte=(bmpWidth*biBitCount/8+3)/4*4;
186
187 //循环变量,针对彩色图像,遍历每像素的三个分量
188
189 int m=0,n=0,count_xiang_su=0;
190
191 //将图像左下角1/4部分置成黑色
192
193 ofstream outfile("图像像素.txt",ios::in|ios::trunc);
194
195 if(biBitCount==8)//对于灰度图像
196 {
197 //------------------------------------------------------------------------------------
198 //以下完成图像的分割成8*8小单元,并把像素值存储到指定文本中。由于BMP图像的像素数据是从
199 //左下角:由左往右,由上往下逐行扫描的
200 int L1=0;
201 int hang=63;
202 int lie=0;
203 //int L2=0;
204 //int fen_ge=8;
205 for(int fen_ge_hang=0;fen_ge_hang<8;fen_ge_hang++)//64*64矩阵行循环
206 {
207 for(int fen_ge_lie=0;fen_ge_lie<8;fen_ge_lie++)//64*64列矩阵循环
208 {
209 //--------------------------------------------
210 for(L1=hang;L1>hang-8;L1--)//8*8矩阵行
211 {
212 for(int L2=lie;L2<lie+8;L2++)//8*8矩阵列
213 {
214 m=*(pBmpBuf+L1*lineByte+L2);
215 outfile<<m<<"";
216 count_xiang_su++;
217 if(count_xiang_su%8==0)//每8*8矩阵读入文本文件
218 {
219 outfile<<endl;
220 }
221 }
222 }
223 //---------------------------------------------
224 hang=63-fen_ge_hang*8;//64*64矩阵行变换
225 lie+=8;//64*64矩阵列变换
226 //该一行(64)由8个8*8矩阵的行组成
227 }
228 hang-=8;//64*64矩阵的列变换
229 lie=0;//64*64juzhen
230 }
231 }
232
233 //double xiang_su[2048];
234 //ofstream outfile("xiang_su_zhi.txt",ios::in|ios::trunc);
235 if(!outfile)
236 {
237 cout<<"open error!"<<endl;
238 exit(1);
239 }
240 elseif(biBitCount==24)
241 {//彩色图像
242 for(int i=0;i<bmpHeight;i++)
243 {
244 for(int j=0;j<bmpWidth;j++)
245 {
246 for(int k=0;k<3;k++)//每像素RGB三个分量分别置0才变成黑色
247 {
248 //*(pBmpBuf+i*lineByte+j*3+k)-=40;
249 m=*(pBmpBuf+i*lineByte+j*3+k);
250 outfile<<m<<"";
251 count_xiang_su++;
252 if(count_xiang_su%8==0)
253 {
254 outfile<<endl;
255 }
256 //n++;
257 }
258 n++;
259 }
260
261
262 }
263 cout<<"总的像素个素为:"<<n<<endl;
264 cout<<"----------------------------------------------------"<<endl;
265 }
266
267 //将图像数据存盘
268
269 char writePath[]="nvcpy.BMP";//图片处理后再存储
270
271 saveBmp(writePath, pBmpBuf, bmpWidth, bmpHeight, biBitCount, pColorTable);
272
273 //清除缓冲区,pBmpBuf和pColorTable是全局变量,在文件读入时申请的空间
274
275 delete []pBmpBuf;
276
277 if(biBitCount==8)
278 delete []pColorTable;
279 }
280
281 void main()
282 {
283 doIt();
284 }
原创粉丝点击