位图的基本格式.docx
- 文档编号:4552726
- 上传时间:2022-12-06
- 格式:DOCX
- 页数:31
- 大小:1.53MB
位图的基本格式.docx
《位图的基本格式.docx》由会员分享,可在线阅读,更多相关《位图的基本格式.docx(31页珍藏版)》请在冰豆网上搜索。
位图的基本格式
位图的基本格式
第一章位图的基本格式
1.1位图文件格式的产生及发展
BMP图像文件格式是微软公司为其Windows环境设置的标准图像格式,而且Windows系统软件中还同时内含了一系列支持BMP图像处理的API函数,随着Windows在世界范围内的不断普及,BMP文件格式无疑也已经成为PC机上的流行图像文件格式。
它的主要特点可以概括为:
文件结构与PCX文件格式类似,每个文件只能存放一幅图像;图像数据是否采用压缩方式存放,取决于文件的大小与格式,即压缩处理成为图像文件的一个选项,用户可以根据需要进行选择。
其中,非压缩格式是BMP图像文件所采用的一种通用格式。
但是,如果用户确定将BMP文件格式压缩处理,则Windows设计了两种压缩方式:
如果图像为16色模式,则采用RLE4压缩方式,若图像为256色模式,则采用RLE8压缩方式。
同时,BMP图像文件格式可以存储单色、16色、256色以及真彩色四种图像数据,其数据的排列顺序与一般文件不同,它以图像的左下角为起点存储图像,而不是以图像的左上角为起点;而且BMP图像文件格式中还存在另外一个与众不同的特点,即其调色板数据所采用的数据结构中,红、绿、蓝三种基色数据的排列顺序也恰好与其它图像文件格式相反。
总之,BMP图像文件格式拥有许多适合于Windows环境的新特色,而且随着Windows版本的不断更新,微软公司也在不断改进其BMP图像文件格式,例如:
当前BMP图像文件版本中允许采用32位颜色表,而且针对32位Windows的产生,相应的API函数也在不断地推陈出新,这些无疑都同时促成了BMP文件格式的不断风靡。
但由于BMP文件格式只适合于Windows上的应用软件,而对于DOS环境中的各种应用软件则无法提供相应的支持手段,因此这无疑是阻碍BMP文件格式的流通程度超过PCX文件格式的一个重要因素。
1.2位图文件的类型
Windows中定义了两种位图文件类型,即一般位图文件格式与设备无关位图文件格式。
其中,由于设备无关位图(DIB)文件格式具有更强的灵活性与完整的图像数据、压缩方式等定义。
BMP图像文件的结构可以分为如下三个部分:
文件头、调色板数据以及图像数据。
其中文件头的长度为固定值54个字节;调色板数据对所有不超过256色的图像模式都需要进行设置,即使是单色图像模式也不例外,但是对于真彩色图像模式,其对应的BMP文件结构中却不存在相应调色板数据的设置信息;图像数据既可以采用一定的压缩算法进行处理,也可以不必对图像数据进行压缩处理,这不仅与图像文件的大小相关,而且也与对应的图像处理软件是否支持经过压缩处理的BMP图像文件相关。
以下将分别介绍BMP图像文件结构中的这三个重要组成部分。
特别值得注意的是:
BMP图像文件结构设计得相当简单,这无疑有利于图像文件的处理速度,但是同时也使得BMP图像文件格式具有一定的局限性,即一个BMP图像文件只能存储一幅图像。
1.3BMP文件格式的结构定义
BMP图像文件的文件头定义Windows中将BMP图像文件的文件头分成两个数据结构,其中一个数据结构中包含BMP文件的类型、大小和打印格式等信息,称为BITMAPFILEHEADER;另外一个数据结构中则包含BMP文件的尺寸定义等信息,称为BITMAPINFOHEADER。
如果图像文件还需要调色板数据,则将其存放在文件头信息之后。
BITMAPFIEHEADER数据结构在Windows.h中的定义为:
typedefstructuretagBITMAPFILEHEADER
{
WORDbfType;
DWORDbfSize:
WORDbfReserved1;
WORDbfReserved2:
DWORDbfOffBits:
}BITMAPFILEHEADER;
其中,bfType在图像文件存储空间中的数据地址为0,数据类型unsignedchar,内容为固定值“BM”,用于标志文件格式,表示该图像文件为BMP文件。
bfSize的数据地址为2,类型unsignedlong,它以字节为单位,定义位图文件的大小。
BfReserved1与bfReserved2的数据地址分别为6和8,数据类型则都为unsignedint,二者都是BMP文件的保留字,没有任何意义,其值必须为0.
bfOffBits的数据地址为10,数据类型为unsignedlong,它以字节为单位,指示图像数据在文件内的起始地址,即图像数据针对文件头的偏移量。
BITMAPINFOHEADER数据结构用于说明位图的大小,其定义为:
typestructuretagBITMAPINFOHEADER
{
DWORDbiSize:
DWORDbiWidth;
DWORDbiHeight;
WORDbiPlanes:
WORDbiBitCount:
DWORDbiCompression;
DWORDbiSizelmage;
DWORDbiXPelsPerMeter:
DWORDbiYPelsPerMeter:
DWORDbiClrUsed;
DWORDbiClrlmportant;
}BITMAPINFOHEADER;
其中,biSize的数据地址为14,数据类型为unsignedlong,它以字节为单位指定数据结构BITMAPINFOHEADER所占用的存储容量,固定值为40。
biWidth与biHeight的数据地址分别为18和22,数据类型都是unsignedlong,它们分别以像素为单位,给出该BMP文件所描述位图的宽度与高度。
若biHeight的取值为正数,则表明位图为bottom—up类型的DIB位图,而且位图原点为左下角。
若biHeight的取值为负数,则表明位图为top—down类型的DIB位图而且位图原点为左上角。
注意:
一般位图定义中,这两个字段的取值必须为正数。
biPlanes的数据地址为26,类型为unsignedint,它代表目标设备的平面数必须为1。
biBitCount的数据地址为28,类型为unsignedint,它确定每个像素所需要的位数。
当图像为单色时,该字段的取值为1;当图像为16色时,该字段的取值为4;当图像为256色时,该字段的取值为8;当图像为真彩色时,该字段的取值为24。
biCompression的数据地址为30,类型为unsignedlong,它代表bottom—up类型位图的压缩类型(注意:
top—down类型位图不能进行压缩处理),其可能取值及其含义分别为:
若该字段的取值为BI—RGB,则表示文件内的图像数据没有经过压缩处理;若该字段的取值为BI—RLE8,则表示所压缩的图像数据是256色,采用的压缩方法是RLE8;若该字段的取值为BI—RLE4,则表示所压缩的图像数据是16色,采用的压缩方法是RLE4;若该字段的取值为BI—BITFIELDS,则表明图像文件内的数据没有经过压缩处理,而且颜色表由分别表示每个像素点的红、绿、蓝三原色的双字组成。
注意:
BMP文件格式在处理单色或者真彩色图像时,不论图像数据多么庞大,都不对图像数据进行任何压缩处理。
biSizelmage的数据地址为34,类型为unsignedlong,它以字节为单位,给出该BMP内图像数据占用的空间大小。
若图像文件描述BI—RGB位图,则该字段的值必须设置为0。
biXPelsPerMeter字段与biYPelsPerMeter字段的数据地址分别为38与42,类型都是unsignedlong,它们分别以每米像素数为单位,给出位图目的设备水平以及垂直方向的分辨率;其中,应用程序可以根据biXPelsPerMeter字段的值,从源位图组中选择与当前设备特点最匹配的位图。
biClrUsed的数据地址为46,类型为unsignedlong,给出位图实际使用的颜色表中的颜色变址数。
如果该字段的取值为0,则代表本位图使用了biBitCount字段值所代表的最大颜色值,其中biBitCount字段的取值与biCompression所指定的压缩方法相关。
例如:
如果图像为16色,而该字段的取值为10,则代表本位图共使用了12种颜色;如果该字段的取值非零,而且biBitCount字段的取值小于16,则该字段指定图像或者设备驱动器存取的实际颜色数。
若biBitCount字段的取值大于或者等于16,则该字段指定使Windows系统调色板达到最优性能的颜色表大小。
biClrlmportant的数据地址为50,数据类型为unsignedlong,它给出位图显示过程中重要颜色的变址数。
若该字段的取值为0,则表示所有使用的颜色都是重要颜色。
如果位图的描述还需要调色板数据,则应该在BMP文件头之后定义一个颜色表,它包含若干个表项。
其中,每一个表项定义了一种颜色,Windows将其定义为如下的RGBQUAD结构:
typedeftagRGBQUAD
{
BYTErgbBlue;
BYTErgbGreen;
BYTErgbRed;
BYTErgbReserved;
}RGBQUAD;
注意:
RGBQUAD数据结构中,增加了一个保留字段rgbReserved,它不代表任何意义,必须取固定值00同时,RGBQUAD结构定义的颜色值中,红色、绿色与蓝色的排列顺序与一般图像文件的颜色数据排列顺序恰好相反,即:
蓝
2.2.2读入位图
先用下面的语句1)打开一个对话框选择位图文件名,然后用语句2)将变量名保存在FileName变量中。
由于FileName是CString类型,所以在语句3)中打开文件时用GetBuffer()函数取内存中的值。
接着语句4)中用Read()函数读入位图头文件中的数据。
1)CfileDialogFileDia(TRUE,"bmp",NULL,
OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT,
"BMP文件(*.bmp)|*.bmp|所有文件(*.*)|*.*||");
2)FileName=FileDia.GetPathName();
3)rval=file.Open(FileName.GetBuffer(0),
CFile:
:
modeRead|CFile:
:
typeBinary,NULL);
4)file.Read(&bfh,sizeof(bfh));
2.2.3读入位图的数据
在这里定义了一个函数OpenBMPFile()读入位图的数据。
函数的执行语句如下:
先定义位图数据结构的变量并初始化,然后用Read()函数读入BITMAPFILEHEADER和BITMAPINFOHEADER结构的数据。
接着依照BITMAPINFOHEADER结构类型的biBitCount值将位图分类,24bits位图格式和别的位图格式分别处理。
将位图的调色板数据和图像数据皆读入内存。
2.2.4显示滚动条
读入位图数据后,将位图的大小和窗口的大小进行比较,以决定是否显示滚动条。
语句如下
size.cx=m_pBMPInfo->bmiHeader.biWidth;
size.cy=m_pBMPInfo->bmiHeader.biHeight;
GetClientRect(&rect);
if((rect.left-rect.right) (rect.bottom-rect.top) { this->SetScrollSizes(MM_TEXT,size,sizeDefault,sizeDefault); } 2.2.5显示位图 最后调用Invalidate()函数响应OnDraw()函数在屏幕上绘图。 OnDraw()函数的实现方法如下: 一.通过语句段 (1)设置当前文档 二.语句段 (2)读入了当前位图的尺寸和位数 三.语句段(3)调用StretchDIBits()函数在屏幕上绘图 (1)CBmpDoc*pDoc=GetDocument(); ASSERT_VALID(pDoc); (2)longbmp_Width=m_pBMPInfo->bmiHeader.biWidth; longbmp_Height=m_pBMPInfo->bmiHeader.biHeight; USHORTbmp_bits=m_pBMPInfo->bmiHeader.biBitCount; (3)pDC->SetStretchBltMode(COLORONCOLOR); StretchDIBits(pDC->GetSafeHdc(), 0,0,bmp_Width,bmp_Height, 0,0,bmp_Width,bmp_Height, m_pDIBData,m_pBMPInfo, DIB_RGB_COLORS,SRCCOPY); 2.3图像处理前的准备 在进行图像处理之前,先定义几个有用的函数 1)voidGetColor_Index_Origin(CPoint*pPoint,COLORREF*pColor); 2)voidGetColor_TrueColor_Origin(CPoint*pPoint, COLORREF*pColor); 3)BOOLSetColor_Index(CPoint*pPoint,COLORREFColor); 4)BOOLSetColor_TrueColor(CPoint*pPoint, COLORREFColor); 函数1)和2)用于取得屏幕上每个象素的颜色值。 在函数1)和2)中,通过下面的语句块规定只能取得位图内的象素值,而位图范围外的区域都设置为白色。 读入象素值时,依位图格式的不同读取方法也有变化。 24Bits位图像素值只能通过GetColor_TrueColor_Origin()函数来读取,而其它格式的象素值则通过GetColor_Index_Origin()函数来读取。 在GetColor_Index_Origin()函数内部又对8Bits,4Bits,1Bits三种不同的位图格式进行分别处理。 if(pPoint->x>=bmp_Width||pPoint->y>=bmp_Height) { *pColor=0; return; } 函数3)和4)则用来在屏幕上绘制已知象素值的点。 这两个函数同样对不同的象素格式进行不同的处理。 这种情况与前面所述的情形相同。 2.4灰度处理 所谓灰度处理是根据输入图像象素的灰度对输出图像象素的灰度进行再定义。 这种再定义方法有很多种,可以根据不同的需要定义不同的方法。 本例中的方法是先求出图像上点的象素的灰度值,然后将三种原色红、绿、蓝都赋值为此值,再将红、绿、蓝合成象素点绘制到屏幕上。 具体实现流程和算法如下: (1)先判断m_pBMPInfo(包含BMP图像数据的变量)中是否包含数据,因为图像处理都是处理m_pBMPInfo中的数据。 语句如下: if(m_pBMPInfo==NULL) return; (2)通过BeginWaitCursor()函数等待响应。 (3)通过以下语句段取得位图的长宽尺寸和格式 intdwWidth=m_pBMPInfo->bmiHeader.biWidth; intdwHeight=m_pBMPInfo->bmiHeader.biHeight; UINTbitcount=m_pBMPInfo->bmiHeader.biBitCount; (4)对24Bits位图格式和其它格式的位图图像进行不同的处理。 对24Bits图像使用以下函数(a)和(b)读取屏幕上某点的象素值和绘制给定象素值的点。 (a)GetColor_TrueColor_Origin(&point,&Color) (b)SetColor_TrueColor(&point,Color) 对其它格式使用以下函数进行处理 GetColor_Index_Origin(&point,&Color)SetColor_Index(&point,Color)。 (5)首先读取位图数据的点的象素值,进行灰度变换以后再以变换以后的象素值输出到原坐标点。 24Bits格式位图的灰度变换程序示例如下: 1>GetColor_TrueColor_Origin(&point,&Color); DWORDred=Color&0x000000ff; DWORDgreen=Color&0x0000ff00; green>>=8; DWORDblue=Color&0x00ff0000; blue>>=16; Color=round(0.3*red+0.59*green+0.11*blue); red*=2; if(red>255) red-=255; green*=2; if(green>255) green-=255; blue*=2; if(blue>255) blue-=255; green<<=8; blue<<=16; Color=blue|green|red; 2>SetColor_TrueColor(&point,Color); 当然,其它格式的位图的灰度变换只需要改变语句1>和2>即可。 (6)调用Invalidate()函数响应OnDraw()函数在屏幕上绘图。 最后用EndWaitCursor()函数对应BeginWaitCursor()函数。 图 (2)即为对应于图 (1)的灰度处理后的图像。 2.5逆反处理 逆反处理也是灰度处理的一种。 它的原理是对于256色图像,当输入图像的象素的灰度值为a时,输出图像中该象素灰度值为255-a,即输入象素灰度值的逆反值。 具体算法和程序流程如下: (1)先判断m_pBMPInfo(包含BMP图像数据的变量)中是否包含数据,因为图像处理都是处理m_pBMPInfo中的数据。 语句如下: if(m_pBMPInfo==NULL) return; (2)通过BeginWaitCursor()函数等待响应。 (3)通过以下语句段取得位图的长宽尺寸和格式 intdwWidth=m_pBMPInfo->bmiHeader.biWidth; intdwHeight=m_pBMPInfo->bmiHeader.biHeight; UINTbitcount=m_pBMPInfo->bmiHeader.biBitCount; (4)对24Bits位图格式和其它格式的位图图像进行不同的处理。 对24Bits图像使用以下函数(a)和(b)读取屏幕上某点的象素值和绘制给定象素值的点。 (a)GetColor_TrueColor_Origin(&point,&Color) (b)GetColor_TrueColor(&point,Color) 对其它格式使用以下函数进行处理 GetColor_Index_Origin(&point,&Color)SetColor_Index(&point,Color)。 (5)首先读取位图数据的点的象素值,进行逆反变换以后再以变换以后的象素值输出到原坐标点。 24Bits格式位图的逆反变换程序示例如下: 1>GetColor_TrueColor_Origin(&point,&Color); DWORDred=Color&0x000000ff; DWORDgreen=Color&0x0000ff00; green>>=8; DWORDblue=Color&0x00ff0000; blue>>=16; red=255-red; green=255-green; blue=255-blue; green<<=8; blue<<=16; Color=blue|green|red; 2>SetColor_TrueColor(&point,Color); 当然,其它格式的位图的逆反变换只需要改变语句1>和2>即可 (6)调用Invalidate()函数响应OnDraw()函数在屏幕上绘图。 最后用EndWaitCursor()函数对应BeginWaitCursor()函数。 图(3)即为对应于图 (1)的逆反处理后的图像。 2.6平滑处理 (1)先判断m_pBMPInfo(包含BMP图像数据的变量)中是否包含数据,因为图像处理都是处理m_pBMPInfo中的数据。 语句如下: if(m_pBMPInfo==NULL) return; (2)通过BeginWaitCursor()函数等待响应。 (3)通过以下语句段取得位图的长宽尺寸和格式 intdwWidth=m_pBMPInfo->bmiHeader.biWidth; intdwHeight=m_pBMPInfo->bmiHeader.biHeight; UINTbitcount=m_pBMPInfo->bmiHeader.biBitCount; (4)对24Bits位图格式和其它格式的位图图像进行不同的处理。 对24Bits图像使用以下函数(a)和(b)读取屏幕上某点的象素值和绘制给定象素值的点。 (a)GetColor_TrueColor_Origin(&point,&Color) (b)SetColor_TrueColor(&point,Color) 对其它格式使用以下函数进行处理 GetColor_Index_Origin(&point,&Color)SetColor_Index(&point,Color)。 (5)循环读取位图数据的点的象素值,进行平滑处理以后再将处理以后的象素值输出到原坐标点。 (6)调用Invalidate()函数响应OnDraw()函数在屏幕上绘图。 最后用EndWaitCursor()函数对应BeginWaitCursor()函数。 图(4)即为对应于图 (1)的平滑处理后的图像。 2.7对比度增强 (1)先判断m_pBMPInfo(包含BMP图像数据的变量)中是否包含数据,因为图像处理都是处理m_pBMPInfo中的数据。 语句如下: if(m_pBMPInfo==NULL) return; (2)通过BeginWaitCursor()函数等待响应。 (3)通过以下语句段取得位图的长宽尺寸和格式 intdwWidth=m_pBMPInfo->bmiHeader.biWidth; intdwHeight=m_pBMPInfo->bmiHeader.biHeight; UINTbitcount=m_pBMPInfo->bmiHeader.biBitCount; (4)对24Bits位图格式和其它格式的位图图像进行不同的处理。 对24Bits图像使用以下函数(a)和(b)读取屏幕上某点的象素值和绘制给定象素值的点。 (a)GetColor_TrueColor_Origin(&point,&Color) (b)SetColor_TrueColor(&point,Color) 对其它格式使用以下函数进行处理 GetColor_Index_Origin(&point,&Color) SetColor_Index(&point,Color)。 (5)循环读取位图数据的点的象素值,进行对比度增强处理以后再以处理以后的象素值输出到原坐标点。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 位图 基本 格式