原创 24位真彩图格式解析(含VC代码)。

2010-2-22 22:58 3675 3 3 分类: MCU/ 嵌入式
BMP格式24位位图,是目前应用比较广泛使用的位图格式,其文件头和数据区都比较简单,这里来分析一下。
本例使用visual c++ 6.0版对一幅320*230的24位BMP文件进行操作,采用的是命令行格式。
1、文件头分析
点击看大图
图1 BMP文件头
从00000000h地址开始,为14个字节的BMP文件头,包含一些信息。
42 4d:‘B’、‘M’两个字母的ASCII码,表示该文件是BMP文件;
B6 5E 03 00:表示本文件的大小,可以通过在windows环境下利用文件属性查看,这里“低对低,高对高”的原则,可以知道,本文件大小是:220854字节;
00 00 00 00:4个保留字节;
36 00 00 00:文件头加信息头的大小,也就是排除了真正数据区的信息区的大小,一共是54字节,36为其十六进制表示;
这样文件头总计14字节,包含文件类型、文件大小、信息区大小等。
2、信息头分析
点击看大图
图2 BMP信息头
紧接着文件头的40个字节,是信息头,这样文件头的大小加上信息头的大小14+40正好等于54字节。
28 00 00 00:信息头大小,为40字节;
40 01 00 00:图像宽度,为320像素;
E6 00 00 00:图像高度,为230像素;
01 00:图像设备等级;
18 00:颜色深度,为24位;
00 00 00 00:压缩格式,表示未压缩;
80 5E 03 00:数据区字节数,等于文件大小减去信息区(54字节),也等于总像素数乘3;
后面到横线前的零不经常使用, 我们不去管它。
3、使用VC读取信息区信息的定义和代码:
文件头结构体定义:
typedef struct _BMPFileHeader
{
    unsigned char B;
    unsigned char M;
    unsigned long FileSize;
    unsigned long Reserved1;
    unsigned long HeaderLength;

}BMPFileHeader;
信息头结构体定义:
typedef struct _BMPFileInfo
{
    unsigned long InfoSize;
    unsigned long ImageWidth;
    unsigned long ImageHeight;
    unsigned int Level;
    unsigned int ColorDepth;
    unsigned long Compress;
    unsigned long PixelBytes;
    unsigned long horizon;
    unsigned long vertical;
    unsigned long offset1;
    unsigned long offset2;
}BMPFileInfo;
定义自己的结构体:
BMPFileHeader MyHeader;
BMPFileInfo MyInfo;
读取并打印文件头数据函数:
void PrintBMPHeader()//打印BMP文件头
{
    FILE *mybmp;
    mybmp=fopen(FILEPATH,"r");

    fread(&MyHeader.B,1,1,mybmp);
    fread(&MyHeader.M,1,1,mybmp);
    fread(&MyHeader.FileSize,1,4,mybmp);
    fread(&MyHeader.Reserved1,1,4,mybmp);
    fread(&MyHeader.HeaderLength,1,4,mybmp);

    printf("FileType:\t\t%c %c P \n",MyHeader.B,MyHeader.M);
    printf("FileSize:\t\t%ld  bytes\n",MyHeader.FileSize);
    printf("HeaderLength:\t\t%ld \n",MyHeader.HeaderLength);

    fclose(mybmp);
}
读取并打印信息头数据函数:
void PrintBMPInfo()
{
    FILE *mybmp;
    mybmp=fopen(FILEPATH,"r");

    fseek(mybmp,14,0);
    fread(&MyInfo.InfoSize,1,4,mybmp);
    fread(&MyInfo.ImageWidth,1,4,mybmp);
    fread(&MyInfo.ImageHeight,1,4,mybmp);
    fread(&MyInfo.Level,1,2,mybmp);
    fread(&MyInfo.ColorDepth,1,2,mybmp);
    fread(&MyInfo.Compress,1,4,mybmp);
    fread(&MyInfo.PixelBytes,1,4,mybmp);
    fread(&MyInfo.horizon,1,4,mybmp);
    fread(&MyInfo.vertical,1,4,mybmp);
    fread(&MyInfo.offset1,1,4,mybmp);
    fread(&MyInfo.offset2,1,4,mybmp);

    printf("InfoSize:\t\t%ld\n",MyInfo.InfoSize);
    printf("ImageWidth:\t\t%ld\n",MyInfo.ImageWidth);
    printf("ImageHeight:\t\t%ld\n",MyInfo.ImageHeight);
    printf("Level:\t\t\t%ld\n",MyInfo.Level);
    printf("ColorDepth:\t\t%ld\n",MyInfo.ColorDepth);
    printf("PixelBytes:\t\t\t%ld\n",MyInfo.PixelBytes);

    fclose(mybmp);
}
程序执行效果图:
30929126-5149-4593-82d5-f6c89b4af5b6.jpg
图3 程序执行效果

由此来看,我们不仅仅读取好了文件信息,并且把它们都存入了自己定义的结构体便于使用。下次,我将讲述一下如何进行图像(特种)压缩。
PARTNER CONTENT

文章评论0条评论)

登录后参与讨论
EE直播间
更多
我要评论
0
3
关闭 站长推荐上一条 /3 下一条