电脑常识【雷老师的图像处理】读入一幅RGB图象,编写程序显示图象中任一象素点的R

电脑常识【雷老师的图像处理】读入一幅RGB图象,编写程序显示图象中任一象素点的R

1.读入一幅RGB图象,编写程序显示图象中任一象素点的RGB值。
2.利用C++语言编写代码实现。
3.实现彩色图像的显示与RGB值的显示。

实验步骤

  1. 搭建VS2019环境

  2. 安装MFC工具包

  3. 创建一个工程

  4. 完成界面布局

  5. 添加按键响应函数

程序清单1 添加按键按下的响应函数


void CMFCApplication1Dlg::OnBnClickedButtonOpenbmp()
{
	// TODO: 在此添加控件通知处理程序代码
	// 
	//打开文件 
	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();

			//显示图像	
			//guangjie2333的设计
			CWnd* pWnd = GetDlgItem(IDC_STATIC_PICTURE); //获得pictrue控件窗口的句柄			
			CRect rect;
			pWnd->GetClientRect(&rect); //获得pictrue控件所在的矩形区域			
			CDC* pDC = pWnd->GetDC(); //获得pictrue控件的DC			
			pDC->SetStretchBltMode(COLORONCOLOR);
			StretchDIBits(pDC->GetSafeHdc(), 0, 0, rect.Width(), rect.Height(), 0, 0, bmpInfo.biWidth, bmpInfo.biHeight, pBmpData, pBmpInfo, DIB_RGB_COLORS, SRCCOPY);
			//打印信息
			TRACE(" rect.Width() = %d , rect.Height() = %d, bmpInfo.biWidth = %d ,  bmpInfo.biHeight = %d",rect.Width(), rect.Height(), bmpInfo.biWidth, bmpInfo.biHeight);
			X_Scale = bmpInfo.biWidth / rect.Width();
			Y_Scale = bmpInfo.biHeight / rect.Height();
		}
	}
}

  1. 添加鼠标移动响应函数

程序清单2 添加鼠标移动的响应函数


void CMFCApplication1Dlg::OnMouseMove(UINT nFlags, CPoint point)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值
	//guangjie2333的设计

	CDialogEx::OnMouseMove(nFlags, point);

	//确保鼠标在图像内移动
	if (point.x >= 10 && point.x<=358 && point.y >= 58 && point.y <= 373)
	{
		TRACE("捕捉到了鼠标移动,当前位置 X = %d  Y = %d", point.x, point.y);
		SetDlgItemInt(IDC_EDIT_X, point.x);     //写入坐标值x
		SetDlgItemInt(IDC_EDIT_Y, point.y);     //写入坐标值y

		CWnd* pWnd = GetDlgItem(IDC_STATIC_PICTURE); //获得pictrue控件窗口的句柄
		CDC* pDC = pWnd->GetDC(); //获得pictrue控件的DC	
		HDC hDC = pDC->GetSafeHdc(); ;
		COLORREF rgb = ::GetPixel(hDC, point.x, point.y);  //后两个参数是屏幕绝对坐标,如果用相对坐标则获取错误的灰度值

		int r = GetRValue(rgb);     //获得灰度分量
		int g = GetGValue(rgb);
		int b = GetBValue(rgb);
		SetDlgItemInt(IDC_EDIT_R, r);     //写入灰度分量R
		SetDlgItemInt(IDC_EDIT_G, g);     //写入灰度分量G
		SetDlgItemInt(IDC_EDIT_B, b);     //写入灰度分量B

	}
	else
	{
		SetDlgItemInt(IDC_EDIT_X, 0);     //写入坐标值x
		SetDlgItemInt(IDC_EDIT_Y, 0);     //写入坐标值y
		SetDlgItemInt(IDC_EDIT_R, 0);     //写入灰度分量R
		SetDlgItemInt(IDC_EDIT_G, 0);     //写入灰度分量G
		SetDlgItemInt(IDC_EDIT_B, 0);     //写入灰度分量B
	}
}


  1. 读取bmp图片

  2. 将鼠标放在图片区域内自动显示坐标和RGB

图1
实验结果:

当把鼠标放在火箭的白色火焰区域

图2

当把鼠标放在左上角蓝天区域

图3

实验分析:

从图2 的结果看出,将鼠标放在图片的白色区域R G B 显示均为255 ,结果正确。

从图3 的结果看出,将鼠标放在图片的蓝色区域R G B 显示均为133 143 181 ,结果中的蓝色分量大于红色分量和绿色分量,结果认为正确。

综上所述,实验取得成功。
感想与心得:

  1. 通过这次实验熟悉了C++的语法
  2. 通过这次实验,仅仅花了一个晚上的时间就速成了MFC,对界面设计和人机交互有了更深的理解。
  3. 通过这次实验,提高了我解决问题的能力,通过上网搜索相关的内容,将他们创造性的为我所用。
  4. 我与别人的不同点在于我将鼠标放在图片的任何一个位置,无需其他操作,就能显示位置信息和RGB信息。
  5. 我的界面设计比别人更美观和简洁。
  6. 实验结束后会把我解决问题的过程上传至csdn供更多人参考。

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值