opencv中的picture控件实现显示图片和双击放大功能

该博客详细介绍了如何在MFC应用程序中使用OpenCV库来显示图片,并实现双击图片控件进行局部放大的功能。通过创建全局变量存储图片,使用DrawMat函数绘制图片到picture控件,并在OnLButtonDblClk事件中计算双击位置,从而确定要放大的区域,再次调用DrawMat函数以放大显示。整个过程涉及到了图像处理、窗口事件处理及MFC与OpenCV的交互。
摘要由CSDN通过智能技术生成

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);
}



  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

大大怪!叔叔

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值