BMP文件的读取与显示Word下载.docx
《BMP文件的读取与显示Word下载.docx》由会员分享,可在线阅读,更多相关《BMP文件的读取与显示Word下载.docx(15页珍藏版)》请在冰豆网上搜索。
在WindowsXP系统中有许多图像文件,为了查看图像文件的内容,WindowsXP系统提供了Windows图片和传真查看器(PictureFaxViewer)。
此外,Windows系统还提供了画图(Paint),实现简单图像的编辑。
计算的图像可以有多种存储格式,通常以其文件名后缀进行区分,常见的图像格式有BMP、JPG、GIF、PNG、WMF和PCX等。
1.2设计目的
这次课程设计是要完成一个BMP图像处理软件,其中包括对文件的读取保存、修改和显示。
读取文件中的图片:
可以对文件中的图片进行读取,在修改后也可以保存修改后的文件,并在文档中显示图片。
1.3设计意义
对编程知识有了更进一步的了解,使我更加熟练掌握了编程技巧,明白了一些函数是如何定义调用的,知道了一些头文件的功能,还有一些嵌套功能,怎么样调试及运行程序,这次编程使我收益匪浅,能运用了MFC来编程,也对BMP文件的读入及打开有了更深的了解。
1.4开发工具简介
VisualC++6.0,简称VC或者VC6.0,是微软推出的一款C++编译器,将“高级语言”翻译为“机器语言(低级语言)”的程序。
VisualC++是一个功能强大的可视化软件开发工具。
自1993年Microsoft公司推出VisualC++1.0后,随着其新版本的不断问世,VisualC++已成为专业程序员进行软件开发的首选工具。
虽然微软公司推出了VisualC++.NET(VisualC++7.0),但它的应用的很大的局限性,只适用于Windows2000、WindowsXP和WindowsNT4.0。
所以实际中,更多的是以VisualC++6.0为平台。
VisualC++6.0它不仅是一个C++编译器,而且是一个基于Windows操作系统的可视化集成开发环境(integrateddevelopmentenvironment,IDE)。
VisualC++6.0由许多组件组成,包括编辑器、调试器以及程序向导AppWizard、类向导ClassWizard等开发工具。
这些组件通过一个名为DeveloperStudio的组件集成为和谐的开发环境。
Microsoft的主力软件产品。
2需求分析
分析系统要处理的信息,对信息要求哪些处理功能
2.1系统处理信息分析
BMP文件的读取与显示系统需要处理对文件的格式的辨别、对文件的组成和结构进行分析等方面,具体包括对以下五个方面进行处理:
一、BMP文件组成
BMP文件由文件头、位图信息头、颜色信息和图形数据四部分组成,如表2-1所示。
文件头BITMAPFILEHEADER
位图信息
BITMAPINFO
位图信息头
BITMAPINFOHEADER
颜色信息表
位图像素数据
表2-1BMP文件结构
二、BMP文件头(14字节)
BMP文件头数据结构含有BMP文件的类型、文件大小和位图起始位置等信息。
其结构定义如下:
typedefstructtagBITMAPFILEHEADER
{WORDbfType;
//位图文件的类型,必须为BM(0-1字节)
DWORDbfSize;
//位图文件的大小,以字节为单位(2-5字节)
WORDbfReserved1;
//位图文件保留字,必须为0(6-7字节)
WORDbfReserved2;
//位图文件保留字,必须为0(8-9字节)
DWORDbfOffBits;
//位图数据的起始位置,以相对于位图(10-13字节)
//文件头的偏移量表示,以字节为单位
}BITMAPFILEHEADER;
三、位图信息头(40字节)
BMP位图信息头数据用于说明位图的尺寸等信息。
typedefstructtagBITMAPINFOHEADER
{ DWORDbiSize;
//本结构所占用字节数(14-17字节)
LONGbiWidth;
//位图的宽度,以像素为单位(18-21字节)
LONGbiHeight;
//位图的高度,以像素为单位(22-25字节)
WORDbiPlanes;
//目标设备的级别,必须为1(26-27字节)
WORDbiBitCount;
//每个像素所需的位数,必须是1(双色),(28-29字节)
//4(16色),8(256色)或24(真彩色)之一
DWORDbiCompression;
//位图压缩类型,必须是0(不压缩),(30-33字节)
//1(BI_RLE8压缩类型)或2(BI_RLE4压缩类型)之一
DWORDbiSizeImage;
//位图的大小,以字节为单位(34-37字节)
LONGbiXPelsPerMeter;
//位图水平分辨率,每米像素数(38-41字节)
LONGbiYPelsPerMeter;
//位图垂直分辨率,每米像素数(42-45字节)
DWORDbiClrUsed;
//位图实际使用的颜色表中的颜色数(46-49字节)
DWORDbiClrImportant;
//位图显示过程中重要的颜色数(50-53字节)
}BITMAPINFOHEADER;
四、颜色表
颜色表用于说明位图中的颜色,它有若干个表项,每一个表项是一个RGBQUAD类型的结构,定义一种颜色。
RGBQUAD结构的定义如下:
typedefstructtagRGBQUAD
{BYTErgbBlue;
//蓝色的亮度(值范围为0-255)
BYTErgbGreen;
//绿色的亮度(值范围为0-255)
BYTErgbRed;
//红色的亮度(值范围为0-255)
BYTErgbReserved;
//保留,必须为0
}RGBQUAD;
颜色表中RGBQUAD结构数据的个数有biBitCount来确定:
当biBitCount=1,4,8时,分别有2,16,256个表项;
当biBitCount=24时,没有颜色表项。
位图信息头和颜色表组成位图信息,BITMAPINFO结构定义如下:
typedefstructtagBITMAPINFO
{BITMAPINFOHEADERbmiHeader;
//位图信息头
RGBQUADbmiColors[1];
//颜色表
}BITMAPINFO;
五、位图数据
位图数据记录了位图的每一个像素值,记录顺序是在扫描行内是从左到右,扫描行之间是从下到上。
位图的一个像素值所占的字节数:
当biBitCount=1时,8个像素占1个字节;
当biBitCount=4时,2个像素占1个字节;
当biBitCount=8时,1个像素占1个字节;
当biBitCount=24时,1个像素占3个字节;
Windows规定一个扫描行所占的字节数必须是4的倍数(即以long为单位),不足的以0填充,biSizeImage=((((bi.biWidth*bi.biBitCount)+31)&
~31)/8)*bi.biHeight;
2.2处理功能分析
系统的处理功能主要包括在指定的设备环境上显示指定的位图、从指定的位图文件中读取位图信息及数据并显示在客户区上、将客户区显示的图像保存到指定的位图文件中、保存位图文件等。
3总体设计
3.1系统功能模块层次图
BMP文件的读取与显示系统功能模块层次图,如图3-1所示。
图3-1系统功能模块层次图
3.2功能简介
利用本软件主要实现对BMP文件的读取与显示功能,其中包括从任意路径选择并打开一个BMP位图文件,并实现对该BMP位图文件的显示和保存功能,关闭此文件后可以实现对其他BMP文件的打开、显示和保存功能。
3.3主要功能的流程图
BMP文件的读取与显示系统主要功能流程图如图3-2所示。
图3-2系统主要功能流程图
4详细设计与实现
4.1建立单文档工程
用VC++向导建立一个单文档工程,名称为Openimagefile,具体创建步骤如下:
1、选择File->
New菜单命令,打开“新建”对话框。
2、在“工程”选项卡中,选择MFCAppWizard(exe)工程类型,并设置工程名为Openimagefile,单击OK按钮,打开MFC应用程序向导,如图4-1所示。
图4-1建立Openimagefile工程
3、选择Singledocument,单击Finish按钮,再单击OK按钮,向导将自动创建单文档用户界面应用程序框架,如图4-2所示。
图4-2选择Singledocument
4.2添加成员函数和成员变量
1、在视图类Openimagefile添加两个成员变量,代码如下:
classOpenimagefile:
publicCView
{BITMAPINFO*m_pBMInfo;
//位图信息结构指针
BYTE*m_pBMData;
//位图数据指针
}
2、在视图类Openimagefile的构造函数中添加初始化代码,并在析构函数中添加清理代码,如下:
Openimagefile:
:
Openimagefile()
{m_pBMInfo=NULL;
m_pBMData=NULL;
~Openimagefile()
{if(m_pBMInfo!
=NULL)
deletem_pBMInfo;
if(m_pBMData!
deletem_pBMData;
3、为视图类Openimagefile添加成员函数BMShow,用来在指定的设备环境上显示指定的位图,该函数代码如下:
voidOpenimagefile:
BMShow(CDC*pDC,intnX,intnY,intnWidth,intnHeight)
{pDC->
SetStretchBltMode(COLORONCOLOR);
//设置缩放拷贝模式
StretchDIBits(pDC->
GetSafeHdc(),//设备环境句柄
nX,//目标(客户区)矩形区域左上角的X坐标
nY,//目标(客户区)矩形区域左上角的Y坐标
nWidth,//目标(客户区)矩形区域的宽度
nHeight,//目标(客户区)矩形区域的高度
0,//源(位图)矩形区域左上角的X坐标
0,//源(位图)矩形区域左上角的Y坐标
m_pBMInfo->
bmiHeader.biWidth,//源(位图)矩形区域的宽度
bmiHeader.biHeight,//源(位图)矩形区域的高度
m_pBMData,//位图像素数据地址
m_pBMInfo,//位图信息结构地址
DIB_RGB_COLORS,//使用标志
SRCCOPY);
//光栅操作码,指定像素结合方式
4、在视图类Openimagefile中添加成员函数BMRead,用来从指定的位图文件中读取位图信息及数据,并显示在客户区上,该函数代码如下:
BMRead(LPCTSTRlpszFileName)
{CFilefile;
CStringstr;
BITMAPINFO*pBMI=NULL;
BYTE*pData=NULL;
//位图像素数据指针
file.Open(lpszFileName,CFile:
modeRead|CFile:
typeBinary);
//打开位图文件
BITMAPFILEHEADERbmfh;
//位图文件头结构对象
file.Read(&
bmfh,sizeof(BITMAPFILEHEADER));
//读取位图文件头信息
if(bmfh.bfType!
=0x4d42)//判断是否是位图
{str.Format("
文件%s不是一个BMP文件!
"
lpszFileName);
AfxMessageBox(str);
return;
}
BITMAPINFOHEADERbmih;
//位图信息头结构对象
bmih,sizeof(BITMAPINFOHEADER));
//读取位图信息头
if(bmih.biBitCount<
=16)//判断是否是真彩色位图
文件%s不是真彩色位图!
pBMI=(BITMAPINFO*)newchar[sizeof(BITMAPINFOHEADER)];
//分配内存
memcpy(pBMI,&
//拷贝内存
DWORDdwSize=bmfh.bfSize-bmfh.bfOffBits;
//图像数据的字节数
pData=newBYTE[dwSize];
//为图像数据分配内存
file.Read(pData,dwSize);
//读取位图图像数据
file.Close();
if(m_pBMInfo!
m_pBMInfo=pBMI;
m_pBMData=pData;
5、在视图类Openimagefile中添加成员函数BMWrite,用来将客户区显示的图像保存到指定的位图文件中,该函数代码如下:
BMWrite(LPCTSTRlpszFileName)
{CRectrect;
GetClientRect(rect);
intnWidth=rect.Width();
//客户区宽度
intnHeight=rect.Height();
//客户区高度
intnBitCount=32;
//32位位图
//设置位图信息结构
BITMAPINFO*pBMInfo=newBITMAPINFO;
pBMInfo->
bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
bmiHeader.biWidth=nWidth;
//位图宽度
bmiHeader.biHeight=nHeight;
//位图高度
bmiHeader.biPlanes=1;
bmiHeader.biBitCount=nBitCount;
//位图位数
bmiHeader.biCompression=BI_RGB;
//未压缩格式
bmiHeader.biSizeImage=0;
bmiHeader.biXPelsPerMeter=0;
bmiHeader.biYPelsPerMeter=0;
bmiHeader.biClrUsed=0;
bmiHeader.biClrImportant=0;
//创建位图数据
HDChDC,hMemDC;
HBITMAPhBitMap;
CBitmap*pBitMap;
CDC*pMemDC;
BYTE*pBMData;
//位图数据指针
hDC=GetDC()->
GetSafeHdc();
//获取当前窗口DC句柄
hMemDC=CreateCompatibleDC(hDC);
//创建兼容当前窗口的内存DC,并返回内存DC句柄
//创建设备无关位图(DIB),并指定位图数据指针
hBitMap=CreateDIBSection(hMemDC,pBMInfo,DIB_RGB_COLORS,(void**)&
pBMData,NULL,0);
pBitMap=newCBitmap;
pBitMap->
Attach(hBitMap);
//创建位图指针
pMemDC=newCDC;
pMemDC->
Attach(hMemDC);
//创建内存DC指针
SelectObject(pBitMap);
SetBkMode(TRANSPARENT);
BMShow(pMemDC,0,0,nWidth,nHeight);
//在内存DC上显示当前窗口上的位图
//设置位图文件头结构
bmfh.bfType=0x4d42;
bmfh.bfOffBits=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER);
bmfh.bfSize=bmfh.bfOffBits+(nWidth*nHeight)*nBitCount/8;
bmfh.bfReserved1=0;
bmfh.bfReserved2=0;
DWORDdwSize=(nWidth*nHeight)*nBitCount/8;
//位图图像数据大小
CFilefile;
if(file.Open(lpszFileName,CFile:
modeWrite|CFile:
modeCreate))
{file.Write(&
file.Write(&
(pBMInfo->
bmiHeader),sizeof(BITMAPINFOHEADER));
file.Write(pBMData,dwSize);
file.Close();
}
DeleteDC();
deletepMemDC;
deletepBitMap;
deletepBMInfo;
6、按Ctrl+W组合键,选择MFC类向导的“消息映射”选项卡,如图4-1所示。
图4-1“消息映射”选项卡
4.3重新定义OnFileOpen函数
在ObjectIDs列表框中选择ID_FILE_OPEN,在Messages(消息)列表框选择COMMAND(命令),单击AddFunction(添加函数)按钮,将在Openimagefile类中添加成员函数OnFileOpen,并添加如下代码:
OnFileSave()
{if((m_pBMInfo==NULL)||(m_pBMData==NULL))
CFileDialogdlg(FALSE,NULL,NULL,
OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT,
"
BMPFiles(*.bmp)|*.bmp||"
NULL);
if(dlg.DoModal()==IDOK)
{CStringfilename=dlg.GetPathName()+"
.bmp"
;
BMWrite(filename);
4.4修改OnDraw函数
添加位图显示功能,在Openimagefile类成员函数OnDraw函数中添加代码如下:
OnDraw(CDC*pDC)
{CE1503Doc*pDoc=GetDocument();
ASSERT_VALID(pDoc);
if(!
m_bFile)//如果没有选择位图文件,返回
CDC*pMemDC=newCDC;
//内存显示DC
CreateCompatibleDC(pDC);
//创建与当前DC兼容的DC
//从位图文件中载入位图数据,并返回位图的句柄
HBITMAPhBitmap=(HBITMAP)LoadImage(AfxGetInstanceHandle(),
m_strFileName,IMAGE_BITMAP,0,0,
LR_LOADFROMFILE|LR_CREATEDIBSECTION);
CBitmapbitmap;
//CBitmap类对象
bitmap.Attach(hBitmap);
//绑定位图数据
BITMAPbm;
bitmap.GetBitmap(&
bm);
//获取位图信息
SelectObject(&
bitmap);
CRectrect;
GetClientRect(re