opencv中的picture控件实现显示图片和双击放大功能
显示功能实现
.h头文件添加声明
afx_msg void Cshow2Dlg::DrawMat(cv::Mat & img, UINT nID);
.cpp文件添加函数代码DrawMat(Mat & img, UINT nID)并且创建全局变量
Mat pic,pic1;//存储两个picture控件现在显示内容
void Cshow2Dlg::DrawMat(Mat & img, UINT nID)
{
Mat imgTmp;//画图的存储图片
if (nID == IDC_left) pic = img.clone();
else if (nID == IDC_right)pic1 = img.clone();
CRect rect;
GetDlgItem(nID)->GetClientRect(&rect); // 获取控件大小
cv::resize(img, imgTmp, cv::Size(rect.Width(), rect.Height()));// 缩小或放大Mat并备份
// 转一下格式 ,这段可以放外面,
switch (imgTmp.channels())
{
case 1:
cv::cvtColor(imgTmp, imgTmp, CV_GRAY2BGRA); // GRAY单通道
break;
case 3:
cv::cvtColor(imgTmp, imgTmp, CV_BGR2BGRA); // BGR三通道
break;
default:
break;
}
int pixelBytes = imgTmp.channels()*(imgTmp.depth() + 1); // 计算一个像素多少个字节
// 制作bitmapinfo(数据头)
BITMAPINFO bitInfo;
bitInfo.bmiHeader.biBitCount = 8 * pixelBytes;
bitInfo.bmiHeader.biWidth = imgTmp.cols;
bitInfo.bmiHeader.biHeight = -imgTmp.rows;
bitInfo.bmiHeader.biPlanes = 1;
bitInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bitInfo.bmiHeader.biCompression = BI_RGB;
bitInfo.bmiHeader.biClrImportant = 0;
bitInfo.bmiHeader.biClrUsed = 0;
bitInfo.bmiHeader.biSizeImage = 0;
bitInfo.bmiHeader.biXPelsPerMeter = 0;
bitInfo.bmiHeader.biYPelsPerMeter = 0;
// Mat.data + bitmap数据头 -> MFC
CDC *pDC = GetDlgItem(nID)->GetDC();
::StretchDIBits(
pDC->GetSafeHdc(),
0, 0, rect.Width(), rect.Height(),
0, 0, rect.Width(), rect.Height(),
imgTmp.data,
&bitInfo,
DIB_RGB_COLORS,
SRCCOPY
);
ReleaseDC(pDC);
编写鼠标双击响应函数
首先向对话框添加事件响应函数OnLButtonDblClk
并添加以下代码
void Cshow2Dlg::OnLButtonDblClk(UINT nFlags, CPoint point)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
CRect rect_ctr, rect_ctr1;
CPoint point1 = point;
(this->GetDlgItem(IDC_left))->GetWindowRect(&rect_ctr);//获取Picture控件相对屏幕左上角的坐标,
//存储到rect_ctr中
(this->GetDlgItem(IDC_right))->GetWindowRect(&rect_ctr1);//获取Picture控件相对屏幕左上角的坐标
ScreenToClient(rect_ctr);//获取Picture控件相对对话框客户区左上角的坐标
point.x -= rect_ctr.left;//point获取的是鼠标相对对话框客户区左上角的坐标,减去rect_ctr.left和
point.y -= rect_ctr.top;//rect_ctr.top后,即为鼠标相对Picture控件左上角的坐标
//获取状态栏上的文字,并将鼠标的坐标显示在状态栏上
//如果鼠标位于Picture控件之外,在对话框状态栏上不显示其坐标
if (point.x>(rect_ctr.right - rect_ctr.left) || point.y>(rect_ctr.bottom - rect_ctr.top)
|| point.x<0 || point.y<0)
;
else
{
Rect m;
m.x = pic.cols*point.x / (rect_ctr.right - rect_ctr.left);
m.y = pic.rows*point.y / (rect_ctr.bottom - rect_ctr.top);
/* circle(pic, Size(m.x, m.y), 70, Scalar(0, 255, 255), 8, 8);*/
if (m.x >pic.cols * 7 / 8)//求出鼠标点击后可放大的矩形类型rect的值
m.x = pic.cols * 7 / 8;
else if (m.x>pic.cols / 8)
m.x = m.x - pic.cols / 16;
else m.x = 0;
if (m.y > pic.rows * 7 / 8)
m.y = pic.rows * 7 / 8;
else if (m.y > pic.rows / 8)
m.y = m.y - pic.rows / 16;
else m.y = 0;
m.width = pic.cols / 8;
m.height = pic.cols / 8;
Mat WE = pic(m).clone();
DrawMat(WE, IDC_left);//左图像放大
}
ScreenToClient(rect_ctr1);//获取pic1ture控件相对对话框客户区左上角的坐标
point1.x -= rect_ctr1.left;//point1获取的是鼠标相对对话框客户区左上角的坐标,减去rect_ctr1.left和
point1.y -= rect_ctr1.top;//rect_ctr1.top后,即为鼠标相对pic1ture控件左上角的坐标
//获取状态栏上的文字,并将鼠标的坐标显示在状态栏上
//如果鼠标位于pic1ture控件之外,在对话框状态栏上不显示其坐标
if (point1.x>(rect_ctr1.right - rect_ctr1.left) || point1.y>(rect_ctr1.bottom - rect_ctr1.top)
|| point1.x<0 || point1.y<0)
;
else
{
Rect m;
m.x = pic1.cols*point1.x / (rect_ctr1.right - rect_ctr1.left);
m.y = pic1.rows*point1.y / (rect_ctr1.bottom - rect_ctr1.top);
if (m.x >pic1.cols * 7 / 8)
m.x = pic1.cols * 7 / 8;
else if (m.x>pic1.cols / 8)
m.x = m.x - pic1.cols / 16;
else m.x = 0;
if (m.y > pic1.rows * 7 / 8)
m.y = pic1.rows * 7 / 8;
else if (m.y > pic1.rows / 8)
m.y = m.y - pic1.rows / 16;
else m.y = 0;
m.width = pic1.cols / 8;
m.height = pic1.cols / 8;
Mat WE = pic1(m);
DrawMat(WE, IDC_right);//左图像放大
};//在picture控件里面则
CDialogEx::OnLButtonDblClk(nFlags, point);
}