我们先从简单的开始吧.先分一个类:(一) 非动态显示图片(即图片先通过资源管理器载入,有一个固定ID)(二) 动态载入图片(即只需要在程序中指定图片的路径即可载入)为方便说明,我们已经建好一个基于对话框的工程,名为Ttest.对话框类为CTestDlg(一) 非动态载入图片.方法1.先从最简单的开始,用picture 控件来实现. 步骤:先在资源里Import一张图片,ID为IDB_BITMAP2 然后在对话框上添加一个picture控件,右键点击打开属性,将type下拉框选择BITMAP,紧跟着下面就出现一个Image下拉框,拉开就会看到所有已经载入好的图片,选择你要的图片.运行程序即可看到.方法2.通过背景图同样如上,先载入一张图片,ID为IDB_BITMAP2 TestDlg.h中CBrush m_brBk;//在public中定义TestDlg.cpp中在初始化函数OnInitDialog()中加入:BOOL CTestDlg::OnInitDialog(){CDialog::OnInitDialog();CBitmap bmp;bmp.LoadBitmap(IDB_BITMAP2);m_brBk.CreatePatternBrush(&bmp);bmp.DeleteObject();...return TRUE; // return TRUE unless you set the focus to a control}在打开类向导,找到WM_CTLCOLOR消息,重载得对应函数OnCtlColor(),添加如下:HBRUSH CTestDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor){HBRUSH hbr =CDialog::OnCtlColor(pDC, pWnd, nCtlColor);if (pWnd == this){return m_brBk;}return hbr;}(二) 动态载入图片.方法3 图像控件(本例用KoDak 图像编辑控件)1. 首先应该保证系统中有这个控件。
注意,它不能单独使用,必须和其他几个控件(特别是Imgcmn.dll)一同使用。
如果没有,从别的机器上copy过来即可。
这几个文件是Imgadmin.ocx,Imgcmn.dll,Imgedit.ocx,Imgscan.ocx,Imgshl.dll,Imgthumb.ocx,Imgutil.dll,把它们copy到windows\system目录下,然后用regsvr32.exe将它们分别注册。
2. 打开工程,进入资源管理器,在对话框上单击右键,单击Insert Activex control… 选择Kodak图象编辑控件,大小任意。
3. 在对话框上选中该控件,为其添加变量:m_ctrlPicture。
4. 在BOOL CTestDlg::OnInitDialog()添加如下: BOOL CTestDlg::OnInitDialog(){CDialog::OnInitDialog();m_ctrlPicture.SetImage("aa.jpg"); //保证图像在工程目录下,也可以写绝对路径m_ctrlPicture.Display();.;;return TRUE; // return TRUE unless you set the focus to a control// EXCEPTION: OCX Property Pages should return FALSE}编译运行就OK了,此种方法的好处就是可能针对多种图像格式.方法4 通过CBitmap,HBITMAP,直接用OnPaint()绘制首先在CTestDlg类中声明一个变量: CBitmap m_bmp;然后我们在对话框中加入一个picture 标签,名为IDC_STATIC1int cx=bminfo.biWidth; //得到图像宽度int cy=bminfo.biHeight; //得到图像高度/////////////////// /////////////////////////////////////////////得到了图像的宽度和高度后,我们就可以对图像大小进行适应,即调整控件的大小,让它正好显示一张图片/////////////////////////// CRect rect;GetDlgItem(IDC_STATIC1)->GetWindowRect(&rect);ScreenToClient(&rect);GetDlgItem(IDC_STATIC1)->MoveWindow(rect.left,rect.top,cx,c y,true);//调整大小return TRUE; // return TRUE unless you set the focus to a control// EXCEPTION: OCX Property Pages should return FALSE}图片加载成功了,标签大小也适应了,下面就是绘制绘制图像了,打开类向导,重载WM_PAINT消息void CDisplayPic::OnPaint(){//////////////以下三种情况任选一种会是不同效果(只能一种存在)/////////// //CPaintDC dc(this); //若用此句,得到的是对话框的DC,图片将被绘制在对话框上.CPaintDC dc(GetDlgItem(IDC_STATIC1)); //用此句,得到picture 控件的DC,图像将被绘制在控件上// CDC dc;// dc.m_hDC=::GetDC(NULL); //若用此两句,得到的是屏幕的DC,图片将被绘制在屏幕上/////////////////////////////////////////////////////// CRect rcclient;GetDlgItem(IDC_STATIC1)->GetClientRect(&rcclient);CDC memdc;memdc.CreateCompatibleDC(&dc);CBitmap bitmap;bitmap.CreateCompatibleBitmap(&dc, rcclient.Width(), rcclient.Height());memdc.SelectObject( &bitmap );CWnd::DefWindowProc(WM_PAINT,(WPARAM)memdc.m_hDC , 0);CDC maskdc;maskdc.CreateCompatibleDC(&dc);CBitmap maskbitmap;maskbitmap.CreateBitmap(rcclient.Width(), rcclient.Height(), 1, 1, NULL);maskdc.SelectObject( &maskbitmap );maskdc.BitBlt( 0, 0, rcclient.Width(), rcclient.Height(), &memdc, rcclient.left, rcclient.top, SRCCOPY);CBrush brush;brush.CreatePatternBrush(&m_bmp);dc.FillRect(rcclient, &brush);dc.BitBlt(rcclient.left, rcclient.top, rcclient.Width(),rcclient.Height(),&memdc, rcclient.left, rcclient.top,SRCPAINT);brush.DeleteObject();// Do not call CDialog::OnPaint() for painting messages}以上四种方法唯有KoDak可以支持多种图像,其它的只支持BMP使用IPicture::Render 绘制图片的方法说明:HRESULT Render(HDC hdc, //Handle of device context on which to render the image//绘图设备long x, //Horizontal position of image in hdc//绘图设备上的X起始坐标long y, //Vertical position of image in hdc//绘图设备上的Y起始坐标long cx, //Horizontal dimension of destination rectangle//绘图设备上的水平像素单位数(宽)long cy, //Vertical dimension of destination rectangle//绘图设备上的垂直像素单位数(高)OLE_XPOS_HIMETRIC xSrc,//Horizontal offset in source picture//原图的X起始坐标OLE_YPOS_HIMETRIC ySrc,//Vertical offset in source picture//原图的Y起始坐标OLE_XSIZE_HIMETRIC cxSrc,//Amount to copy horizontally in source picture//总计拷贝的水平像素单位数(宽)OLE_YSIZE_HIMETRIC cySrc,//Amount to copy vertically in source picture//总计拷贝的垂直像素单位数(高)LPCRECT prcWBounds//Pointer to position of destination for a metafile hdc//图源文件指针);范例:HRESULThr=m_lppi->Render(pDC->m_hDC,0,0,100,100,0,0,11774,20320,&rc);使用CreateFile取得文件句柄的方法说明HANDLE WINAPI CreateFile(LPCTSTR lpFileName,//The name of the object to be created or opened.//打开或者新建的文件名DWORD dwDesiredAccess,// The access to the object, which can be read, write, or both.// 文件访问权限常用的是GENERIC_EXECUTE / GENERIC_READ /GENERIC_WRITEDWORD dwShareMode,// The sharing mode of an object, which can be read, write, both, or none// 文件的共享模式,常用的是FILE_SHARE_DELETE / FILE_SHARE_READ/FILE_SHARE_WRITE ,0表示不共享LPSECURITY_ATTRIBUTES lpSecurityAttributes,// A pointer to a SECURITY_ATTRIBUTES structure that determines whether or not the returned handle can be inherited by child processes.// 详细内容,参见msdn 的相关描述,我就不翻译了DWORD dwCreationDisposition,// An action to take on files that exist and do not exist.// 详细内容,参见msdn 的相关描述,我就不翻译了DWORD dwFlagsAndAttributes,// The file attributes and flags.// 详细内容,参见msdn 的相关描述,我就不翻译了HANDLE hTemplateFile// A handle to a template file with the GENERIC_READ access right. The template file supplies file attributes and extended attributes for the file that is being created. This parameter can be NULL.// 详细内容,参见msdn 的相关描述,我就不翻译了);范例:HANDLEhFile=CreateFile(_T("\\aaa.jpg"),GENERIC_READ,0,NULL,OPEN_E XISTING,0,NULL);使用IPersistStream::Load获取LPPICTURE对象的方法:STDAPI OleLoadPicture(IStream * pStream,//Pointer to the stream that contains picture's dataLONG lSize, //Number of bytes read from the streamBOOL fRunmode,//The opposite of the initial value of the picture's// propertyREFIID riid, //Reference to the identifier of the interface// describing the type of interface pointer to returnVOID ppvObj //Address of output variable that receives interface// pointer requested in riid);其他方法://按文件大小分配内存LPVOID pvData;HGLOBALhGlobal=GlobalAlloc(GMEM_MOVEABLE,dwFileSize);//锁定内存pvData=GlobalLock(hGlobal);//读取文件到内存DWORD dwFileRead=0;BOOLbRead=ReadFile(hFile,pvData,dwFileSize,&dwFileRead,NULL);//从已分配内存生成IStream流HRESULThr=CreateStreamOnHGlobal(hGlobal,TRUE,&pstm);hr=OleLoadPicture(pstm,dwFileSize,FALSE,IID_IPicture,( LPVOID*)&(*lppi));pstm->Release();一个相对完整的步骤//加载图片BOOL CPicTestDlg::LoadMyJpegFile(CString fname,LPPICTURE*lppi){HANDLEhFile=CreateFile(fname,GENERIC_READ,0,NULL,OPEN_EXISTING ,0,NULL);if(hFile==INVALID_HANDLE_VALUE){CString str;str.Format(_T("%s无法被打开"),fname);MessageBox(str);return FALSE;}//取得文件大小DWORD dwFileSize=GetFileSize(hFile,NULL);if((DWORD)-1==dwFileSize){CloseHandle(hFile);MessageBox(_T("图像文件是空的"));return FALSE;}//读取图像文件LPVOID pvData;//按文件大小分配内存HGLOBALhGlobal=GlobalAlloc(GMEM_MOVEABLE,dwFileSize);if(NULL==hGlobal){CloseHandle(hFile);MessageBox(_T("内存不足,无法分配足够内存"));return FALSE;}pvData=GlobalLock(hGlobal);if(NULL==pvData){GlobalUnlock(hGlobal);CloseHandle(hFile);MessageBox(_T("无法锁定内存"));return FALSE;}DWORD dwFileRead=0;BOOLbRead=ReadFile(hFile,pvData,dwFileSize,&dwFileRead,NULL);GlobalUnlock(hGlobal);CloseHandle(hFile);if(FALSE==bRead){MessageBox(_T("读文件出错"));return FALSE;}LPSTREAM pstm=NULL;//从已分配内存生成IStream流HRESULT hr=CreateStreamOnHGlobal(hGlobal,TRUE,&pstm);if(!SUCCEEDED(hr)){MessageBox(_T("生成流操作失败"));if(pstm!=NULL)pstm->Release();return FALSE;}else if(pstm==NULL){MessageBox(_T("生成流操作失败"));return FALSE;}if(!*lppi)(*lppi)->Release();hr=OleLoadPicture(pstm,dwFileSize,FALSE,IID_IPicture,(LPVO ID*)&(*lppi));pstm->Release();if(!SUCCEEDED(hr)){MessageBox(_T("加载操作失败"));return FALSE;}else if(*lppi==NULL){MessageBox(_T("加载操作失败"));return FALSE;}return TRUE;}//绘制图片TCHAR strPath[MAX_PATH];memset(strPath,0,MAX_PATH);//得到当前路径GetCurrentDirectory(MAX_PATH,strPath);//定义图片路径wcscat_s(strPath,MAX_PATH,_T("\\145.bmp"));//加载图片到m_lppim_bHadLoad=LoadMyJpegFile(strPath,&m_lppi);//取得绘图设备CDC *pDC=GetDC();//定义绘图矩形区域CRect rc;//得到图片长宽long hmWidth=0;long hmHeight=0;m_lppi->get_Height(&hmHeight);m_lppi->get_Width(&hmWidth);//定义区域与设备关联GetClientRect(&rc);int nWidth,nHeight;//得到设备的长宽nWidth=rc.Width();nHeight=rc.Height();//绘制图片到设备区域HRESULThr=m_lppi->Render(pDC->m_hDC,nWidth,0,-nWidth,nHeight,hmWidt h,hmHeight,-hmWidth,-hmHeight,&rc);使用以上内容可以在mfc的窗体中的任何地方绘制图片,重绘的时候,需要在方法OnPaint()中加以定义,另外可以在OnInitDialog()中提前加载图片到内存中.void CsymmetryImageDlg::OnBnClickedOpenimage(){CFileDialog fileDlg(true, (LPCTSTR)_T("BMP文件"), (LPCTSTR)_T("*.bmp"), OFN_HIDEREADONL Y, (LPCTSTR)_T("BMP文件|*.bmp"), NULL);if (fileDlg.DoModal() == IDOK){/// 获得图像文件路径m_imagePath.SetWindowText(fileDlg.GetPathName());/// 直接用PictureBox显示BMP图像HBITMAP hBitmap = (HBITMAP)::LoadImage(NULL, fileDlg.GetPathName(), IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);m_pictureBox.SetBitmap(hBitmap);}UpdateData(FALSE);}void CsymmetryImageDlg::OnBnClickedButton1(){// TODO: 在此添加控件通知处理程序代码CFileDialog fileDlg(true, (LPCTSTR)_T("JPG文件"), (LPCTSTR)_T("*.jpg"), OFN_HIDEREADONL Y, (LPCTSTR)_T("JPG文件|*.jpg"), NULL);if (fileDlg.DoModal() == IDOK){GetDlgItem(IDC_EDIT1)->SetWindowText(fileDlg.GetPathName());/// 显示jpg图像CImage image;image.Load((LPCTSTR)(fileDlg.GetPathName()));HDC hdc = ::GetDC(this->m_hWnd);image.Draw(hdc, 300, 200);}UpdateData(FALSE);}本文来自CSDN博客,转载请标明出处:/jianuMan/archive/2010/09/19/5895625.aspx。