BMP文件输入输出

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;
}
原文地址:https://www.cnblogs.com/Shiina-Rikka/p/15506192.html