位图BitMap图像的读取与存储

本文详细介绍了位图文件的组成部分及结构,包括BITMAPFILEHEADER、BITMAPINFOHEADER、调色板和图像数据等,并提供了C++代码示例来演示如何读取和写入位图文件。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  做图像处理时的源文件一般要用无损的图像文件格式,位图(BitMap)是windows系统下可存储无压缩图像的文件格式。要实现位图文件的读取和存储,首先要明白位图文件的的存储数据结构。位图文件由四部分依序组成:BITMAPFILEHEADER,BITMAPINFOHEADER,调色板,Image Data。

1)BITMAPFILEHEADER结构的长度是固定的14个字节,描述文件的有关信息。其数据结构是:

[cpp]  view plain copy
  1. typedef struct tagBITMAPFILEHEADER {  
  2.         WORD    bfType;//must be 0x4D42.  
  3.         DWORD   bfSize;//the size of the whole bitmap file.  
  4.         WORD    bfReserved1;  
  5.         WORD    bfReserved2;  
  6.         DWORD   bfOffBits;//the sum bits of BITMAPFILEHEADER,BITMAPINFOHEADER and RGBQUAD;the index byte of the image data.  
  7. } BITMAPFILEHEADER, FAR *LPBITMAPFILEHEADER, *PBITMAPFILEHEADER;  
2)BITMAPINFOHEADER结构的长度是固定的40个字节,描述图像的有关信息。其数据结构是:
[cpp]  view plain copy
  1. typedef struct tagBITMAPINFOHEADER{  
  2.         DWORD      biSize;//the size of this struct.it is 40 bytes.  
  3.         LONG       biWidth;//the width of image data. the unit is pixel.  
  4.         LONG       biHeight;//the height of image data. the unit is pixel.  
  5.         WORD       biPlanes;//must be 1.  
  6.         WORD       biBitCount;//the bit count of each pixel.usually be 1,4,8,or 24.  
  7.         DWORD      biCompression;//is this image compressed.0 indicates no compression.  
  8.         DWORD      biSizeImage;//the size of image data.  
  9.         LONG       biXPelsPerMeter;  
  10.         LONG       biYPelsPerMeter;  
  11.         DWORD      biClrUsed;  
  12.         DWORD      biClrImportant;  
  13. } BITMAPINFOHEADER, FAR *LPBITMAPINFOHEADER, *PBITMAPINFOHEADER;  
    值得注意的是,其中biSizeImage指的是实际图像数据的大小,以字节为单位。其计算公式是:宽*高。其中宽必须是4的整数倍。如果不是整数倍,则取大于宽的离4的整数倍最近的数值。这个要求可能是因为现在的计算机大都是32位4字节的,计算机每次读取4字节,这样每行的像素可以整数次读取完成。

3)调色板:现在的计算机大都是32位或是更高,于是图像数据可用真彩色24位表达的,即每个像素均由24bit表示,每8bit表示RGB三色中的一色。但以前的计算机处理能力较差,图像用1位、4位或8位,即BITMAPINFOHEADER中的biBitCount不是24,这时又想表达出RGB色彩就需要调色板,调色板即使将图像数据中使用的一种颜色对应到RGB颜色中,这样图像数据中的像素值就是一个索引值,真正的像素值是这个索引值对应的调色板中的值。调色板是一个数组,数组中每个元素就是一个rgb颜色,对于8位图像,最多可表达256种颜色,调色板的大小就是256。调色板数组中每个元素的数据结构:

[cpp]  view plain copy
  1. typedef struct tagRGBQUAD {  
  2.         BYTE    rgbBlue;  
  3.         BYTE    rgbGreen;  
  4.         BYTE    rgbRed;  
  5.         BYTE    rgbReserved;  
  6. } RGBQUAD;  
  7. typedef RGBQUAD FAR* LPRGBQUAD;  
4)图像数据对于1位图像,1个像素用1bit存储,对于24位图像,1个像素用24bit存储。位图文件的数据是从下而上,从左而右存储的。所以说,读取的时候,最先读到的是图像左下方的像素,最后读取的是图像右上方的图像。

用c++写的位图文件的读取与存储方法:
类结构(BitMap.h):
[cpp]  view plain copy
  1. #include <windows.h>  
  2. class BitMap  
  3. {  
  4. public:  
  5.     BitMap();  
  6.     ~BitMap();  
  7. protected:  
  8.     BITMAPFILEHEADER fileHeader;  
  9.     BITMAPINFOHEADER infoHeader;  
  10. public:  
  11.     int width_p,height_p,bitCount;  
  12.     unsigned char *dataBuf;  
  13.     LPRGBQUAD colorTable;  
  14.     bool Read(char *fileName);  
  15.     bool Write(char *_fileName);     
  16. };  
方法(BitMap.cpp):
[cpp]  view plain copy
  1. #include "BitMap.h"  
  2. #include <stdio.h>  
  3. #include <iostream>  
  4. #include <fstream>  
  5. using namespace std;  
  6. #define NULL 0  
  7.   
  8. BitMap::BitMap(){};  
  9. BitMap::~BitMap(){};  
  10.   
  11. //read bitmap info from a file  
  12. bool BitMap::Read(char* fileName)  
  13. {  
  14.     FILE *_f=fopen(fileName,"rb");//open file  
  15.     if(_f==NULL) return false;  
  16.   
  17.     fread(&fileHeader,sizeof(BITMAPFILEHEADER),1,_f);//read BITMAPFILEHEADER  
  18.   
  19.     fread(&infoHeader,sizeof(BITMAPINFOHEADER),1,_f);//read BITMAPINFOHEADER  
  20.     width_p=infoHeader.biWidth;  
  21.     height_p=infoHeader.biHeight;  
  22.     bitCount=infoHeader.biBitCount;  
  23.   
  24.     if(bitCount==8)//if colorTable exist,read colorTable  
  25.     {  
  26.         colorTable=new RGBQUAD[256];  
  27.         fread(&colorTable,sizeof(RGBQUAD),256,_f);  
  28.     }  
  29.   
  30.     dataBuf=new unsigned char[infoHeader.biSizeImage];//read image data  
  31.     fread(dataBuf,1,infoHeader.biSizeImage,_f);  
  32.   
  33.     fclose(_f);//close file  
  34.     return true;  
  35. }  
  36.   
  37. //write bitmap info to a file  
  38. bool BitMap::Write(char * _fileName)  
  39. {  
  40.     FILE* f=fopen(_fileName,"wb");//create or open file to be written  
  41.     if(f==NULL) return false;  
  42.   
  43.     int colorTableSize=0;//if bitcount is 24, there is no color table.  
  44.     if(bitCount==8)//if bitcount is 8 ,the size of color table is 256*4,4B is the size of RGBQUAD.  
  45.         colorTableSize=sizeof(RGBQUAD)*256;  
  46.   
  47.     int headerSize=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+ colorTableSize;//the size of the header of bmp file.  
  48.     int lineSize=(width_p*bitCount/8+3)/4*4;//the size of each line in bmp file.  
  49.     int dataSize=lineSize*height_p;//the size of the image data of bmp file.  
  50.      
  51.     fileHeader.bfType=0x4D42;//set the attribute of BITMAPFILEHEADER  
  52.     fileHeader.bfSize=headerSize+dataSize;  
  53.     fileHeader.bfReserved1=0;  
  54.     fileHeader.bfReserved2=0;  
  55.     fileHeader.bfOffBits=headerSize;  
  56.   
  57.     infoHeader.biSize=40;//set the attribute of BITMAPINFOHEADER  
  58.     infoHeader.biWidth=width_p;  
  59.     infoHeader.biHeight=height_p;  
  60.     infoHeader.biPlanes=1;  
  61.     infoHeader.biBitCount=bitCount;  
  62.     infoHeader.biCompression=0;  
  63.     infoHeader.biSizeImage=dataSize;  
  64.     infoHeader.biClrImportant=0;  
  65.     infoHeader.biXPelsPerMeter=0;  
  66.     infoHeader.biYPelsPerMeter=0;  
  67.   
  68.     fwrite(&fileHeader,sizeof(BITMAPFILEHEADER),1,f);//write the data of BITFILEHEADER to bmp file  
  69.     fwrite(&infoHeader,sizeof(BITMAPINFOHEADER),1,f);//write the data of BITINFOHEADER to bmp file  
  70.     if(bitCount==8)//if color table exists,write the data of color table to bmp file  
  71.     {  
  72.         colorTable=new RGBQUAD[256];  
  73.         fwrite(&colorTable,sizeof(RGBQUAD),256,f);  
  74.     }  
  75.     fwrite(dataBuf,1,dataSize,f);//write the image data to bmp file  
  76.   
  77.     fclose(f);//data writting is finished,close the bmp file.  
  78.     return true;  
  79. }  
程序入口:
[cpp]  view plain copy
  1. void main()  
  2. {  
  3.     BitMap* bm=new BitMap();  
  4.     bm->Read("nv.BMP");  
  5.     bm->Write("nvnew.bmp");  
  6.     delete bm;  
  7. }  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值