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图的存储方式。

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值