1. 程式人生 > 其它 >BMP檔案輸入輸出

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;
}