BMP图片 读取

学习资料主要来源是CSDN论坛,维基百科,和Microsoft官方文档。

BMP,BitMap图,是微软提出的用来存储位图的标准格式,它现在不仅仅只适用于Windows系统,还已经拓展到了其他平台,于是 BMP 也有了别名 DIB Device-independent BitMap 设备独立的位图。

首先BMP格式使用的是小端模式记录数据块。比如有一个数据块是0x123456 其中数学上,最高位的一个字节直接为12,中间位的一个字节为34,最低位的一个字节为56。用低地址去记录低位,是谓“小端模式”。于是BMP格式中,实际存储的是0x563412。(计算机按字节存储!)

BMP图片主要由文件头,信息头,调色板和像素组四部分构成。

文件头是交代图片的文件属性信息的。通常,在BMP图片装载入内存后,此部分将被抛弃。

信息头是交代图片的图像属性信息的,诸如图片每像素所使用的位数、图片宽度、高度、压缩方式等等。历史上,这个头有着各种各样的标准,常见的形式是windows NT版本时提出来的。虽年代久远,但仍被广泛使用,以致于现在大多数BMP图片依然是这个的组成结构。不同的BMP格式标准的区别主要在于信息头的大小,这可以通过信息头的第一个参数,长为四个字节的DIB Header Size 区分。本文及程序只考虑DIB Header Size = 40 , 这即是这种最常见的情况。

调色板一般只有在颜色位数小于等于8时,才存在。它交代该位图所使用的颜色索引。颜色索引即是一种从颜色到序号的映射,存在的目的是节省空间开销(这主要是当前情况下,一般显示器所能显示的RGB颜色内,每个通道被限制为8位,取值为0~255)

像素组是记录每个像素点具体的颜色或颜色索引。在颜色位数小于等于8时,像素组用相应位数记录颜色索引。比如1位图中,一个字节描述了8个像素的信息。颜色位数为16时,有RGB555和RGB565两种情况,BMP图片不压缩时(信息头的参数Compress = 0),使用的就是RGB555模式。即R、G、B三个通道分别用五位,最高位悬空置零。颜色位数为24位时,R、G、B三个通道分别用八位。颜色位数为32位时,R、G、B三个通道依旧分别用八位,剩下八位悬空置零。

值得注意的是,像素组有比特补零的标准。这主要是因为计算机一次处理四字节的效率更好这个特点决定的。也就是说如果一张图片的尺寸是121*120,它的BMP的像素组尺寸实际是124*120,多出的位置零。注意,信息头的参数宽不因此改变,是121。

另一个值得注意的是,当信息头的参数高为正数时,图片将是倒立的,即像素组第一行第一列的数据实际为图像的最后一行第一列的像素,像素组第一行第二列的数据实际为图像最后一行第二列的像素。这或许是定义标准的大师更倾向于数学坐标系的方向吧!

真正去写程序时,建议使用那些二进制查看器,来打开BMP格式的图片,并对照着标准,一 一比对,相信很快就能上手了!

BMP图片 读取_第1张图片

BMP图片 读取_第2张图片

 

最后,完整程序如下,需要另行使用其他程序 显示这个输出的格式为 " *.txt " 的图像矩阵。

个人建议用 matlab  的 importdata 函数和相关矩阵函数。

 

// BMP图片格式读取与图像矩阵输出

# include 
# include 
# include 
# include 
# include 
# include 
using namespace std;

// 此类用以记录颜色本身 
class Color 
{
	public:
		Color( unsigned short red_new = 0, unsigned short green_new = 0, 
			unsigned short blue_new = 0, unsigned short alpha_new = 0 );
		void setRed( unsigned short red_new );
		void setGreen( unsigned short green_new );
		void setBlue( unsigned short blue_new );
		void setAlpha( unsigned short alpha_new);
		unsigned short getRed() const;
		unsigned short getGreen() const;
		unsigned short getBlue() const;
		unsigned short getAlpha() const;
	private:
		unsigned short red,green,blue,alpha;
};

// 此类用以记录文件头 
// signature 文件属性
// size 文件大小
// reserved1 / reserved2 保留字
// offset 文件头到像素组的偏移量 
class FileHeader
{
	public:
		void open( ifstream &bmpFile );
		void setSignature( unsigned short signature_new );
		void setFileSize( unsigned long fileSize_new );
		void setReserved1( unsigned short Reserved1_new );
		void setReserved2( unsigned short Reserved2_new);
		void setOffset( unsigned long offset_new);
		unsigned short getSignature() const;
		unsigned long getFileSize() const;
		unsigned short getReserved1() const;
		unsigned short getReserved2() const;
		unsigned long getOffset() const;
		void display() const;
	private:
		unsigned short signature, reserved1, reserved2;
		unsigned long fileSize, offset;
};

// 此类用以记录信息头
// headerSize 信息头大小(字节数) 
// width 图像宽度(像素) 
// height 图像高度(像素) 
// planes 缺省为1 
// bitsPerPixel 每像素所使用的比特数 
// compression 压缩方式 0为不压缩 
// imageSize 图像大小 不压缩时,此项为 0 
// xPixelsPerMeter 水平分辨率 
// yPixelsPerMeter 垂直分辨率 
// colorTableCount 调色板的颜色索引数 0为使用所有调色板项 
// impoColorCount 重要影响的颜色索引数 0为所有颜色索引都重要 
class InfoHeader
{
	public:
		void open( ifstream &bmpFile );
		void setHeaderSize( unsigned long headerSize_new );
		void setWidth( unsigned long width_new );
		void setHeight( unsigned long height_new );
		void setPlanes( unsigned short planes_new);
		void setBitsPerPixel( unsigned short bitsPerPixel_new );
		void setCompression( unsigned long compression_new );
		void setImageSize( unsigned long imageSize_new );
		void setXPixelsPerMeter( unsigned long xPixelsPerMeter_new );
		void setYPixelsPerMeter( unsigned long yPixelsPerMeter_new );
		void setColorTableCount( unsigned long colorTableCount_new );
		void setImpoColorCount( unsigned long impoColorCount_new );
		unsigned long getHeaderSize() const;
		unsigned long getWidth() const;
		unsigned long getHeight() const;
		unsigned short getPlanes() const;
		unsigned short getBitsPerPixel() const;
		unsigned long getCompression() const;
		unsigned long getImageSize() const;
		unsigned long getXPixelsPerMeter() const;
		unsigned long getYPixelsPerMeter() const;
		unsigned long getColorTableCount() const;
		unsigned long getImpoColorCount() const;
		void display() const;
	private:
		 unsigned long headerSize, width, height, compression, imageSize, 
		 	xPixelsPerMeter, yPixelsPerMeter, colorTableCount, impoColorCount;
  		 unsigned short planes, bitsPerPixel;
};

// 此类用以描述调色板 
// colorCount 颜色索引数
// 颜色索引值存在 vector  
class ColorTable: public vector< Color >
{
	public:
		void open( ifstream& bmpFile ); 
		void setColorCount( unsigned short colorCount_new );
		unsigned short getColorCount() const;
		void display() const;
	private:
		unsigned short colorCount; 
};

// 此类为像素组的基类
// 为像素组类提供必要的信息
class BaseOfPixelArray
{
	public:
		void setWidth( unsigned long width_new );
		void setHeight( unsigned long height_new );	
		void setBitsPerPixel( unsigned long height_new );	
		unsigned long getWidth() const;
		unsigned long getHeight() const;
		unsigned long getBitsPerPixel() const;
	protected:
		unsigned short bitsPerPixel;
		unsigned long width, height;
} ;

// 1, 4, 8位时的像素组 
// 由于当图像的高为正数时,图像数据为倒向,于是我们反过来输出 
class PixelArray8: public BaseOfPixelArray, public vector< vector< unsigned short > >
{
	public:
		void open( ifstream & );
};

// 16, 24, 32位时的像素组 
// 由于当图像的高为正数时,图像数据为倒向,于是我们反过来输出 
class PixelArray32: public BaseOfPixelArray, public vector< vector< Color > >
{
	public:
		void open( ifstream & );
};

// 此类用以记录整个BMP图像文件 
class BmpImgFile
{
	public: 
		void open( ifstream &bmpFile );
		FileHeader& getFileHeader();
		InfoHeader& getInfoHeader();
		ColorTable& getColorTable();
		PixelArray8& getPixelArray8();
		PixelArray32& getPixelArray32();
		void displayPixelArray( ofstream &bmpTxT ) const;
	private:
		FileHeader fHeader;
		InfoHeader iHeader;
		ColorTable cTable;
		PixelArray8 pArray8;
		PixelArray32 pArray32;
};

Color::Color( unsigned short red_new, unsigned short green_new , 
			unsigned short blue_new, unsigned short alpha_new )
{
	setRed( red_new );
	setGreen( green_new );
	setBlue( blue_new );
	setAlpha( alpha_new );
}

void Color::setRed( unsigned short red_new )
{
	red = red_new;
}

void Color::setGreen( unsigned short green_new )
{
	green = green_new;
}

void Color::setBlue( unsigned short blue_new )
{
	blue = blue_new;
}

void Color::setAlpha( unsigned short alpha_new)
{
	alpha = alpha_new;
}

unsigned short Color::getRed() const
{
	return red;
}

unsigned short Color::getGreen() const
{
	return green;
}

unsigned short Color::getBlue() const
{
	return blue;
}

unsigned short Color::getAlpha() const
{
	return alpha;
}

void FileHeader::open( ifstream &bmpFile )
{
	unsigned short signature_new, reserved1_new, reserved2_new;
	unsigned long fileSize_new, offset_new;
	bmpFile.read( reinterpret_cast< char * >( &signature_new ), sizeof( unsigned short ) );
    bmpFile.read( reinterpret_cast< char * >( &fileSize_new ), sizeof( unsigned long ) );
    bmpFile.read( reinterpret_cast< char * >( &reserved1_new ), sizeof( unsigned short ) );
    bmpFile.read( reinterpret_cast< char * >( &reserved2_new ), sizeof( unsigned short ) );
    bmpFile.read( reinterpret_cast< char * >( &offset_new ), sizeof( unsigned long ) );
    setSignature( signature_new );
    setFileSize( fileSize_new );
    setReserved1( reserved1_new );
    setReserved2( reserved2_new );
    setOffset( offset_new );
}

void FileHeader::setSignature( unsigned short signature_new )
{
	signature = signature_new;
}

void FileHeader::setFileSize( unsigned long fileSize_new )
{
	fileSize = fileSize_new;
}

void FileHeader::setReserved1( unsigned short reserved1_new )
{
	reserved1 = reserved1_new;
}

void FileHeader::setReserved2( unsigned short reserved2_new)
{
	reserved2 = reserved2_new;
}

void FileHeader::setOffset( unsigned long offset_new)
{
	offset = offset_new;
}

unsigned short FileHeader::getSignature() const
{
	return signature;
}

unsigned long FileHeader::getFileSize() const
{
	return fileSize;
}

unsigned short FileHeader::getReserved1() const
{
	return reserved1;
}

unsigned short FileHeader::getReserved2() const
{
	return reserved2;
}

unsigned long FileHeader::getOffset() const
{
	return offset;
}

void FileHeader::display() const
{
	cout << "Loading file header..." << endl;
	cout << left << setw(15) << "signature:" << signature << endl;
    cout << left << setw(15) << "fileSize:" << fileSize << endl;
    cout << left << setw(15) << "reserved1:" << reserved1 << endl;
    cout << left << setw(15) << "reserved2:" << reserved2 << endl;
    cout << left << setw(15) << "offset:" << offset << endl;
    cout << "File header has been successfully outputed;" << endl;
}

void InfoHeader::open( ifstream &bmpFile )
{
	unsigned long headerSize_new, width_new, height_new, compression_new, imageSize_new, 
		 	xPixelsPerMeter_new, yPixelsPerMeter_new, colorTableCount_new, impoColorCount_new;
  	unsigned short planes_new, bitsPerPixel_new;
    bmpFile.read( reinterpret_cast< char * >( &headerSize_new ), sizeof( unsigned long ) );
    bmpFile.read( reinterpret_cast< char * >( &width_new ), sizeof( unsigned long ) );
    bmpFile.read( reinterpret_cast< char * >( &height_new ), sizeof( unsigned long ) );
    bmpFile.read( reinterpret_cast< char * >( &planes_new ), sizeof( unsigned short ) );
    bmpFile.read( reinterpret_cast< char * >( &bitsPerPixel_new ), sizeof( unsigned short ) );
    bmpFile.read( reinterpret_cast< char * >( &compression_new ), sizeof( unsigned long ) );
    bmpFile.read( reinterpret_cast< char * >( &imageSize_new ), sizeof( unsigned long ) );
    bmpFile.read( reinterpret_cast< char * >( &xPixelsPerMeter_new ), sizeof( unsigned long ) );
    bmpFile.read( reinterpret_cast< char * >( &yPixelsPerMeter_new ), sizeof( unsigned long ) );
    bmpFile.read( reinterpret_cast< char * >( &colorTableCount_new ), sizeof( unsigned long ) );
    bmpFile.read( reinterpret_cast< char * >( &impoColorCount_new ), sizeof( unsigned long ) );
    setHeaderSize( headerSize_new );
    setWidth( width_new );
    setHeight( height_new );
    setPlanes( planes_new );
    setBitsPerPixel( bitsPerPixel_new );
    setCompression( compression_new );
    setImageSize( imageSize_new );
    setXPixelsPerMeter( xPixelsPerMeter_new );
    setYPixelsPerMeter( yPixelsPerMeter_new );
    setColorTableCount( colorTableCount_new );
    setImpoColorCount( impoColorCount_new );
}

void InfoHeader::setHeaderSize( unsigned long headerSize_new )
{
	headerSize = headerSize_new;
}

void InfoHeader::setWidth( unsigned long width_new )
{
	width = width_new;
}

void InfoHeader::setHeight( unsigned long height_new )
{
	height = height_new;
}

void InfoHeader::setPlanes( unsigned short planes_new)
{
	planes = planes_new;
}

void InfoHeader::setBitsPerPixel( unsigned short bitsPerPixel_new )
{
	bitsPerPixel = bitsPerPixel_new;
}

void InfoHeader::setCompression( unsigned long compression_new )
{
	compression = compression_new;
}

void InfoHeader::setImageSize( unsigned long imageSize_new )
{
	imageSize = imageSize_new;
}

void InfoHeader::setXPixelsPerMeter( unsigned long xPixelsPerMeter_new )
{
	xPixelsPerMeter = xPixelsPerMeter_new;
}

void InfoHeader::setYPixelsPerMeter( unsigned long yPixelsPerMeter_new )
{
	yPixelsPerMeter = yPixelsPerMeter_new;
}

void InfoHeader::setColorTableCount( unsigned long colorTableCount_new )
{
	colorTableCount = colorTableCount_new;
}

void InfoHeader::setImpoColorCount( unsigned long impoColorCount_new )
{
	impoColorCount = impoColorCount_new;
}

unsigned long InfoHeader::getHeaderSize() const
{
	return headerSize;
}

unsigned long InfoHeader::getWidth() const
{
	return width;
}

unsigned long InfoHeader::getHeight() const
{
	return height;
}

unsigned short InfoHeader::getPlanes() const
{
	return planes;
}

unsigned short InfoHeader::getBitsPerPixel() const
{
	return bitsPerPixel;
}

unsigned long InfoHeader::getCompression() const
{
	return compression;
}

unsigned long InfoHeader::getImageSize() const
{
	return imageSize;
}

unsigned long InfoHeader::getXPixelsPerMeter() const
{
	return xPixelsPerMeter;
}

unsigned long InfoHeader::getYPixelsPerMeter() const
{
	return yPixelsPerMeter;
}

unsigned long InfoHeader::getColorTableCount() const
{
	return colorTableCount;
}

unsigned long InfoHeader::getImpoColorCount() const
{
	return impoColorCount;
}

void InfoHeader::display() const
{
	cout << "Loading information header..." << endl;
	cout << left << setw(20) << "headerSize:" << headerSize << endl;
    cout << left << setw(20) << "width:" << width << endl;
    cout << left << setw(20) << "height:" << height << endl;
    cout << left << setw(20) << "planes:" << planes << endl;
    cout << left << setw(20) << "bitsPerPixel:" << bitsPerPixel << endl;
    cout << left << setw(20) << "compression:" << compression << endl;
    cout << left << setw(20) << "imageSize:" << imageSize << endl;
    cout << left << setw(20) << "xPixelsPerMeter:" << xPixelsPerMeter << endl;
    cout << left << setw(20) << "yPixelsPerMeter:" << yPixelsPerMeter << endl;
    cout << left << setw(20) << "colorTableCount:" << colorTableCount << endl;
    cout << left << setw(20) << "impoColorCount:" << impoColorCount << endl;
    cout << "Information header has been successfully outputed;" << endl;
}

void ColorTable::open( ifstream &bmpFile ) 
{
	unsigned long nowColor;
	this->resize( colorCount );
	for ( int i=0; i < colorCount; ++i )
	{
		bmpFile.read( reinterpret_cast< char * >( &nowColor ), sizeof( unsigned long ) );
		this->at( i ).setRed( nowColor << 8 >> 3*8 );
		this->at( i ).setGreen( nowColor << 2*8 >> 3*8 );
		this->at( i ).setBlue( nowColor <<3*8 >> 3*8 );
		this->at( i ).setAlpha( nowColor >> 3*8);
	}
}

void ColorTable::setColorCount( unsigned short colorCount_new )
{
	colorCount = colorCount_new;
}

unsigned short ColorTable::getColorCount() const
{
	return colorCount;
}

void ColorTable::display() const
{
	cout << "Loading color table..." << endl;
	cout << "index  Red  Green  Blue  Alpha" << endl;
	for ( int i = 0; i < colorCount; ++i )
		cout << left << setw( 8 ) << i << left << setw( 8 ) << this->at( i ).getRed()
			<< left << setw( 8 ) << this->at( i ).getGreen() << left << setw( 8 ) 
			<< this->at( i ).getBlue() << left << setw( 8 ) << this->at( i ).getAlpha() << endl;
	cout << "Color table has been successfully outputed;" << endl; 
}

void BaseOfPixelArray::setWidth( unsigned long width_new )
{
	width = width_new;
}

void BaseOfPixelArray::setHeight( unsigned long height_new )	
{
	height = height_new;
}

void BaseOfPixelArray::setBitsPerPixel( unsigned long bitsPerPixel_new )
{
	bitsPerPixel = bitsPerPixel_new;
}

unsigned long BaseOfPixelArray::getWidth() const
{
	return width;
}

unsigned long BaseOfPixelArray::getHeight() const
{
	return height;
}

unsigned long BaseOfPixelArray::getBitsPerPixel() const
{
	return bitsPerPixel;
}

void PixelArray8::open( ifstream &bmpFile )
{
	unsigned long nw, i, nh, dataItem;
	this->resize( height );
	for ( i = 0; i < height; ++i )
		this->at( i ).resize( width );
	for ( nh = 0; nh < height; ++nh )
	{
		nw = 0;
		while ( nw < width )
		{
			bmpFile.read( reinterpret_cast< char * >( &dataItem ), sizeof( unsigned long ) );
			dataItem = ( dataItem << 24 ) + ( dataItem >> 8 << 24 >> 8 )
				 + ( dataItem << 8 >> 24 << 8 ) + ( dataItem >> 24 );
			i = 0;
			while ( (i < 32 / bitsPerPixel ) && ( nw < width ) )
			{
				++i;
				++nw;
				this->at( nh ).at( nw - 1 ) = dataItem >> ( 32 - bitsPerPixel );
				dataItem = dataItem << bitsPerPixel;
			}
		}
	}
}

void PixelArray32::open( ifstream &bmpFile )
{
	unsigned short red_new, green_new, blue_new, nothing;
	unsigned long nw, nh, i;
	unsigned char temp1, temp2, temp3, temp4;
	this->resize( height );
	for ( i = 0; i < height; ++i )
		this->at( i ).resize( width );
	if ( ( width * bitsPerPixel ) % 32 == 0)
		nothing = 0;
	else
		nothing = ( ( ( width * bitsPerPixel ) / 32 + 1 ) * 32 - width * bitsPerPixel ) / 8;
	for ( nh = 0; nh < height; ++nh )
	{
		if (nh == 0)
		{
			int b;
			b=1;
		}
		for ( nw = 0; nw < width; ++nw )
		{
			bmpFile.read( reinterpret_cast< char * >( &temp1 ), sizeof( unsigned char ) );
			bmpFile.read( reinterpret_cast< char * >( &temp2 ), sizeof( unsigned char ) );
			switch ( bitsPerPixel)
			{
				case 16 :
					red_new = ( ( ( temp2 & 0x7C ) >> 2 ) + 1 ) * 8; 
					blue_new = ( ( temp1 & 0x1F ) + 1 ) * 8;
					green_new = ( ( ( ( temp1 & 0xE0 ) >> 5 )+ ( ( temp2 & 3 ) << 3 ) ) + 1 ) * 8;
					break;
				case 24 :
					bmpFile.read( reinterpret_cast< char * >( &temp3 ), sizeof( unsigned char ) );
					red_new = temp3;
					green_new = temp2;
					blue_new = temp1;   
					break;
				case 32 :
					bmpFile.read( reinterpret_cast< char * >( &temp3 ), sizeof( unsigned char ) );
					bmpFile.read( reinterpret_cast< char * >( &temp4 ), sizeof( unsigned char ) );					
					red_new = temp3;
					green_new = temp2;
					blue_new = temp1;
					break;
			}
			this->at( nh ).at( nw ).setBlue( blue_new );
			this->at( nh ).at( nw ).setGreen( green_new );
			this->at( nh ).at( nw ).setRed( red_new );
		}
		for ( i = 1; i <= nothing; ++i )
			bmpFile.read( reinterpret_cast< char * >( &temp1 ), sizeof( unsigned char ) );			
	}
}

void BmpImgFile::open( ifstream &bmpFile )
{
	fHeader.open( bmpFile );
	iHeader.open( bmpFile );
	if ( iHeader.getBitsPerPixel() <= 8 )
	{
		if ( iHeader.getColorTableCount() == 0 )
			cTable.setColorCount( 1 << iHeader.getBitsPerPixel() );
		else
			cTable.setColorCount( iHeader.getColorTableCount() );
		cTable.open( bmpFile );
		iHeader.getWidth();
		pArray8.setWidth( iHeader.getWidth() );
		pArray8.setHeight( iHeader.getHeight() );
		pArray8.setBitsPerPixel( iHeader.getBitsPerPixel() );
		pArray8.open( bmpFile );
	}
	else
	{
		pArray32.setWidth( iHeader.getWidth() );
		pArray32.setHeight( iHeader.getHeight() );
		pArray32.setBitsPerPixel( iHeader.getBitsPerPixel() );
		pArray32.open( bmpFile );
	}
}

FileHeader& BmpImgFile::getFileHeader() 
{
	return fHeader;
}

InfoHeader& BmpImgFile::getInfoHeader()
{
	return iHeader;
}

ColorTable& BmpImgFile::getColorTable()
{
	return cTable;
}

void BmpImgFile::displayPixelArray( ofstream &bmpTxT ) const
{
	cout << "Loading the pixel array..." << endl;
	long i, j, height = iHeader.getHeight(), 
		width = iHeader.getWidth(), bitsPerPixel = iHeader.getBitsPerPixel();
	for ( i = height - 1; i >= 0; --i )
	{
		for ( j = 0; j < width; ++j )
		{
			 
			if ( bitsPerPixel <= 8 ) 
				bmpTxT << cTable.at( pArray8.at( i ).at( j ) ).getRed() << " ";
			else
				bmpTxT << pArray32.at( i ).at( j ).getRed() << " "; 
		}
		bmpTxT << endl;
	}
	for ( i = height - 1; i >= 0; --i )
	{
		for ( j = 0; j < width; ++j )
			if ( bitsPerPixel <= 8 )
				bmpTxT << cTable.at( pArray8.at( i ).at( j ) ).getGreen() << " ";
			else
				bmpTxT << pArray32.at( i ).at( j ).getGreen() << " ";
		bmpTxT << endl; 
	}
	for ( i = height - 1; i >= 0; --i )
	{
		for ( j = 0; j < width; ++j )
			if ( bitsPerPixel <= 8 )
				bmpTxT << cTable.at( pArray8.at( i ).at( j ) ).getBlue() << " ";
			else
				bmpTxT << pArray32.at( i ).at( j ).getBlue() << " ";
		bmpTxT << endl; 
	}
	cout << "It has been successfully outputed in the root directory with the \"txt\" postfix." << endl;
}

int main()
{
	unsigned short order;
	string path;
	cout << "Welcome to will's ImageRead program" << endl;
	cout << "Just choose the order number and the program will implement the order." << endl;
	cout << "1 Read the image" << endl;
	cout << "0 Terminate the program" << endl;
	cin >> order;
	if ( order == 0 )
	{
		return 0;
	}
	cout << "Please input the path of the image file. Case sensitive." << endl;
	cout << "If the image file is just in the root diretory, just input the file name, like \"lena.bmp\"." << endl;
	cin >> path;
	ifstream inBmpFile( path.c_str(), ios::in | ios::binary );
	ofstream outBmpFile;
	BmpImgFile bmp1;
	bmp1.open( inBmpFile );
	do 
	{
		cout << endl;
		cout << "1 Show the file header" << endl;
		cout << "2 Show the information header" << endl;
		cout << "3 Show the color table" << endl;
		cout << "4 Output the pixel array" << endl;
		cout << "5 Read another image file" << endl;
		cout << "0 Terminate the program"<< endl;
		cin >> order;
		cout << endl;
		switch ( order )
		{
			case 1 : 
				bmp1.getFileHeader().display();
				break;
			case 2 : 
				bmp1.getInfoHeader().display();
				break;
			case 3 : 
				if (bmp1.getInfoHeader().getBitsPerPixel() > 8)
					cout << "The bmp file doesn't contain the color table!" << endl;
				else
					bmp1.getColorTable().display();
				break;
			case 4 : 
				path.at( path.size() - 1 )='t';
				path.at( path.size() - 2 )='x';
				path.at( path.size() - 3 )='t';
				outBmpFile.open( path.c_str(), ios::out | ios::binary );
				bmp1.displayPixelArray( outBmpFile ); 
				break;
			case 5 : 
				cout << "Please input the path of the image file. Case sensitive." << endl;
				cout << "If the image file is just in the root diretory, ";
				cout << "just input the file name, like \"lena.bmp\"." << endl;
				cin >> path;
				inBmpFile.open( path.c_str(), ios::in | ios::binary );
				bmp1.open( inBmpFile );
				break;
		}
	}
	while ( order != 0 );
	cout << "Good day!";
}

 

你可能感兴趣的:(图像处理)