2024年4月28日发(作者:)

一、BMP文件读写

1.BMP文件组成

BMP文件有文件头、位图信息头、颜色信息和图像数据等四部分组成。

BMP文件头数据包含BMP文件类型、文件大小和位图起始位置等信息。其结构定义如

下:

typedef struct tagBITMAPFILEHEADER

{

WORD bfType;//位图文件的类型,必须为BMP

DWORD bfSize;//位图文件的大小,以字节为单位

WORD bfReserved1;//位图文件保留字,必须为0

WORD bfReserved2;//位图文件保留字,必须为0

DWORD bfOffBits;//位图数据的起始位置,以相对于位图文件头的偏移量表示,以

//字节单位

}BITMAPFILEHEADER;

BMP位图信息头数据用于说明位图的尺寸等信息。其结构定义如下:

typedef struct tagBITMAPINFOHEADER

{

DWORD biSize;//本结构所占用字节数

LONG biWidth;//位图的宽度,以像素为单位

LONG biHeight;//位图的高度,以像素为单位

WORD biplanes;//目标设备的级别,必须为1

WORD biBitCount;//每个像素所需要的位数,必须为1(双色),4(16色),8(256

//色)或24(真彩色)之一

DWORD biCompression;//位图压缩类型,必须为0(不压缩),1(BI_RLE8压缩类

//型)或2(BI_RLE4压缩类型)之一

DWORD biSizeIMage;//位图的大小,以字节为单位

LONG biXPelsPerMeter;//位图水平分辨率,每米像素数

LONG biXPelsPerMeter;// 位图垂直分辨率,每米像素数

DWORD biClrUsed;//位图实际使用的颜色表中的颜色数

DWORD biClrImportant;//位图显示过程中重要的颜色数

}BITMAPINFOHEADER

颜色表用于说明位图中的颜色,它有若干个表项,每一表项是一个RGBQUAR类型的

结构,定义一种颜色。颜色表中RGBQUAR结构数据的个数是由biBitCount来确定。

位图数据记录了位图的每一个像素值,记录顺序是咋扫描行内是从左到右,扫描行间是

从下到上。

2.BMP文件读写

本文所编写是程序是基于MFC,而在MFC中,没有处理DIB位图的类,所以结合面

向对象的方法来设计一个专门处理DIB位图的专用类CDib类。其接口文件和实现文件分别

为CDIB.H和。文件CDIB.H中包含了CDib类的类声明有关的所有信息,

包含了CDib类中各函数的实现。(代码参见程序)

首先,在VC6.0中,利用向导,新建一个工程名为RWbmp的单文档应用程序,然后再

将设计好的CDIB.H和添加到该工程中,最后再在现有的菜单上添加两个用于实

现对BMP文件操作的菜单项,结果如下图所示。

图1.1 设计菜单项

接下来,就是为“BMP文件操作”菜单项下的两个子菜单项:“打开”和“保存”,在

CRWbmpView类中添加消息映射和编写相应的消息响应处理函数。

由于在CDib类中,已经实现了对DIB文件的读写操作的功能函数:void LoadFile(const

char* dibFileName)、void SaveFile(const CString filename),所以在编写相应子菜单项的消息

响应处理函数时,可以直接调用CDib类中的相应的功能函数。

对以“打开”子菜单项的消息响应处理函数,其实现代码如下所示:

void CRWbmpView::OnBmpOpen()

{

// TODO: Add your command handler code here

CFileDialogdlg(TRUE,_T("BMP"),_T("*.BMP"),OFN_HIDEREADONLY|

OFN_OVERWRITEPROMPT,_T("位图文件(*.BMP)|*.BMP|"));

("%s",hName() );

le(filename);

if(IDOK==l ())

Invalidate();

}

对以“保存”子菜单项的消息响应处理函数,其实现代码如下所示:

void CRWbmpView::OnBmpSave()

{

// TODO: Add your command handler code here

CFileDialogdlg(FALSE,_T("BMP"),_T("*.BMP"),OFN_HIDEREADONLY|

OFN_OVERWRITEPROMPT,_T("位图文件(*.BMP)|*.BMP|"));

CString filename;

("%s",hName());

if(filename!="*.BMP")

le(filename);

Invalidate();

if(IDOK==l())

}

在CRWbmpView类的头文件中,添加两个变量成员:CDib CDib、CString filename,并

在该头文件中添加代码:#include "CDIB.h"。

最后修改CRWbmpView类中OnDraw(CDC *pDC)函数实现函数,其代码为:

void CRWbmpView::OnDraw(CDC* pDC)

{

CRWbmpDoc* pDoc = GetDocument();

ASSERT_VALID(pDoc);

// TODO: add draw code for native data here

if(filename!="")

{

CBitmap m_bitmap;

HBITMAPhBitmap=(HBITMAP)LoadImage(NULL,_T(filename),

IMAGE_BITMAP,0,0,

LR_CREATEDIBSECTION|LR_DEFAULTSIZE|LR_LOADFROMFILE);

m_ (hBitmap);

CDC dcImage;

if(!CompatibleDC (pDC))

return;

BITMAP bm;

m_map (&bm);

Object (&m_bitmap);

pDC->BitBlt (0,0,h ,ht ,&dcImage,0,0,SRCCOPY);

}

}

接下来就是调试工作。经调试发现,该应用程序还有不完善了地方。当单击“保存”子

菜单项,弹出“另存为”对话框,但当单击对话框中“取消”按钮时,程序会出错。