BMP图的格式以及C语言读取8位灰度图

 BMP文件的格式:BMP文件在实际存储中包含以下的数据:

                  1.位图文件头 占用14个字节

[plain]  view plain  copy
  1. //文件信息  
  2. unsigned short bfType;//文件类型,ASCII字符BM;  
  3.   
  4. //位图文件头     
  5. typedef struct{  
  6.     unsigned long bfSize;//文件大小  
  7.     unsigned short bfReserved1;//备用  
  8.     unsigned short bfReserved2;//备用  
  9.     unsigned long bfOffBits;//图像开始处的字节偏移  
  10.       
  11. }BitMapFileHeader;  
          本来 那个unsigned short bfType数据是在位图文件头之中的,在实际的编程中,需要考虑到结构的对齐原则,呵呵
,本人在vs2013中没有学会如何设置结构体的对齐原则(用代码进行设置不行,#pragme pack(2),,,,#pragme pop),所以只好将那个数据提出位图信息头了.所以结构体占用了12个字节,bfType占用了2个字节

                    2.位图信息  位图信息包含两部分内容一个是位图信息头,另一个是调色板

                                      位图信息头 占用40个字节            

[plain]  view plain  copy
  1. //文图信息头  
  2. typedef struct{  
  3.     unsigned long biSize;//信息头大小  
  4.     unsigned long biWidth;//图像宽度,以像素为单位  
  5.     unsigned long biHeight;//图像高度,以像素为单位  
  6.     unsigned short biPlanes;//位平面数,为1;  
  7.     unsigned short biBitCount;//每像素位数,1,4,8,24  
  8.     unsigned long biCompression;//压缩类型,0为非压缩  
  9.     unsigned long biSizeImage;//压缩图像大小  
  10.     unsigned long biXpelspermeter;//水平分辨率  
  11.     unsigned long biYpelspermeter;//垂直分辨率  
  12.     unsigned long biClrUsed;//使用的色彩数  
  13.     unsigned long biClrImportant;//重要色彩数  
  14. }BitMapInforHeader;  
                                      接下来是调色板了,占用了的字节数是不确定的.2位灰度图占用8个字节,4为灰度图占用64个字节,8位灰度图占用1024个字节.算法如下:

[plain]  view plain  copy
  1. /调色板  
  2. typedef struct  
  3. {  
  4.     unsigned char rgbBlue; //该颜色的蓝色分量    
  5.     unsigned char rgbGreen; //该颜色的绿色分量    
  6.     unsigned char rgbRed; //该颜色的红色分量    
  7.     unsigned char rgbReserved; //保留值    
  8. } RGBQuad;  
在调色板数据结构中,有4个分量分别是红绿蓝和一个保留值,每个分量占用一个字节,8位灰度图实际上有0~255个数据,每个数据4个字节,所以是1024个字节.(白色是由三种颜色绘出来的)

                                  3.像素数据,实际上就是0~255的数值,

[plain]  view plain  copy
  1. //像素数据  
  2.   
  3. unsigned char * * ImgData;//二维数组  

这儿定义了一个二维数组来存储数据

                                     4. 其他数据.   在实际的图像存储过程中会有以下其他数据

[plain]  view plain  copy
  1. //其他数据  
  2. typedef struct OtherData  
  3. {  
  4.     unsigned char extradata;  
  5.     struct OtherData *next;  
  6.   
  7. }OtherData;  

这儿用一个链表来存储,但是有一个缺点就是在链表中只有一个有用的数据,所以结构体的利用率有点低,解决办法是在一个结构体数组中多设置几个数据项.




                         接下来是第二部分C语言来读取8位BMP灰度图

[plain]  view plain  copy
  1. int main()  
  2. {  
  3.     FILE* fp;  
  4.     errno_t err;  
  5.     unsigned int j, k;  
  6.     BitMapFileHeader FileHeader;  
  7.     BitMapInforHeader InfoHeader;  
  8.     RGBQuad *IpRGBQuad;          
  9.         char FileName[30];  
  10.         OtherData  *Otherdata, *temp,*SavePreCursor;  
  11.       
  12.       
  13.     /*图像的读取顺序是从下到上,从左到右*/  
  14.   
  15.     IpRGBQuad = (RGBQuad *)malloc(256*sizeof(RGBQuad));//灰度图为8位的调色板数据为256个结构,1024个字节  
  16.     Otherdata = (OtherData*)malloc(sizeof(OtherData));  
  17.     SavePreCursor = Otherdata;//保存当前指针游标,目的就是保存链表头结点  
  18.     Otherdata->extradata = NULL;  
  19.     Otherdata->next = NULL;  
  20.     strcpy_s(FileName, "图像灰度.bmp");  
  21.   
  22.     err = fopen_s(&fp,FileName, "rb");  
  23.     if( err!=0 )  
  24.     {  
  25.         printf_s("cannot open this file");  
  26.         return 0;  
  27.           
  28.     }  
  29.     //拥有1024个调色板数据  
  30.   
  31.     //printf("%d\n", sizeof(FileHeader));  
  32.     //fread(&FileHeader, sizeof(FileHeader), 1, fp);//读取位图文件头  
  33.     fread(&bfType, sizeof(unsigned short), 1, fp);//读取位图文件头  
  34.     if (bfType == 0x4D42)  
  35.     {  
  36.         printf_s("\n\n------------------------位图文件头----------------------------------------\n\n");  
  37.         fread(&FileHeader, sizeof(FileHeader), 1, fp);//读取位图文件头  
  38.           
  39.   
  40.         printf_s("文件类型%X\n",bfType);  
  41.         //printf_s("%X\n", FileHeader.bfType);  
  42.         printf_s("文件大小(单位字节):%X\n", FileHeader.bfSize);  
  43.         printf_s("备用:%X\n", FileHeader.bfReserved1);  
  44.         printf_s("备用:%X\n", FileHeader.bfReserved2);  
  45.         printf_s("图像开始处的字节偏移:%X\n", FileHeader.bfOffBits);  
  46.   
  47.   
  48.         //读取位图信息头  
  49.         printf_s("\n\n-------------------------位图信息头----------------------------------------\n\n");  
  50.         fread(&InfoHeader, sizeof(InfoHeader), 1, fp);  
  51.   
  52.         printf_s("信息头大小:%X\n", InfoHeader.biSize);  
  53.         printf_s("图像宽度:%d\n", InfoHeader.biWidth);  
  54.         printf_s("图像高度:%d\n", InfoHeader.biHeight);  
  55.         printf_s("位平面数:%X\n", InfoHeader.biPlanes);  
  56.         printf_s("每像素位数:%X\n", InfoHeader.biBitCount);  
  57.         printf_s("压缩类型:%X\n", InfoHeader.biCompression);  
  58.         printf_s("压缩图像大小的字节数:%X\n", InfoHeader.biSizeImage);  
  59.         printf_s("水平分辨率:%X\n", InfoHeader.biXpelspermeter);  
  60.         printf_s("垂直分辨率:%X\n", InfoHeader.biYpelspermeter );  
  61.         printf_s("使用的色彩数:%X\n", InfoHeader.biClrUsed);  
  62.         printf_s("重要色彩数:%X\n", InfoHeader.biClrImportant);  
  63.   
  64.   
  65.         //读取调色板数据  
  66.   
  67.         printf_s("\n\n-----------------------------调色板------------------------------------------\n\n");  
  68.         printf_s("\t红\t绿\t蓝\n");  
  69.       
  70.         fread(IpRGBQuad, sizeof(RGBQuad), 256, fp);  
  71.         for (int i = 0; i < 256; i++)  
  72.         {  
  73.             printf("\t%X\t%X\t%X\n",IpRGBQuad[i].rgbBlue , IpRGBQuad[i].rgbGreen , IpRGBQuad[i].rgbRed );  
  74.         }  
  75.   
  76.   
  77.   
  78.         //读取像素数据  
  79.   
  80.         InfoHeader.biHeight++;  
  81.         InfoHeader.biWidth += 2;  
  82.         ImgData = new unsigned char *[InfoHeader.biHeight];  
  83.         for (j = 0; j < InfoHeader.biHeight; j++)  
  84.         {  
  85.             ImgData[j] = new unsigned char [InfoHeader.biWidth];//定义像素数组ImgData[InfoHeader.biHeight][InfoHeader.biWidth]  
  86.         }  
  87.   
  88.         for ( j = 0; j < InfoHeader.biHeight; j++)  
  89.         {  
  90.             for ( k = 0; k < InfoHeader.biWidth; k++)  
  91.             {  
  92.                 fread(&ImgData[j][k], sizeof(unsigned char), 1, fp);  
  93.                 //  
  94.             }  
  95.               
  96.         }  
  97.           
  98.   
  99.   
  100.         //读取其他数据  
  101.           
  102.         temp = (OtherData*)malloc(sizeof(OtherData));  
  103.         while (!feof(fp))  
  104.         {  
  105.             temp = (OtherData*)malloc(sizeof(OtherData));  
  106.   
  107.             fread(&temp->extradata, sizeof(unsigned char), 1, fp);  
  108.   
  109.             Otherdata->next = temp;  
  110.             Otherdata = Otherdata->next;  
  111.         }  
  112.         Otherdata->next = NULL;//置末尾为空,判断条件  
  113.         Otherdata = SavePreCursor;//使Otherdata重新指向头部  
  114.     }  
  115.       
  116.   
  117.     fclose(fp);  
  118.     system("pause");  
  119.     return 0;  
  120. }  
  • 1
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值