一、建立SDI工程
在stdafx.h中添加CvvImage.h 的头文件包含
二、在Doc类中添加变量
找到 ***Doc 也就是文档类的定义,添加一个变量CvvImage m_image; 将 m_image的类型设置为public。
三、添加虚函数
添加两个函数,分别用来打开图片文件和保存图片文件,添加过程见下图。
分别添加函数OnOpenDocument 和 OnSaveDocument 如下面的代码:
BOOL COpenCV_SDIDoc::OnOpenDocument(LPCTSTR lpszPathName) { if (!CDocument::OnOpenDocument(lpszPathName)) return FALSE; // TODO: 在此添加您专用的创建代码 m_image.Load(lpszPathName); return TRUE; }
BOOL COpenCV_SDIDoc::OnSaveDocument(LPCTSTR lpszPathName) { // TODO: 在此添加专用代码和/或调用基类 m_image.Save(lpszPathName); return TRUE; }
注意:return TURE;
四、在View类中添加显示图像代码
在View类中间添加必要的图片显示代码,主要是在Ondraw里面。
void COpenCV_SDIView::OnDraw(CDC* pDC/*pDC*/) { CdemoDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); if (!pDoc) return; // TODO: 在此处为本机数据添加绘制代码 CvvImage & img = pDoc ->m_image; CRect r; GetClientRect (&r); img.DrawToHDC(pDC->GetSafeHdc() ,r); }
【编译测试】
编译整个程序,会出现一个错误:
error C2664: 'CvvImage::Load' : cannot convert parameter 1 from 'LPCTSTR' to 'const char *'
error C2664: 'CvvImage::Save' : cannot convert parameter 1 from 'LPCTSTR' to 'const char *'
解决方法:
运行效果:
五、滚轮调节图像大小
1、为*view类添加public变量 double scale;
2、使用类向导为*view类添加虚函数OnMouseWheel,并添加以下代码。
BOOL COpenCV_SDIView::OnMouseWheel(UINT nFlags, short zDelta, CPoint pt) { // TODO: 在此添加消息处理程序代码和/或调用默认值 //AfxMessageBox("ok"); static float upLimit = 10.0f; static float downLinit = 0.04f; static float fUp = 1.1f; static float fDown = 0.9f; if(zDelta > 0 && scale <= upLimit) { scale *= fUp; } else if(zDelta < 0 && scale >= downLinit) { scale *= fDown; } this->Invalidate(); return CView::OnMouseWheel(nFlags, zDelta, pt); }
void COpenCV_SDIView::OnDraw(CDC* pDC) { COpenCV_SDIDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); if (!pDoc) return; // TODO: 在此处为本机数据添加绘制代码 //static CRect rect(0, 0,0, 0); CRect rect; GetClientRect (&rect); XFORM xForm = //the affine tranform matrix which GDI adapted. { 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f }; xForm.eM11 = scale; xForm.eM22 = scale; pDC->SetGraphicsMode(GM_ADVANCED); pDC->SetWorldTransform(&xForm); CvvImage & img = pDoc ->m_image; img.DrawToHDC(pDC->GetSafeHdc() ,rect); }
六、无拉伸显示原图像
以上显示存在一个问题:原图像被拉伸了,要想没有缩放地绘制图像的部分到DC,需要使用下面这个函数。
void CvvImage::Show(HDC dc, int x, int y, int w, int h, int from_x, int from_y);代码如下:
void COpenCV_SDIView::OnDraw(CDC* pDC) { COpenCV_SDIDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); if (!pDoc) return; // TODO: 在此处为本机数据添加绘制代码 else { CvvImage & img = pDoc ->m_image; int x = 0, y = 0; CRect rect; GetClientRect(&rect); if(img.Width() < rect.Width ()) //将图像摆放在视图中央 { x = rect.Width () - img.Width(); x = x / 2; } if(img.Height() < rect.Height()) { y = rect.Height() - img.Height(); y = y / 2; } //显示 img.Show(pDC->m_hDC, x, y, img.Width(),img.Height(), m_ImageX, m_ImageY); } }
【测试】