为了正常的体验网站,请在浏览器设置里面开启Javascript功能!

bmp读取详解

2013-03-08 11页 doc 148KB 31阅读

用户头像

is_221263

暂无简介

举报
bmp读取详解bmp读取详解 BMP图像文件由三部分组成:位图文件头数据结构,它包含BMP图像文件的类型、显示内容等信息;位图信息数据结构,它包含有BMP图像的宽、高、压缩方法,以及定义颜色等信息。 位图文件主要分为如下3个部分: 块名称 对应Windows结构体定义 大小(Byte) 文件信息头 BITMAPFILEHEADER 14 位图信息头 BITMAPINFOHEADER 40 RGB颜色阵列 BYTE* 由图像长宽尺寸决定 1、   文件信息头BITMAPFILEHEADER 结构体定义如...
bmp读取详解
bmp读取详解 BMP图像文件由三部分组成:位图文件头数据结构,它包含BMP图像文件的类型、显示内容等信息;位图信息数据结构,它包含有BMP图像的宽、高、压缩方法,以及定义颜色等信息。 位图文件主要分为如下3个部分: 块名称 对应Windows结构体定义 大小(Byte) 文件信息头 BITMAPFILEHEADER 14 位图信息头 BITMAPINFOHEADER 40 RGB颜色阵列 BYTE* 由图像长宽尺寸决定 1、   文件信息头BITMAPFILEHEADER 结构体定义如下: typedef struct tagBITMAPFILEHEADER { WORD bfType;   DWORD bfSize;  WORD bfReserved1;  WORD bfReserved2;  DWORD bfOffBits; } BITMAPFILEHEADER; 其中:‍‍ bfType WORD 说明文件的类型,该值必需是0x4D42,也就是字符'BM'。 bfSize DWORD 说明该位图文件的大小,用字节为单位,即整个图像文件的存储需要多少存储空间。 bfReserved1 WORD 保留,必须设置为0 bfReserved2 WORD 保留,必须设置为0 bfOffBits DWORD 说明从文件头开始到实际的图象数据之间的字节的偏移量。这个参数是非常有用的,因为位图信息头和调色板的长度会根据不同情况而变化,所以你可以用这个偏移值迅速的从文件中读取到位数据。   2、位图信息头BITMAPINFOHEADER 结构体定义如下: typedef struct tagBITMAPINFOHEADER { DWORD biSize;  LONG biWidth; 4 LONG biHeight;  WORD biPlanes;  WORD biBitCount;  DWORD biCompression;  DWORD biSizeImage;  LONG biXPelsPerMeter;  LONG biYPelsPerMeter;  DWORD biClrUsed;  DWORD biClrImportant; } BITMAPINFOHEADER; 其中: biSize DWORD 说明BITMAPINFOHEADER结构所需要的字数。一般是40 biWidth LONG 说明图象的宽度,以象素为单位。 biHeight LONG 说明图象的高度,以象素为单位。注:这个值除了用于描述图像的高度之外,它还有另一个用处,就是指明该图像是倒向的位图,还是正向的位图。如果该值是一个正数,说明图像是倒向的,如果该值是一个负数,则说明图像是正向的。大多数的BMP文件都是倒向的位图,也就是说高度值是一个正数。 biPlanes WORD 为目标设备说明位面数,其值将总是被设为1。 biBitCount WORD 说明比特数/象素,其值为1、4、8、16、24、或32。但是由于我们平时用到的图像绝大部分是24位和32位的,所以我们讨论这两类图像。 24示一个像素占三个字节。 biCompression DWORD 说明图象数据压缩的类型,同样我们只讨论没有压缩的类型:BI_RGB。 biSizeImage DWORD 说明图象的大小,以字节为单位。当用BI_RGB时,可设置为0。biSizeImage = biWidth * biHeight (但是此处的biWidth必须是4的倍数,比如biWidth =240,则可仍然是240,但是若biWidth = 241 ,则取biWidth = 244.) biXPelsPerMeter LONG 说明水平分辨率,用象素/米表示。 biYPelsPerMeter LONG 说明垂直分辨率,用象素/米表示。 biClrUsed DWORD 说明位图实际使用的彩色表中的颜色索引数(设为0的话,则说明使用所有调色板项)。 biClrImportant DWORD 说明对图象显示有重要影响的颜色索引的数目,如果是0,表示都重要。 sizeof(BITMAPINFOHEADER) + sizeof(BITMAPFILEHEADER) + biSizeImage = bfSize 比如一幅图像的占用的存储空间是1729590. 则它的组成是:BITMAPINFOHEADER结构所需要的字数 40 ;BITMAPFILEHEADER这个结构所占的字节数14;真正的图像大小1729536.所以 40 + 14 + 1729536 = 1729590 BMP头文件格式以及C语言读取头文件(二) 具体数据举例: 如某BMP文件开头: 424D 4690 0000 0000 0000 4600 0000 2800 0000 8000 0000 9000 0000 0100*1000 0300 0000 0090 0000 A00F 0000 A00F 0000 0000 0000 0000 0000*00F8 0000 E007 0000 1F00 0000 0000 0000*02F1 84F1 04F1 84F1 84F1 06F2 84F1 06F2 04F2 86F2 06F2 86F2 86F2 .... .... BMP文件可分为四个部分:位图文件头、位图信息头、彩色板、图像数据阵列,在上图中已用*分隔。 一、图像文件头 1)1:(这里的数字代表的是"字",即两个字节,下同)图像文件头。424Dh=’BM’,表示是Windows支持的BMP格式。 2)2-3:整个文件大小。4690 0000,为00009046h=36934。 3)4-5:保留,必须设置为0。 4)6-7:从文件开始到位图数据之间的偏移量。4600 0000,为00000046h=70,上面的文件头就是35字=70字节。 5)8-9:位图图信息头长度。 6)10-11:位图宽度,像素为以单位。8000 0000,为00000080h=128。 7)12-13:位图高度,以像素为单位。9000 0000,为00000090h=144。 8)14:位图的位面数,该值总是1。0100,为0001h=1。 二、位图信息头 9)15:每个像素的位数。有1(单色),4(16色),8(256色),16(64K色,高彩色),24(16M色,真彩色),32(4096M色,增强型真彩色)。1000为0010h=16。 10)16-17:压缩说明:有0(不压缩),1(RLE 8,8位RLE压缩),2(RLE 4,4位RLE压缩,3(Bitfields,位域存放)。RLE简单地说是采用像素数+像素值的方式进行压缩。T408采用的是位域存放方式,用两个字节表示一个像素,位域分配为r5b6g5。图中0300 0000为00000003h=3。 11)18-19:用字节数表示的位图数据的大小,该数必须是4的倍数,数值上等于位图宽度×位图高度×每个像素位数。0090 0000为00009000h=80×90×2h=36864。 12)20-21:用象素/米表示的水平分辨率。A00F 0000为0000 0FA0h=4000。 13)22-23:用象素/米表示的垂直分辨率。A00F 0000为0000 0FA0h=4000。 14)24-25:位图使用的颜色索引数。设为0的话,则说明使用所有调色板项。 15)26-27:对图象显示有重要影响的颜色索引的数目。如果是0,表示都重要。 具体代码C语言执行:(D  盘中有文件名为1的bmp图像) #include #include typedef  struct  tagBITMAPFILEHEADER { unsigned short int  bfType;       //位图文件的类型,必须为BM unsigned long       bfSize;       //文件大小,以字节为单位 unsigned short int  bfReserverd1; //位图文件保留字,必须为0 unsigned short int  bfReserverd2; //位图文件保留字,必须为0 unsigned long       bfbfOffBits;  //位图文件头到数据的偏移量,以字节为单位 }BITMAPFILEHEADER; typedef  struct  tagBITMAPINFOHEADER { long biSize;                //该结构大小,字节为单位 long  biWidth;              //图形宽度以象素为单位 long  biHeight;               //图形高度以象素为单位 short int  biPlanes;           //目标设备的级别,必须为1 short int  biBitcount;      //颜色深度,每个象素所需要的位数 short int  biCompression;        //位图的压缩类型 long  biSizeImage;           //位图的大小,以字节为单位 long  biXPelsPermeter;       //位图水平分辨率,每米像素数 long  biYPelsPermeter;       //位图垂直分辨率,每米像素数 long  biClrUsed;         //位图实际使用的颜色表中的颜色数 long  biClrImportant;       //位图显示过程中重要的颜色数 }BITMAPINFOHEADER; typedef  struct { BITMAPFILEHEADER  file; //文件信息区 BITMAPINFOHEADER  info; //图象信息区 }bmp; bmp  readbmpfile(void); //函数声明 int main(void) {   bmp m;          //定义一个结构变量   m=readbmpfile(); //读取一个位图   getchar();   return 0; }     bmp  readbmpfile(void) { bmp  m;        //定义一个位图结构   FILE *fp;  if((fp=fopen( "d:\\1.bmp", "r"))==NULL)  { printf( "can't open the bmp imgae.\n ");    exit(0);  } else { fread(&m.file.bfType,sizeof(char),1,fp); printf("类型为%c",m.file.bfType); fread(&m.file.bfType,sizeof(char),1,fp); printf("%c\n",m.file.bfType);        fread(&m.file.bfSize,sizeof(long),1,fp); printf("文件长度为%d\n",m.file.bfSize);  fread(&m.file.bfReserverd1,sizeof(short int),1,fp); printf("保留字1为%d\n",m.file.bfReserverd1); fread(&m.file.bfReserverd2,sizeof(short int),1,fp); printf("保留字2为%d\n",m.file.bfReserverd2); fread(&m.file.bfbfOffBits,sizeof(long),1,fp); printf("偏移量为%d\n",m.file.bfbfOffBits); fread(&m.info.biSize,sizeof(long),1,fp); printf("此结构大小为%d\n",m.info.biSize); fread(&m.info.biWidth,sizeof(long),1,fp); printf("位图的宽度为%d\n",m.info.biWidth); fread(&m.info.biHeight,sizeof(long),1,fp); printf("位图的高度为%d\n",m.info.biHeight); fread(&m.info.biPlanes,sizeof(short),1,fp); printf("目标设备位图数%d\n",m.info.biPlanes); fread(&m.info.biBitcount,sizeof(short),1,fp); printf("颜色深度为%d\n",m.info.biBitcount); fread(&m.info.biCompression,sizeof(long),1,fp); printf("位图压缩类型%d\n",m.info.biCompression); fread(&m.info.biSizeImage,sizeof(long),1,fp); printf("位图大小%d\n",m.info.biSizeImage); fread(&m.info.biXPelsPermeter,sizeof(long),1,fp); printf("位图水平分辨率为%d\n",m.info.biXPelsPermeter); fread(&m.info.biYPelsPermeter,sizeof(long),1,fp); printf("位图垂直分辨率为%d\n",m.info.biYPelsPermeter); fread(&m.info.biClrUsed,sizeof(long),1,fp); printf("位图实际使用颜色数%d\n",m.info.biClrUsed); fread(&m.info.biClrImportant,sizeof(long),1,fp); printf("位图显示中比较重要颜色数%d\n",m.info.biClrImportant); } return m; } 结果执行如下:‍‍ 1.BMP文件的读入 BMP文件分为4个组成部分,那么BMP文件的读入也要按照4个组成部分依次进行处理,即先处理BITMAPFILEHEADER结构,然后是BITMAPINFOHEADER结构、颜色表,最后是位图数据。 首先,有关BITMAPFILEHEADER、BITMAPINFOHEADER、RGBQUAD等结构的定义包含在头文件“Windows.h”中,应把其包含进来。 #include "Windows.h" 其次,为了后面对图像进行修改及存盘方便,我们定义了几个全局变量,用来存放读入图像的位图数据、宽、高、颜色表及每像素位数等信息。所定义的全局变量如下: unsigned char *pBmpBuf;//读入图像数据的指针 int bmpWidth;//图像的宽 int bmpHeight;//图像的高 RGBQUAD *pColorTable;//颜色表指针 int biBitCount;//图像类型,每像素位数 根据BMP文件结构,BMP文件读入操作的基本流程如图1-8所示。    图1-8 BMP文件读入操作流程图 readBmp()函数实现了BMP文件的读取操作,下面的代码是对readBmp()函数的说明和实现。 /**************************************** ******************************* * 函数名称: *     readBmp() * *函数参数: *    char *bmpName -文件名字及路径 * *返回值: *    0为失败,1为成功 * *说明:给定一个图像文件名及其路径,读图像 的位图数据、宽、高、颜色表及每像素 *      位数等数据进内存,存放在相应的全局变量中 **************************************** *******************************/ bool readBmp(char *bmpName) { //二进制读方式打开指定的图像文件 FILE *fp=fopen(bmpName,"rb"); if(fp==0) return 0; //跳过位图文件头结构BITMAPFILEHEADER fseek(fp, sizeof(BITMAPFILEHEADER),0); //定义位图信息头结构变量,读取位图信息头进内存,存放在变量head中 BITMAPINFOHEADER head; fread(&head, sizeof(BITMAPINFOHEADER), 1,fp); //获取图像宽、高、每像素所占位数等信息 bmpWidth = head.biWidth; bmpHeight = head.biHeight; biBitCount = head.biBitCount; //定义变量,计算图像每行像素所占的字节数(必须是4的倍数) int lineByte=(bmpWidth * biBitCount/8+3)/4*4; //灰度图像有颜色表,且颜色表表项为256 if(biBitCount==8){ //申请颜色表所需要的空间,读颜色表进内存 pColorTable=new RGBQUAD[256]; fread(pColorTable,sizeof(RGBQUAD),256,fp); } //申请位图数据所需要的空间,读位图数据进内存 pBmpBuf=new unsigned char[lineByte * bmpHeight]; fread(pBmpBuf,1,lineByte * bmpHeight,fp); //关闭文件 fclose(fp); return 1; } 2.BMP文件的存盘 给定图像路径名以及图像的数据,对图像的写操作也是按照BMP文件4个组成部分进行分别处理的。其基本流程如图1-9所示。     图1-9 BMP文件写操作流程图 saveBmp()函数实现了BMP文件的写操作,该函数的说明及代码实现如下。 /***************************************** * 函数名称: *     saveBmp() * *函数参数: *    char *bmpName-文件名字及路径 *    unsigned char *imgBuf-待存盘的位图数据 *    int width-以像素为单位待存盘位图的宽 *    int height-以像素为单位待存盘位图高 *    int biBitCount-每像素所占位数 *    RGBQUAD *pColorTable-颜色表指针 *返回值: *    0为失败,1为成功 * *说明:给定一个图像位图数据、宽、高、颜色表 指针及每像素所占的位数等信息, *      将其写到指定文件中 ****************************************** *****************************/ bool saveBmp(char *bmpName, unsigned char *imgBuf, int width, int height, int biBitCount, RGBQUAD *pColorTable) { //如果位图数据指针为0,则没有数据传入,函数返回 if(!imgBuf) return 0; //颜色表大小,以字节为单位,灰度图像颜色表 为1024字节,彩色图像颜色表大小为0 int colorTablesize=0; if(biBitCount==8) colorTablesize=1024; //待存储图像数据每行字节数为4的倍数 int lineByte=(width * biBitCount/8+3)/4*4; //以二进制写的方式打开文件 FILE *fp=fopen(bmpName,"wb"); if(fp==0) return 0; //申请位图文件头结构变量,填写文件头信息 BITMAPFILEHEADER fileHead; fileHead.bfType = 0x4D42;//bmp类型 //bfSize是图像文件4个组成部分之和 fileHead.bfSize= sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + colorTablesize + lineByte*height; fileHead.bfReserved1 = 0; fileHead.bfReserved2 = 0; //bfOffBits是图像文件前3个部分所需空间之和 fileHead.bfOffBits=54+colorTablesize; //写文件头进文件 fwrite(&fileHead, sizeof(BITMAPFILEHEADER),1, fp); //申请位图信息头结构变量,填写信息头信息 BITMAPINFOHEADER head; head.biBitCount=biBitCount; head.biClrImportant=0; head.biClrUsed=0; head.biCompression=0; head.biHeight=height; head.biPlanes=1; head.biSize=40; head.biSizeImage=lineByte*height; head.biWidth=width; head.biXPelsPerMeter=0; head.biYPelsPerMeter=0; //写位图信息头进内存 fwrite(&head, sizeof(BITMAPINFOHEADER),1, fp); //如果灰度图像,有颜色表,写入文件 if(biBitCount==8) fwrite(pColorTable, sizeof(RGBQUAD),256, fp); //写位图数据进文件 fwrite(imgBuf, height*lineByte, 1, fp); //关闭文件 fclose(fp); return 1; } 对于readBmp()和saveBmp()函数的简单调用如下: void main() { //读入指定BMP文件进内存 char readPath[]="dog.BMP"; readBmp(readPath); //输出图像的信息 printf("width=%d,height=%d, biBitCount =%d\n",bmpWidth,bmpHeight, biBitCount); //将图像数据存盘 char writePath[]="dogcpy.BMP"; saveBmp(writePath, pBmpBuf, bmpWidth, bmpHeight, biBitCount, pColorTable); //清除缓冲区,pBmpBuf和pColorTable是 全局变量,在文件读入时申请的空间 delete []pBmpBuf; if(biBitCount==8) delete []pColorTable; } 该main()函数将指定BMP文件读入内存,将图像信息打印输出,最后又原样存入指定文件中。读者可以打开程序当前目录下的“dog.bmp”和“dogcpy.bmp”两个文件进行对比。 以上对于BMP文件的读写函数仅针对灰度图像(biBitCount=8)和彩色图像(biBitCount=24)两种格式,对于其他如biBitCount=1的图像类型,读者可以根据需要,自己对程序作简单的修改即可实现。
/
本文档为【bmp读取详解】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑, 图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。 本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。 网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。

历史搜索

    清空历史搜索