当前位置:C++技术网 > 资讯 > 学习心得之八------实现从磁盘读入图片文件

学习心得之八------实现从磁盘读入图片文件

更新时间:2015-09-17 22:30:01浏览次数:1+次

                                        学习心得之八------实现从磁盘读入图片文

    之前写《学习心得之七---程序启动画面的设计》时心思来潮想写个像word那样类似的启动画面,后来发现,有点难,最起码从电脑磁盘读取图片文件就实现不了,捣鼓了一晚上,终于有眉目了,写篇心得咯。

    首先,我们创建一个基于对话框的工程LoadBmp,然后我们在ID号为IDD_LOADBMP_DIALOG的对话框中删除原有控件,加三个控件----静态控件,编辑框控件,按钮控件:

我们将静态控件的Caption改为“请从磁盘加载位图资源文件”,修改编辑框,按钮控件的ID号:

IDC_FILENAME;   

IDC_BROWSE;

并为按钮控件关联一个成员变量m_filename,如图:

 

我们在编辑框控件上右击鼠标,选择classwizard,按照如图步骤添加成员变量,我们在第四步时,不选择value,而是control。完成后,我们在CLoadBmpDlg的头文件中,添加一个成员变量:

class CLoadBmpDlg : public CDialog
{
// Construction
public:
	CLoadBmpDlg(CWnd* pParent = NULL);	// standard constructor
	HBITMAP m_hBmp;
//省略代码
}

并在构造函数中将其设为NULL;

CLoadBmpDlg::CLoadBmpDlg(CWnd* pParent /*=NULL*/)
	: CDialog(CLoadBmpDlg::IDD, pParent)
{
	//{{AFX_DATA_INIT(CLoadBmpDlg)
	
	//}}AFX_DATA_INIT
	// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
	m_hBmp=NULL;
}

接下来,我们处理"..."按钮单击消息。首先创建类向导,生成消息函数:

void CLoadBmpDlg::OnBrowse() 
{
	// TODO: Add your control notification handler code here
	CFileDialog filedlg(TRUE);
	if(filedlg.DoModal()==IDOK)
	{
		CString szfile=filedlg.GetPathName();
		m_FileName.SetWindowText(szfile);
		if (m_hBmp != NULL)
		{
			DeleteObject(m_hBmp);
			m_hBmp = NULL;
		}
		m_hBmp = (HBITMAP)LoadImage(NULL, szfile,IMAGE_BITMAP,
					0, 0, LR_LOADFROMFILE);	
		OnPaint();
	}
}

我们要从磁盘读取文件,当然少不了CFileDialog类了,它与《学习心得之五,MFC编程中两种文件对话框的创建》里的创建步骤一样,我们就不细分过滤文件了,接下来我们得到文件的路径使用函数Getpathname(),并将选择的磁盘文件的路径写到编辑框中,调用函数setwindowtext();我们判断下是否已经选择了图片文件,因此加个if语句,这是个好习惯哦!接着我们使用函数LoadImage()加载图片:

 

HANDLE LoadImage(

HINSTANCE hinst,

LPCTSTR lpszName,

UINT uType,

int cxDesired,

int cyDesired,

UINT fuLoad

);

 

第一个参数,可以为NULL,就是图像的实例句柄;

第二个参数,如果从磁盘加载的,就是文件路径咯,否则就是图像的资源名称

第三个参数,加载的类型,IMAGE_BITMAP:装载位图;IMAGE_CURSOR:装载光标;IMAGE_ICON:装载图标。

第四个参数,表示图表或鼠标的宽度,如果是位图那就是0;

第五个参数,同上,只不过表示的是高度,

最后表示加载类型,如果是LR_LOADFROMFILE,表示从磁盘加载文件。

返回值是加载的图像句柄,但我们需要的是位图句柄,因此强制类型转化咯。

最后我们调用OnPaint(),使用WM_PAINT消息绘图。

 

void CLoadBmpDlg::OnPaint() 
{
	if (IsIconic())
	{
	//省略代码		}
	else
	{
               ///加上的代码:		
		if(m_hBmp!=NULL)
		{
			CDC *pDC=GetDC();
			CBitmap bmp;
			bmp.Attach(m_hBmp);
			CDC memDC;
			memDC.CreateCompatibleDC(pDC);
			memDC.SelectObject(&bmp);
			BITMAP BitInfo;
			bmp.GetBitmap(&BitInfo);
	                          int x=BitInfo.bmweight;
		             int y=BitInfo.bmHeight;
		             pDC->BitBlt(10,50,x,y,&memDC,0,0,SRCCOPY);            
                                       bmp.Detach();
                                       memDC.DeleteDC();
                            }
                }
}

 

我们创建设备描述表对象,并返回一个DC指针,然后创建一个位图类,并将我们之前LoadImage返回的位图句柄附属到我们的CBitmap上,我们定义一个设备描述表对象,并用它创建一个兼容DC,我们看看函数CreateCompatibleDC:

 

HDC CreateCompatibleDC(HDC hdc);

 

接下来我们选入我们的位图对象bmp,我们定义一个BITMAP的对象,接受位图bmp的信息,并用变量x,y接受位图的高,宽,最后就是函数BitBlt();该函数用于从原设备中复制位图到目标设备。具体参数我们可以查MSDN;点击《VS2015离线MSDN安装包下载地址和各版本在线MSDN入口地址》,我们就能查到了。我这就不详述了。看看是想实现结果吧

如果我们觉得图片太小了(原谅我是个鸟橱,个人兴趣),将函数BitBlt的调用改为函数StrechBlt的调用就行了,这个函数实现延伸图片,铺满客户区,只不过图片分辨率就会降低。