启用

BOOL YourDlg::OnInitDialog()
{
	CDialogEx::OnInitDialog();
	//...
	SetIcon(m_hIcon, TRUE);			// 设置大图标
	SetIcon(m_hIcon, FALSE);		// 设置小图标
	// TODO: 在此添加额外的初始化代码
	//启用文件拖放功能
	DragAcceptFiles(TRUE);
}

拖个picture control 控件

一顿操作......
类型设置Rectangle 

添加消息

资源视图点主窗口,点消息按钮找到WM_DROPFILES,点这个消息右侧有个小三角,添加个OnDropFiles方法(这名字是自动有的)

去主显示界面的YourDlg.cpp中找到OnDropFiles方法

…这里是分割,以便好观察下边

添加代码

void YourDlg::OnDropFiles(HDROP hDropInfo)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值
	TCHAR filePath[MAX_PATH];
	DragQueryFile(hDropInfo, 0, filePath, MAX_PATH);

	m_CurrentImagePath.Format(_T("%s"), filePath);

	// 使用OpenCV加载图片
	m_CurrentImage = cv::imread(cv::String(CT2A(m_CurrentImagePath.GetString())));

	if (m_CurrentImage.empty()) {
		MessageBox(_T("无法加载图像文件!"), _T("错误"), MB_OK);
		return;
	}

	ShowImg(m_CurrentImage, IDC_PICTURE_CONTROL);//这个是自己写的,要在YourDlg.h中添加头


	CDialogEx::OnDropFiles(hDropInfo);
}

ShowImg(m_CurrentImage, IDC_PICTURE_CONTROL) 这个是自己写的,要在YourDlg.h中添加头

IDC_PICTURE_CONTROL 这个东西的话,应该是PICTURE_CONTROL 控件的ID吧,到底对不对呢,不知道。

添加代码

void YourDlg::ShowImg(const cv::Mat& image, INT control_id)
{
	if (image.empty()) {
		MessageBox(_T("图像为空!"), _T("错误"), MB_OK);
		return;
	}

	// 创建临时副本用于显示,不修改原始图像
	cv::Mat displayImage = image.clone();

	// 获取控件尺寸
	CRect rect;
	GetDlgItem(control_id)->GetClientRect(&rect);
	int controlWidth = rect.Width();
	int controlHeight = rect.Height();

	// 获取图片尺寸
	int imgWidth = displayImage.cols;
	int imgHeight = displayImage.rows;

	// 计算等比例缩放后的尺寸
	double imgRatio = (double)imgWidth / imgHeight;
	double controlRatio = (double)controlWidth / controlHeight;

	int drawWidth, drawHeight;

	if (imgRatio > controlRatio)
	{
		// 以宽度为基准缩放
		drawWidth = controlWidth;
		drawHeight = (int)(controlWidth / imgRatio);
	}
	else
	{
		// 以高度为基准缩放
		drawHeight = controlHeight;
		drawWidth = (int)(controlHeight * imgRatio);
	}

	// 如果需要缩放,创建缩放后的图像
	if (drawWidth != imgWidth || drawHeight != imgHeight)
	{
		cv::Mat resizedImage;
		cv::resize(displayImage, resizedImage, cv::Size(drawWidth, drawHeight), 0, 0, cv::INTER_LINEAR);
		displayImage = resizedImage;
	}

	// 转换OpenCV Mat到CImage
	CImage cimg;
	int channels = displayImage.channels();

	if (channels == 3)
	{
		// BGR转RGB
		cv::Mat rgb;
		cv::cvtColor(displayImage, rgb, cv::COLOR_BGR2RGB);

		// 创建CImage
		cimg.Create(rgb.cols, rgb.rows, 24);

		// 复制数据
		uchar* ps = rgb.data;
		uchar* pimg = (uchar*)cimg.GetBits();
		int step = cimg.GetPitch();
		for (int i = 0; i < rgb.rows; i++)
		{
			memcpy(pimg, ps, rgb.cols * 3);
			ps += rgb.step;
			pimg += step;
		}
	}
	else if (channels == 1)
	{
		// 灰度图
		cimg.Create(displayImage.cols, displayImage.rows, 8);

		// 设置灰度调色板
		RGBQUAD palette[256];
		for (int i = 0; i < 256; i++)
		{
			palette[i].rgbRed = palette[i].rgbGreen = palette[i].rgbBlue = i;
			palette[i].rgbReserved = 0;
		}
		cimg.SetColorTable(0, 256, palette);

		// 复制数据
		uchar* ps = displayImage.data;
		uchar* pimg = (uchar*)cimg.GetBits();
		int step = cimg.GetPitch();
		for (int i = 0; i < displayImage.rows; i++)
		{
			memcpy(pimg, ps, displayImage.cols);
			ps += displayImage.step;
			pimg += step;
		}
	}
	else
	{
		MessageBox(_T("不支持的图像格式!"), _T("错误"), MB_OK);
		return;
	}

	// 计算居中位置
	int x = (controlWidth - drawWidth) / 2;
	int y = (controlHeight - drawHeight) / 2;

	// 绘制图片
	CWnd* pCwnd = GetDlgItem(control_id);
	CDC* pDc = pCwnd->GetDC();

	// 创建内存DC进行双缓冲绘制
	CDC memDC;
	memDC.CreateCompatibleDC(pDc);
	CBitmap bmp;
	bmp.CreateCompatibleBitmap(pDc, controlWidth, controlHeight);
	CBitmap* pOldBmp = memDC.SelectObject(&bmp);

	// 填充背景色
	memDC.FillSolidRect(0, 0, controlWidth, controlHeight, RGB(240, 240, 240));

	// 等比例绘制图片
	cimg.Draw(memDC.m_hDC, x, y, drawWidth, drawHeight);

	// 将内存DC内容绘制到屏幕上
	pDc->BitBlt(0, 0, controlWidth, controlHeight, &memDC, 0, 0, SRCCOPY);

	// 清理资源
	memDC.SelectObject(pOldBmp);
	bmp.DeleteObject();
	memDC.DeleteDC();
	ReleaseDC(pDc);

}
//需要在头文件中加上
CString m_CurrentImagePath; // 用作其他用途的cv图,原图
cv::Mat m_CurrentImage;// 此次图像路径,能用的上就用,用不上想删 删
 
Logo

火山引擎开发者社区是火山引擎打造的AI技术生态平台,聚焦Agent与大模型开发,提供豆包系列模型(图像/视频/视觉)、智能分析与会话工具,并配套评测集、动手实验室及行业案例库。社区通过技术沙龙、挑战赛等活动促进开发者成长,新用户可领50万Tokens权益,助力构建智能应用。

更多推荐