上篇博客简要介绍了如何利用MFC读取并显示一幅位图图像,并获取鼠标点击位置的像素坐标和灰度值信息,主要包含了对话框的创建和添加程序,代码也在上一页中给了大家,但是并没有详细说明功能,所以在这一节当中主要介绍代码的含义。
一、打开并显示位图图片
(一)程序清单
void Cwj_zuoyeDlg::OnBnClickedOpen(){// 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 (pare(_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));//打开图片}}}
(二)函数含义
CString filter = (CString)"图像文件(*.bmp)|*.bmp;*.BMP||";//指明可供选择的文件类型和相应的扩展名CFileDialog dlg(TRUE, NULL, NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, filter, NULL); //打开文件
其中CFileDialog是MFC当中的一个类,它的构造函数如下:
explicit CFileDialog(BOOL bOpenFileDialog, //TRUE则显示打开对话框,为FALSE则显示保存对话文件对话框。LPCTSTR lpszDefExt = NULL,//指定默认的文件扩展名。LPCTSTR lpszFileName = NULL, //指定默认的文件名, 可带上完整的文件路径DWORD dwFlags = OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, // 指明一些特定风格LPCTSTR lpszFilter = NULL,//指明可供选择的文件类型和相应的扩展名。CWnd* pParentWnd = NULL, //为父窗口指针。DWORD dwSize = 0,//OPENFILENAME结构体的大小。BOOL bVistaStyle = TRUE //指定文件对话框的风格,设为TRUE则使用Vista风格的文件对//话框,否则使用旧版本的文件对话框。);
所以上面代码的意思就是打开一个对话框,寻找bmp类型的文件并打开(参数不完整时后面的为默认形式)
相关的链接是/kex1n/p/3595800.html和/grllery/article/details/76234863
//显示图像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));//打开图片
SetWindowPos函数的含义如下
BOOL SetWindowPos(const CWnd* pWndInsertAfter, //窗口的 Z 顺序int x, int y, //窗口位置int cx, int cy,//窗口大小UINT nFlags); //选项
参考链接/findumars/p/3948315.html
显示部分主要参考/sundy_/article/details/7183600
还有另一种显示方法,这种显示方法会把整个图片框都填充满,也就是说可能拉伸或者收缩图像的大小,图像很可能失去原来的形状,主要用法如下
//显示图像CWnd *pWnd=GetDlgItem(IDC_STATIC_PIC); //获得pictrue控件窗口的句柄CRect rect;pWnd->GetClientRect(&rect); //获得pictrue控件所在的矩形区域CDC *pDC=pWnd->GetDC(); //获得pictrue控件的DCpDC->SetStretchBltMode(COLORONCOLOR);StretchDIBits(pDC->GetSafeHdc(),0,0,rect.Width(),rect.Height(),0,0,bmpInfo.biWidth,bmpInfo.biHeight,pBmpData,pBmpInfo,DIB_RGB_COLORS,SRCCOPY);
参考程序/lynn1258/article/details/54376311
该函数具体用法如/hnu_zxc/article/details/7491366
二、显示像素坐标和灰度值
(一)程序清单
void Cwj_zuoyeDlg::OnLButtonDown(UINT nFlags, CPoint point){// TODO: 在此添加消息处理程序代码和/或调用默认值CRect rect;CWnd *pWnd = GetDlgItem(IDC_STATIC); //图像控件框的IDpWnd->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);//写入坐标值xSetDlgItemInt(IDC_EDIT2, y);//写入坐标值yHDC 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);//写入灰度分量RSetDlgItemInt(IDC_EDIT4, g);//写入灰度分量GSetDlgItemInt(IDC_EDIT5, b);//写入灰度分量BCDialogEx::OnLButtonDown(nFlags, point);}
(二)程序简述
GetCursorPos()的用法 通常是 :
CPoint cp;
GetCursorPos(&cp);
它获取的是 鼠标相对屏幕的左上角的距离,单位是像素。而对于一个窗口来说,它的消息响应函数的输入参数通常是相对于客户区左上角的距离。
比如说OnLButtonDown(UINT nFlags, CPoint point)的 point参数,就是相对于客户区的左上角而言的。想要把从GetCursorPos()获得的坐标转化成相对于客户区的坐标,要调用ScreenToClient()函数。
主要参考/SnailProgramer/p/4175561.html
关于MFC编辑框的读写参考/c_gyl/article/details/66972310
这基本把主要部分介绍完了,资料整理不易,所以我就以链接的方式包含起来了,否则长篇大论读者可能不喜欢。
关于这部分内容就介绍到这里,后续还有更新请留意
(一)MFC读取并显示一幅位图图像 并获取鼠标点击位置的像素坐标和灰度值(接上篇博客)