BMP输入输出
BMP头文件格式
这个部分主要是规定了BMP的储存格式。这篇博客
我们只要知道可以利用windows.h库中的几个结构体,开结构体,知道结构体的位数来读信息就好了。当然文件头内的内容应该原封输出到输出文件中。
另外有用的信息是里面的宽度和高度信息,用来读入数值。
fgetc & fputc
内容来自这个
fgetc的返回值是int型,会每次以二进制形式读取文件的8位数据。fputc同理,会每次输出8位数据。
fopen
其实这个东西也是文件读入的一种形式,但是OIer过于习惯freopen,从而忽略的fopen这个方式。
FILE *stream;
FILE *sstream;
stream = fopen("xx.bmp", "rb");
sstream = fopen("xx.bmp", "wb");
其中“b”是指以二进制形式打开
code
#include<bits/stdc++.h>
#include<windows.h>
using namespace std;
const int MAXM = 5e3 + 5;
const int MAXN = 1e3 + 5;
tagBITMAPFILEHEADER t1;
tagBITMAPINFOHEADER t2;
FILE *stream, *sstream;
//输入 因为每次fgetc读入8位,但是有些数据是16或32位,需要多次读取
inline int read(int n)
{
int res = 0;
for(register int i = 1; i<= n; ++i)
{
int tmp = fgetc(stream);
res = res | (tmp << ((i - 1) * 8));
}
return res;
}
//输出 同理
inline void out(int n, int x)
{
for(register int i = 1; i <= n; ++i)
{
int tmp = (x >> ((i - 1) * 8));
fputc(tmp, sstream);
}
}
//储存RGB信息,gray是计算灰度值的方法,有很多
struct rgb
{
long long b, r, g;
int gray;
inline void input()
{
b = read(1);
r = read(1);
g = read(1);
gray = (b * 0.3 + r * 0.59 + g * 0.11);
out(1, gray);
out(1, gray);
out(1, gray);
}
}ph[MAXM][MAXN];
int main()
{
//开文件
stream = fopen("test.bmp", "rb");
sstream = fopen("testout.bmp", "wb");
//开文件失败返回
if(stream == NULL)
{
cerr << "ERROR OPEN FILE" << endl;
exit(-1);
}
//读入结构体的一些信息
t1.bfType = read(2), out(2, t1.bfType);
t1.bfSize = read(4), out(4, t1.bfSize);
t1.bfReserved1 = read(2), out(2, t1.bfReserved1);
t1.bfReserved2 = read(2), out(2, t1.bfReserved2);
t1.bfOffBits = read(4), out(4, t1.bfOffBits);
t2.biSize = read(4), out(4, t2.biSize);
t2.biWidth = read(4), out(4, t2.biWidth);
t2.biHeight = read(4), out(4, t2.biHeight);
//之后还有28字节数据,不要了,原路输出
for(register int i = 1; i <= 7; ++i)
{
register int x = read(4);
out(4, x);
}
//读入rgb信息并输出
for(register int i = 1; i <= t2.biWidth; ++i)
{
for(register int j = 1; j <= t2.biHeight; ++j)
{
ph[i][j].input();
}
}
//记得关文件 return 0;
fclose(stream);
fclose(sstream);
return 0;
}