分别用MFCOpencv库FreeImage库显示同一张BMP图像.docx
- 文档编号:7883253
- 上传时间:2023-01-26
- 格式:DOCX
- 页数:13
- 大小:1.22MB
分别用MFCOpencv库FreeImage库显示同一张BMP图像.docx
《分别用MFCOpencv库FreeImage库显示同一张BMP图像.docx》由会员分享,可在线阅读,更多相关《分别用MFCOpencv库FreeImage库显示同一张BMP图像.docx(13页珍藏版)》请在冰豆网上搜索。
分别用MFCOpencv库FreeImage库显示同一张BMP图像
用VS2008平台设计一个简单的MFC程序,分别用MFC、Opencv库、FreeImage库三种不同的方法来显示同一张BMP图像。
1MFC显示BMP图像
(1)MFC插入单张图片
1、创建MFC打开VS2008软件,创建一个MFC对话框应用程序(Dialog-basedApplication),在名称栏输入创建项目的名称,点击“确定”。
如下图所示:
在出现的“MFC应用程序向导”对话框内,选择“基于对话框”,并取消“使用Unicode库(N)”其他选项不做修改,单击“下一步”,如下图所示:
一直点击“下一步”到“生成的类”对话框,选择基类为“CDialog”单击完成即可创建一个MFC对话框。
如下图所示:
2、添加控件并导入图片生成如下图所示的初始的GUI界面,在工具箱中单击“PictureControl”,将鼠标移动到GUI界面内,这样就在此界面添加了一个Picture控件。
接着,在“资源视图”下,右击选择“添加资源”,在“添加资源”对话框的“资源类型”下选择“Bitmap”,再单击“导入(M)”,打开BMP图片。
如下图所示:
3、设置控件最后在Picture控件的“属性”窗口中将“Type”选择为“Bitmap”类型,将“Image”和“ID”都选择为导入BMP图片的ID,比如IDB_BITMAP1。
如下图所示:
4、运行程序最后保存并运行一下程序,成功后将会得到一个含有导入的BMP图像的窗口,完成显示BMP图像的功能,如下图所示:
(2)MFC插入多张图片
1、添加控件并导入多张图片当需要插入多张图片时,导入图片的方法同上,然后为每一张图片设置它们的“ID”,例如:
IDB_BITMAP1、IDB_BITMAP2、IDB_BITMAP3、IDB_BITMAP4。
在GUI界面中添加一个选择按钮,选择工具箱中的“Combobox”,如下图所示:
通过属性窗口修改它的“ID”为“IDC_CHOICE”,“Type”选择“DropList”,“OwnerDraw”选择“No”,在“数据”项中输入每幅图片的名字,每个名字间用分号隔开。
2、初始化函数在“类视图”下,为类“C(工程名)Dlg.h”增加一些私有成员private:
CBitmapBmp1,Bmp2,Bmp3,Bmp4,;从成员变量对话框为“IDC_CHOICE”和“IDC_PICTURE”增加控制变量分别取名为“m_Choice”,“m_Picture”。
打开“(工程名)Dlg.cpp”源代码文件里找到OnInitDialog()函数体并将其改成:
BOOLCtext9Dlg:
:
OnInitDialog()
{
CDialog:
:
OnInitDialog();
m_Choice.SetCurSel(0);
Bmp1.LoadBitmap(IDB_BITMAP1);
Bmp2.LoadBitmap(IDB_BITMAP2);
Bmp3.LoadBitmap(IDB_BITMAP3);
Bmp4.LoadBitmap(IDB_BITMAP4);
returnTRUE;
}
3、编写控件事件初始化代码在“Combobox”控件的“属性”菜单栏中的“控件事件”找到成员函数OnCbnSelchangeChoice(),并为其添加额外的初始化代码:
voidCtext9Dlg:
:
OnCbnSelchangeChoice()
{
intCurSel=m_Choice.GetCurSel();
switch(CurSel)
{
case0:
m_Picture.SetBitmap(Bmp1);
break;
case1:
m_Picture.SetBitmap(Bmp2);
break;
case2:
m_Picture.SetBitmap(Bmp3);
break;
case3:
m_Picture.SetBitmap(Bmp4);
break;
}
}
4、运行生成解决方案并运行成功后,会得到一个窗口,通过按钮的下拉菜单可以选择显示不同的图片。
2用Opencv库显示BMP位图
1、创建MFC首先创建一个新的MFC对话框应用程序,在初始的GUI界面添加一个Button和一个Picture控件,在Button控件的属性菜单栏中修改标题“Caption”为“读图”,即此控件的功能是读取图片。
将Picture控件的ID号设置为IDC_ShowImg,这个ID号在后面的图像显示函数中会用到。
2、设置程序运行环境在项目属性中加载lib文件:
菜单项目->属性->配置属性->链接器–>输入->附加依赖项中加入cxcore.libcv.libhighgui.lib。
然后在text.h(工程名为text)的#include"resource.h" 下加入如下代码:
#include"cv.h"
#include"highgui.h"
#defineIMAGE_WIDTH256
#defineIMAGE_HEIGHT256
#defineIMAGE_CHANNELS3
3、添加控制变量在类视图面板上右击CtextcDlg,选择添加–>添加变量,添加一个IplImage*类型的变量TheImage;
再点击CtextcDlg,在下面窗口的列表中双击OnInitDialog,在“//TODO:
Addextrainitializationhere”下面添加TheImage的初始化代码:
CvSizeImgSize;
ImgSize.height=IMAGE_HEIGHT;
ImgSize.width=IMAGE_WIDTH;
TheImage=cvCreateImage(ImgSize,IPL_DEPTH_8U,IMAGE_CHANNELS);
然后双击OnPaint,在if(IsIconic())…的else里添加以下代码,用来重绘窗口:
CDialog:
:
OnPaint(); //重绘对话框
CDialog:
:
UpdateWindow(); //更新windows窗口,如果无这步调用,图片显示还会出现问题
ShowImage(TheImage,IDC_ShowImg); //重绘图片函数
接着在CmymfcApp下面的成员列表中双击InitInstance,在两个“//TODO:
Placecodeheretohandlewhenthedialogis…”下面添加:
cvReleaseImage(&dlg.TheImage);即按下“OK”或“Cancel”时,释放TheImage占用的内存。
4、写读取图片的功能函数回到text的GUI编辑界面中,右击按钮“读图”,选择“添加事件处理程序”,建立按钮点击的消息响应程序:
句柄名设置为OnBnClickedReadimg,主要的响应操作包括弹出对话框选择图片文件、读入图片文件、对图片统一缩放至256*256的大小、显示图像,代码如下:
CFileDialogdlg(
TRUE,_T("*.bmp"),NULL,
OFN_FILEMUSTEXIST|OFN_PATHMUSTEXIST|OFN_HIDEREADONLY,
_T("imagefiles(*.bmp;*.jpg)|*.bmp;*.jpg|AllFiles(*.*)|*.*||"),NULL
); //选项图片的约定
dlg.m_ofn.lpstrTitle=_T("OpenImage");//打开文件对话框的标题名
if(dlg.DoModal()!
=IDOK) //判断是否获得图片
return;
CStringmPath=dlg.GetPathName(); //获取图片路径
IplImage*ipl=cvLoadImage(mPath,1);//读取图片、缓存到一个局部变量ipl中
if(!
ipl) //判断是否成功载入图片
return;
if(TheImage) //对上一幅显示的图片数据清零
cvZero(TheImage);
ResizeImage(ipl); //对读入的图片进行缩放,使其宽或高最大值者刚好等于256,再复制到TheImage中
ShowImage(TheImage,IDC_ShowImg); //调用显示图片函数
cvReleaseImage(&ipl); //释放ipl占用的内存
在“类视图”面板右击CtextDlg,选择添加–>添加函数,创建两个函数:
voidShowImage(IplImage*img,UINTID)和voidResizeImage(IplImage*img),此两个函数分别实现图像的读入和显示功能,以下是这两个函数的实现代码:
voidCmymfcDlg:
:
ResizeImage(IplImage*img)
{
intw=img->width;//读取图片的宽和高
inth=img->height;//找出宽和高中的较大值者
intmax=(w>h)?
w:
h;//计算将图片缩放到TheImage区域所需的比例因子
floatscale=(float)((float)max/256.0f);//缩放后图片的宽和高
intnw=(int)(w/scale);
intnh=(int)(h/scale);
//为了将缩放后的图片存入TheImage的正中部位,需计算图片在TheImage左上角的期望坐标值
inttlx=(nw>nh)?
0:
(int)(256-nw)/2;
inttly=(nw>nh)?
(int)(256-nh)/2:
0;
//设置TheImage的ROI区域,用来存入图片img
cvSetImageROI(TheImage,cvRect(tlx,tly,nw,nh));
//对图片img进行缩放,并存入到TheImage中
cvResize(img,TheImage);
//重置TheImage的ROI准备读入下一幅图片
cvResetImageROI(TheImage);
}
voidCmymfcDlg:
:
ShowImage(IplImage*img,UINTID) //ID是PictureControl控件的ID号
{
CDC*pDC=GetDlgItem(ID)->GetDC(); //获得显示控件的DC
HDChDC=pDC->GetSafeHdc(); //获取HDC(设备句柄)来进行绘图操作
CRectrect;
GetDlgItem(ID)->GetClientRect(&rect);
intrw=rect.right-rect.left; //求出图片控件的宽和高
intrh=rect.bottom-rect.top;
intiw=img->width; //读取图片的宽和高
intih=img->height;
inttx=(int)(rw-iw)/2; //使图片的显示位置正好在控件的正中
intty=(int)(rh-ih)/2;
SetRect(rect,tx,ty,tx+iw,ty+ih);
CvvImagecimg;
cimg.CopyOf(img); //复制图片
cimg.DrawToHDC(hDC,&rect); //将图片绘制到显示控件的指定区域内
ReleaseDC(pDC);
}
分析程序功能实现过程:
先利用函数GetPathName来获得BMP位图的文件路径,再利用函数cvLoadImage来获得位图的信息,并用函数cvNamedWindow创建窗口,最后用函数cvShowImage显示位图。
在执行完以上操作之后,调试程序,生成如下对话框:
单击按钮
,添加BMP位图,出现如下对话框,成功地显示了一张BMP位图。
3用FreeImage库显示BMP位图
用VS2008建立一个类型为单文档的MFC应用程序,将freeimage.lib添加到“项目
属性
配置属性
连接器
输入
附加依赖项”中;将FreeImage中的Dist文件夹添加到“工具
选项
项目和解决方案
VC++目录”中的“包含文件”与“库文件”中;并将#include"freeimage.h"添加到头文件stdafx.h中;
1、Doc头文件设置
(1)在“xxDoc.h”的类声明中添加下列代码:
public:
FIBITMAP*m_handleFI;
virtualBOOLOnOpenDocument(LPCTSTRlpszPathName);
(2)在“xxDoc.cpp”文件中将CxxDoc:
:
CxxDoc()改为CxxDoc:
:
CxxDoc():
m_handleFI(NULL),即增加一个类型为FIBITMAP*的变量在类
(3)在“xxDoc.cpp”文件程序段的末尾处添加
BOOLCxxDoc:
:
OnOpenDocument(LPCTSTRlpszPathName)
{
FREE_IMAGE_FORMATfif;
DeleteContents();
fif=FreeImage_GetFIFFromFilename(lpszPathName);
if(fif!
=FIF_UNKNOWN)
m_handleFI=FreeImage_Load(fif,lpszPathName);
return(m_handleFI!
=NULL);
returnTRUE;
}
该函数的功能为:
先利用函数FreeImage_GetFIFFromFilename来获得BMP位图的文件路径,再利用函数FreeImage_Load来读取位图的信息。
)
2、VIEW头文件设置
在“xxView.cpp”里找到voidCxxView:
:
OnDraw(CDC*pDC)
(将(CDC*/*pDC*/)改为(CDC*pDC)即可)这个函数中增加以下代码:
pDC->SetMapMode(MM_HIMETRIC);
if(!
pDoc->m_handleFI)
return;
doubledpiX=FreeImage_GetDotsPerMeterX(pDoc->m_handleFI),
dpiY=FreeImage_GetDotsPerMeterY(pDoc->m_handleFI),
width=FreeImage_GetWidth(pDoc->m_handleFI),
height=FreeImage_GetHeight(pDoc->m_handleFI),
sizeX,//1/100mm==HIMETRIC
sizeY;
BYTE*pData=FreeImage_GetBits(pDoc->m_handleFI);
if(dpiX==0.0)dpiX=72.0*100.0/2.54;
if(dpiY==0.0)
dpiY=72.0*100.0/2.54;
sizeX=1*100.0*1000.0*width/dpiX;
sizeY=1*100.0*1000.0*height/dpiY;//stretched
:
:
StretchDIBits(pDC->m_hDC,1,-1,(int)(sizeX+0.5),-(int)(sizeY+0.5),0,0,(int)(width+0.5),(int)(height+0.5),pData,FreeImage_GetInfo(pDoc->m_handleFI),DIB_RGB_COLORS,SRCCOPY);
该函数的功能是:
设定位图的高度、宽度以及读取位图像素值信息。
3、调试运行程序
在执行完以上操作之后,调试程序,生成如下对话框:
点击文件
打开,插入一张BMP位图,出现如下对话框:
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 分别 MFCOpencv FreeImage 显示 同一 BMP 图像