您好,欢迎访问三七文档
当前位置:首页 > 财经/贸易 > 资产评估/会计 > 第二章 BMP位图类的创建与MFC单文档视图类的显示
BMP位图文件的4个组成部分bmp文件大体上分成四个部分。位图文件头BITMAPFILEHEADER、位图信息头BITMAPINFOHEADER、调色板Palette、实际的位图数据ImageDate第1部分为位图文件头BITMAPFILEHEADER,是一个结构体类型,该结构的长度是固定的,为14个字节。其定义如下:typedefstructtagBITMAPFILEHEADER{WORDbfType;DWORDbfSize;WORDbfReserved1;WORDbfReserved2;DWORDbfOffBits;}BITMAPFILEHEADER,FAR*LPBITMAPFILEHEADER,*PBITMAPFILEHEADER;1.文件头信息块0000-0001:文件标识,为字母ASCII码“BM”。0002-0005:文件大小。0006-0009:保留,每字节以“00”填写。000A-000D:记录图像数据区的起始位置。各字节的信息含义依次为:文件头信息块大小,图像描述信息块的大小,图像颜色表的大小,保留(为01)。第2部分为位图信息头BITMAPINFOHEADER,也是一个结构体类型的数据结构,该结构的长度也是固定的,为40个字节(WORD为无符号16位整数,DWORD为无符号32位整数,LONG为32位整数)。其定义如下:typedefstructtagBITMAPINFOHEADER{DWORDbiSize;图像描述信息块的大小,常为28H。LONGbiWidth;LONGbiHeight;WORDbiPlanes;=1WORDbiBitCount;记录像素的位数DWORDbiCompression;数据压缩方式DWORDbiSizeImage;图像区数据的大小LONGbiXPelsPerMeter;指定目标设备的水平分辨率,单位是像素/米LONGbiYPelsPerMeter;DWORDbiClrUsed;位图实际用到的颜色数DWORDbiClrImportant;位图显示过程中重要的颜色数,如果该值为零,则认为所有的颜色都是重要的。}BITMAPINFOHEADER,FAR*LPBITMAPINFOHEADER,*PBITMAPINFOHEADER;2.图像描述信息块000E-0011:图像描述信息块的大小,常为28H。0012-0015:图像宽度。0016-0019:图像高度。001A-001B:图像的plane总数(恒为1)。001C-001D:记录像素的位数,很重要的数值,图像的颜色数由该值决定。001E-0021:数据压缩方式(数值位0:不压缩;1:8位压缩;2:4位压缩)。0022-0025:图像区数据的大小。0026-0029:水平每米有多少像素,在设备无关位图(.DIB)中,每字节以00H填写。002A-002D:垂直每米有多少像素,在设备无关位图(.DIB)中,每字节以00H填写。002E-0031:此图像所用的颜色数,如值为0,表示所有颜色一样重要。第3部分为颜色表。颜色表实际上是一个RGBQUAD结构的数组,数组的长度由biClrUsed指定(如果该值为零,则由biBitCount指定,即2的biBitCount次幂个元素)。RGBQUAD结构是一个结构体类型,占4个字节,其定义如下:typedefstructtagRGBQUAD{BYTErgbBlue;BYTErgbGreen;BYTErgbRed;BYTErgbReserved;}RGBQUAD;3.颜色表颜色表的大小根据所使用的颜色模式而定:2色图像为8字节;16色图像位64字节;256色图像为1024字节。其中,每4字节表示一种颜色,并以B(蓝色)、G(绿色)、R(红色)、alpha(32位位图的透明度值,一般不需要)。即首先4字节表示颜色号0的颜色,接下来表示颜色号1的颜色,依此类推。第4部分是位图数据,即图像数据,其紧跟在位图文件头、位图信息头和颜色表(如果有颜色表的话)之后,记录了图像的每一个像素值。对于有颜色表的位图,位图数据就是该像素颜色在调色板中的索引值;对于真彩色图,位图数据就是实际的R、G、B值(三个分量的存储顺序是B、G、R)。下面分别就2色、16色、256色和真彩色位图的位图数据进行说明:—对于2色位图,用1位就可以表示该像素的颜色,所以1个字节能存储8个像素的颜色值。—对于16色位图,用4位可以表示一个像素的颜色。所以一个字节可以存储2个像素的颜色值。—对于256色位图,1个字节刚好存储1个像素的颜色值。—对于真彩色位图,3个字节才能表示1个像素的颜色值。需要注意两点:第一,Windows规定一个扫描行所占的字节数必须是4的倍数,不足4的倍数则要对其进行扩充。假设图像的宽为biWidth个像素、每像素biBitCount个比特,其一个扫描行所占的真实字节数的计算公式如下:DataSizePerLine=(biWidth*biBitCount/8+3)/4*4那么,不压缩情况下位图数据的大小(BITMAPINFOHEADER结构中的biSizeImage成员)计算如下:biSizeImage=DataSizePerLine*biHeight第二,一般来说,BMP文件的数据是从图像的左下角开始逐行扫描图像的,即从下到上、从左到右,将图像的像素值一一记录下来,因此图像坐标零点在图像左下角。CDIB类的建立classCDib{public:LPRGBQUADm_lpRgbQuad;//颜色表指针LPBYTEm_lpData;//位图数据指针UINTm_numberOfColors;//颜色数BOOLm_bValid;//位图是否有效BOOLm_bHasRgbQuad;//是否有颜色表HPALETTEm_hPalette;//调色板句柄LPBITMAPFILEHEADERm_lpBmpFileHeader;//位图文件头指针LPBITMAPINFOHEADERm_lpBmpInfoHeader;//位图信息头指针LPBITMAPINFOm_lpBmpInfo;//位图信息指针LPBYTEm_lpDib;//位图指针,包含除位图文件头的所有内容、需要动态分配和释放DWORDsize;public:charm_fileName[256];LPCTSTRGetFileName();BOOLLoadFile(LPCTSTRdibFileName);BOOLSaveFile(LPCTSTRfilename);//LPCTSTRGetFileName();LONGGetWidth();LONGGetHeight();DWORDGetSize();//获取位图大小WORDGetBitCount();//获取单个像素所占的位数UINTGetLineByte();//获取每行像素所占字节数UINTGetNumOfColor();//获取位图颜色数LPRGBQUADGetRgbQuad();//获取位图颜色表LPBYTEGetData();//获取位图数据BOOLDraw(CDC*pDC,BYTE*,CPointorigin,CSizesize);//显示位图BOOLHasRgbQuad();//判断是否有颜色表?BITMAPINFO*GetInfo();BOOLIsGrade();//判断是否为灰度图像WORDPaletteSize(LPBYTElpDIB);WORDDIBNumColors(LPBYTElpDIB);BOOLIsValid();//判断位图是否有效?protected:DWORDCalcRgbQuadLength();//计算位图颜色表的长度BOOLMakePalette();//根据颜色表生成调色板voidEmpty(BOOLbFlag=TRUE);//清理空间public:CDib(void);~CDib(void);};主要成员函数:////////////////////////////////////////////////////////////函数功能:从文件加载位图//输入参数:LPCTSTRdibFileName表示待加载位图文件路径//返回值:加载是否成功///////////////////////////////////////////////////////////BOOLCDib::LoadFile(LPCTSTRdibFileName){strcpy(m_fileName,dibFileName);//记录位图文件名CFiledibFile;//选择读模式定义文件对象if(!dibFile.Open((LPCTSTR)m_fileName,CFile::modeRead|CFile::shareDenyWrite)){returnFALSE;}//Empty(FALSE);//为位图文件头指针分配空间,并初始化为m_lpBmpFileHeader=(LPBITMAPFILEHEADER)newBYTE[sizeof(BITMAPFILEHEADER)];memset(m_lpBmpFileHeader,0,sizeof(BITMAPFILEHEADER));//读取位图文件头intnCount=dibFile.Read(m_lpBmpFileHeader,sizeof(BITMAPFILEHEADER));//读bmp文件头信息到指针m_lpBmpfileHeaderif(nCount!=sizeof(BITMAPFILEHEADER))returnFALSE;if(m_lpBmpFileHeader-bfType==0x4d42)//判断是否是bmp文件{DWORDfileLength=dibFile.GetLength();//获取文件长度信息size=fileLength-sizeof(BITMAPFILEHEADER);//文件数据区大小=文件长度-文件头大小m_lpDib=newBYTE[size];memset(m_lpDib,0,size);dibFile.Read((void*)m_lpDib,size);//读除bmp文件头外的所有数据到指针m_lpDibdibFile.Close();//关闭文件m_lpBmpInfo=(LPBITMAPINFO)m_lpDib;//获取bmp文件的信息m_lpBmpInfoHeader=(LPBITMAPINFOHEADER)m_lpDib;//获取文件信息头地址m_lpRgbQuad=(LPRGBQUAD)(m_lpDib+m_lpBmpInfoHeader-biSize);//颜色表地址=pDib+m_lpBmpInfoHeader-biSize;intm_numberOfColors=GetNumOfColor();//颜色数if(m_lpBmpInfoHeader-biClrUsed==0)//m_lpBmpInfoHeader-biClrUsed=m_numberOfColors;//颜色表的大小CalcRgbQuadLength(){returnm_numberOfColors*sizeof(RGBQUAD)}DWORDcolorTableSize=CalcRgbQuadLength();//位图数据区地址m_lpData=m_lpDib+m_lpBmpInfoHeader-biSize+colorTableSize;if(m_lpRgbQuad==(LPRGBQUAD)m_lpData)//Nocolortablem_lpRgbQuad=NULL;m_lpBmpInfoHeader-biSizeImage=GetSize();m_bValid=TRUE;returnTRUE;}else{m_bValid=FALSE;AfxMessageBox(Thisisn'tabitmapfile!);returnFALSE;}}//////////////////////////////////
本文标题:第二章 BMP位图类的创建与MFC单文档视图类的显示
链接地址:https://www.777doc.com/doc-2185679 .html