1. 程式人生 > >BMP影象的處理(24位轉16位)

BMP影象的處理(24位轉16位)

// BMP_24-16.cpp : 定義控制檯應用程式的入口點。
//

///24位bmp影象轉16位bmp影象
#include "stdafx.h"
#include "iostream"
#include "fstream"
using namespace std;

#pragma pack(2)

struct bmp_fileheader   //檔案頭,長度為14Byte固定
{
	unsigned short bfType;
	unsigned long bfSize;
	unsigned short bfReserved1;
	unsigned short bfReserved2;
	unsigned long bfOffBits;
};

struct bmp_infoheader  //檔案資訊頭,長度為40Byte固定
{
	unsigned long biSize;
	unsigned long biWidth;
	unsigned long biHeight;
	unsigned short biPlanes;
	unsigned short biBitCount;
	unsigned long biCompression;
	unsigned long biSizeImage;
	unsigned long biXPelsPerMeter;
	unsigned long biYPelsPerMeter;
	unsigned long biClrUsed;
	unsigned long biClrImportant;
};

fstream input_file;
fstream output_file;

struct bmp_fileheader bfh;
struct bmp_infoheader bih;

unsigned char *src_buff;
unsigned char *dst_buff;

void read_bmp_fileheader()
{
	input_file.read((char*)&bfh, sizeof(struct bmp_fileheader));將bfh強制轉換位char,第二個引數為結構的長度
}

void read_bmp_infoheader()
{
	input_file.read((char*)&bih, sizeof(struct bmp_infoheader));
}

void read_bmp_data()
{
	src_buff = new unsigned char[bih.biHeight*bih.biWidth * 3];
	input_file.read((char*)src_buff, sizeof(unsigned char)*bih.biHeight*bih.biWidth * 3);
}

void bmp_translate()
{
	dst_buff = new unsigned char[bih.biHeight*bih.biWidth * 2];
	int temp[3];
	unsigned long j = 0;
	for (unsigned long i = 0; i < bih.biHeight *bih.biWidth * 3;i+=3)
	{
		temp[0] = src_buff[i] * 32 / 256;
		temp[1] = src_buff[i+1] * 32 / 256;
		temp[2] = src_buff[i+2] * 32 / 256;

		dst_buff[j] = (temp[0] << 3) + ((temp[1] >> 2) << 3);
		dst_buff[j + 1] = (temp[1] << 6) + (temp[2] << 1);
		j += 2;
	}
}

void write_bmp_fileheader()
{
	bfh.bfSize = bfh.bfOffBits + bih.biHeight*bih.biWidth * 2;
	output_file.write((char*)&bfh, sizeof(struct bmp_fileheader));
}

void write_bmp_infoheader()
{
	bih.biBitCount = 16;
	output_file.write((char*)&bih, sizeof(struct bmp_infoheader));
}

void write_bmp_data()
{
	output_file.write((char*)dst_buff, sizeof(unsigned char)*bih.biWidth*bih.biHeight * 2);
}

int _tmain(int argc, _TCHAR* argv[])
{
	input_file.open("E:\\FFOutput\\pic1.bmp", ios::binary | ios::in);
	output_file.open("E:\\FFOutput\\pic116.bmp", ios::binary | ios::out);

	read_bmp_fileheader();
	read_bmp_infoheader();
	read_bmp_data();

	bmp_translate();
	
	write_bmp_fileheader();
	write_bmp_infoheader();
	write_bmp_data();

	cout << "Well Done!" << endl;
	cin.get();

	delete[] src_buff;
	delete[] dst_buff;

	return 0;
}


這幾天嘗試了一下bmp圖片的格式轉換,參考了一下網上的例子,自己嘗試著將24位真彩色的bmp影象轉換為16位,其中16位選擇rgb555分配的方式

在bmp影象中只有單色,16色,256色(灰度圖)有調色盤。

在處理的過程中,先將原圖中的rgb分量讀取出來,然後根據比例計算出5位的資料。

將rgb555的資料拼湊成2Byte的資料。最後一位置零。

處理過程中用C++中的<<和>>移位運算實現。