文章目录
前言
一、bmp格式图的特点
二、bmp格式图的解析
总结
前言
在图像处理中经常会遇到BMP格式图的解析问题,本文简单介绍了bmp格式图的解析方式,并附上相应的C代码。
一、bmp格式图的特点
bmp图通常由图片的头文件信息和像素数据组成,如图1所示,是bmp图的部分数据,
图1 bmp示例图数据
图2 bmp的大小以及分辨率
其中,424D,十进制为66和77是BM字符的ascii值,表示是BMP文件;
2~5字节表示整个BMP文件的大小,0X00031866即202854个字节,与图2的bmp图大小相同;
6~9字节是保留数据段,一般是0;
10~13字节表示图像存储的位置,0X00000036,即第54个字节;
14~17字节表示位图数据头,0X00000028,即40;
18~21字节表示图像宽度,0X00000104,即260;
22~25表示图像高度,0X00000104,即260;
26~27表示色彩平面数,必须为1,即0X0001;
28~29表示每个像素存储的位数,0X0018,即24;
30~33表示字节压缩方式,0表示不压缩;
34~37表示原始位图数据的大小,0X00031830;
38~41表示横向分辨率,0X00000B13;
42~45表示纵向分辨率,0X00000B13;
46~49表示调色板颜色数,0X00000000;
50~53表示重要颜色数,0X01000000;
从54字节开始为像素数据。
二、bmp格式图的解析
解析bmp图中RGB三通道数据的C代码如下所示,首先读出文件头信息,然后读出像素数据。bmp的像素数据是从下往上从左往右存储的,即读出的第一个数据是左下角的像素值,最后一个数据是右上角的像素值。
#include<stdio.h>
#include<stdlib.h>
#include<string.h>struct myBITMAPFILEHEADER
{unsigned int uiSize;unsigned int uiReserved;unsigned int uiOffBits;unsigned int uiSize1;unsigned int uiWidth;unsigned int uiHeight;unsigned short usPlanes;unsigned short usBitcount;unsigned int uiCompression;unsigned int uiSizeImage;unsigned int uiXPelsPerMeter;unsigned int uiYPelsPerMeter;unsigned int uiClrUsed;unsigned int uiClrImportant;
};int main()
{int iWidth,iHeight;FILE *pf;myBITMAPFILEHEADER fileheader;//存放bmp图头文件信息的结构体char acBmpName[256];sprintf(acBmpName,"1.bmp");pf=fopen(acBmpName,"rb");//此处如果以r打开可能会导致数据读不完整if(NULL==pf){perror("fopen");return -1;}unsigned char ucTmp1,ucTmp2;ucTmp1=fgetc(pf);ucTmp2=fgetc(pf);if((ucTmp1!='B')||(ucTmp2!='M')){printf("The file is not a bmp file!");return -1;}//读取文件头信息fread(&fileheader,sizeof(fileheader),1,pf);iWidth=fileheader.uiWidth;iHeight=fileheader.uiHeight;unsigned char *pusData=(unsigned char *)malloc(iHeight*iWidth*sizeof(unsigned char)*3);unsigned char *pusR=(unsigned char *)malloc(iHeight*iWidth*sizeof(unsigned char));unsigned char *pusG=(unsigned char *)malloc(iHeight*iWidth*sizeof(unsigned char));unsigned char *pusB=(unsigned char *)malloc(iHeight*iWidth*sizeof(unsigned char));memset(pusData,0,iHeight*iWidth*sizeof(unsigned char)*3);memset(pusR,0,iHeight*iWidth*sizeof(unsigned char));memset(pusG,0,iHeight*iWidth*sizeof(unsigned char));memset(pusB,0,iHeight*iWidth*sizeof(unsigned char));//读取像素数据fread(pusData,iHeight*iWidth*sizeof(unsigned char)*3,1,pf);fclose(pf);pf=NULL;//解析出R、G和B通道int i,j;for(i=0;i<iHeight;i++){for(j=0;j<iWidth;j++){pusR[iWidth*(iHeight-i-1)+j]=pusData[i*iWidth*3+j*3+2];pusG[iWidth*(iHeight-i-1)+j]=pusData[i*iWidth*3+j*3+1];pusB[iWidth*(iHeight-i-1)+j]=pusData[i*iWidth*3+j*3+0];}}free(pusData);pusData=NULL;free(pusR);pusR=NULL;free(pusG);pusG=NULL;free(pusB);pusB=NULL;return 0;}
总结
以上就是今天要讲的内容,本文仅仅简单介绍了bmp格式图的解析方式,后续还会继续介绍bmp图的存储方式。