mfc picture control 类型Rectangle 显示图片,拖放实现,opencv加载图像转CImage显示picture control控件中,保存的CV图像其他用途
本文介绍了在MFC对话框程序中实现图片拖放显示功能的步骤。首先通过DragAcceptFiles(TRUE)启用文件拖放功能,然后添加WM_DROPFILES消息处理函数OnDropFiles。在该函数中,使用DragQueryFile获取文件路径,用OpenCV加载图片,并调用自定义的ShowImg函数显示图片。ShowImg函数实现了图片等比例缩放、格式转换(BGR转RGB/灰度图处理)和居中
·
启用
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;// 此次图像路径,能用的上就用,用不上想删 删
火山引擎开发者社区是火山引擎打造的AI技术生态平台,聚焦Agent与大模型开发,提供豆包系列模型(图像/视频/视觉)、智能分析与会话工具,并配套评测集、动手实验室及行业案例库。社区通过技术沙龙、挑战赛等活动促进开发者成长,新用户可领50万Tokens权益,助力构建智能应用。
更多推荐
所有评论(0)