(一)MFC读取并显示一幅位图图像,并获取鼠标点击位置的像素坐标和灰度值

      题目是老师布置的一道作业题,要求用C或C++完成,但不能用VTK/Opencv等软件包,经过很多摸索之后实现了该功能,后续可能还有其他功能要实现,所以先写一篇博客记录下,一方面是方便自己以后使用,另一方面是给其他人做个参考,少走一些弯路。说不定以后学弟学妹们就看到了这篇博客(猜猜我是哪个学校的?)

一、作业要求

要求读取一幅位图图像,即BMP位图,并显示该图像在对话框内。鼠标点击该图像时,显示所点击的像素坐标值和RGB灰度分量。

编译环境:vs2015

二、实现步骤

(一)创建对话框MFC

选择基于对话框的MFC,其他后面的都是默认选项,所以可以直接点击完成即可。

点击完成之后出现如下对话框

把中间的对话框放大,把确定取消两个botton修改为打开图片保存图片,并增加一个图像控件框和五个编辑框,如下图所示

MFC创建就结束了

(二)添加程序

双击打开图片按钮添加程序,如下图所示

添加代码如下:

//打开文件 
	CString filter = (CString)"图像文件(*.bmp)|*.bmp;*.BMP||";//指明可供选择的文件类型和相应的扩展名
	CFileDialog dlg(TRUE, NULL, NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, filter, NULL);  //打开文件

//按下确定按钮 dlg.DoModal() 函数显示对话框
	if (dlg.DoModal() == IDOK)
	{
		//打开对话框获取图像信息
		CString BmpName = dlg.GetPathName();     //获取文件路径名   
		CString EntName = dlg.GetFileExt();      //获取文件扩展名
		EntName.MakeLower();                     //将文件扩展名转换为一个小写字符

		if (EntName.Compare(_T("bmp")) == 0)  //如果是bmp图片则打开显示
		{
			//定义变量存储图片信息
			BITMAPINFO *pBmpInfo;       //记录图像信息头内容
			BYTE *pBmpData;             //图像数据
			BITMAPFILEHEADER bmpHeader; //文件头
			BITMAPINFOHEADER bmpInfo;   //信息头
			CFile bmpFile;              //记录打开文件

				//以只读的方式打开文件 读取bmp图片各部分 bmp文件头 信息 数据
			if (!bmpFile.Open(BmpName, CFile::modeRead | CFile::typeBinary))
				return;
			if (bmpFile.Read(&bmpHeader, sizeof(BITMAPFILEHEADER)) != sizeof(BITMAPFILEHEADER))
				return;
			if (bmpFile.Read(&bmpInfo, sizeof(BITMAPINFOHEADER)) != sizeof(BITMAPINFOHEADER))
				return;
			pBmpInfo = (BITMAPINFO *)new char[sizeof(BITMAPINFOHEADER)];
			//为图像数据申请空间
			memcpy(pBmpInfo, &bmpInfo, sizeof(BITMAPINFOHEADER));  //存储图像信息头内容
			DWORD dataBytes = bmpHeader.bfSize - bmpHeader.bfOffBits;//图像数据大小,单位为字节
			pBmpData = (BYTE*)new char[dataBytes];
			bmpFile.Read(pBmpData, dataBytes);  //存储图像数据
			bmpFile.Close();

			//显示图像
			CStatic *pwnd = (CStatic*)GetDlgItem(IDC_STATIC);  //里面的参数是图片控件的ID
			//pwnd->SetWindowPos(NULL, 0, 0, 0, 0, SWP_NOZORDER | SWP_NOSIZE);
			pwnd->ModifyStyle(0xf, SS_BITMAP);
			pwnd->SetBitmap((HBITMAP)::LoadImage(GetModuleHandle(NULL), BmpName, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE));//打开图片


		}
	}

此时已经可以打开图片了,效果如下:

接下来天加显示坐标值和灰度值的代码:

在类向导里添加消息函数WM_LBUTTONDOWN

添加代码:

代码如下:

void CWJ_zuoye1Dlg::OnLButtonDown(UINT nFlags, CPoint point)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值

	CRect rect;
	CWnd *pWnd = GetDlgItem(IDC_STATIC);
	pWnd->GetWindowRect(&rect);
	ScreenToClient(&rect);

	//先获取鼠标相对于屏幕的坐标
	GetCursorPos(&point);
	int temp_x = point.x;
	int temp_y = point.y;
	//然后得到static控件的rect坐标
	CRect pRect;
	pWnd->GetClientRect(&pRect);
	//最后把当前鼠标的坐标转化为相对于rect的坐标
	pWnd->ScreenToClient(&point);
	int x = point.x;
	int y = point.y;
	SetDlgItemInt(IDC_EDIT1, x);     //写入坐标值
	SetDlgItemInt(IDC_EDIT2, y);     //写入

	HDC hDC = ::GetDC(NULL);

	COLORREF rgb = ::GetPixel(hDC, temp_x, temp_y);
	int r = GetRValue(rgb);
	int g = GetGValue(rgb);
	int b = GetBValue(rgb);
	SetDlgItemInt(IDC_EDIT3, r);     //写入
	SetDlgItemInt(IDC_EDIT4, g);     //写入
	SetDlgItemInt(IDC_EDIT5, b);     //写入

	CDialogEx::OnLButtonDown(nFlags, point);
}

编辑运行:

大概就是这么个情况,时间有限,下一篇我将讲一下上面的代码含义以及相关引用 ,对代码含义有要求的同学可以看我的下篇博客

猜你喜欢

转载自blog.csdn.net/weixin_39270311/article/details/82890502
今日推荐