MFC完成图片查看器的功能

MFC完成图片查看器的功能预期目标:1.打开同类型的位图,文件按顺序排列时可顺序打开下一张图像;2.用鼠标滚轮完成图像的放大及缩小,且以鼠标所指的像素点为固定像素点;3.显示图像的绝对像素坐标和相对像素坐标,并且显示图像的放大比例。需要注意的点:1.在放大的时候,会遇到图像上、下、左、右侧超出显示控件的情况,因此在放大的时候,需要判断图像边界位置。2.在放大及缩小的时候要保证图像长宽...
摘要由CSDN通过智能技术生成

MFC完成图片查看器的功能

预期目标:

1.打开同类型的位图,文件按顺序排列时可顺序打开下一张图像;
2.用鼠标滚轮完成图像的放大及缩小,且以鼠标所指的像素点为固定像素点;
3.显示图像的绝对像素坐标和相对像素坐标,并且显示图像的放大比例。

需要注意的点:

1.在放大的时候,会遇到图像上、下、左、右侧超出显示控件的情况,因此在放大的时候,需要判断图像边界位置。
2.在放大及缩小的时候要保证图像长宽同比变换,即保证图像不失真。
3.在找出图像绝对像素坐标和相对像素坐标时,要注意比例转换。
4.开始楼主敲得代码,在缩放图像时,总是出现闪屏的现象,后来才发现原因,不能直接在控件里放置图像,需要在缓存一 次,就解决闪屏现象。

效果图如下:

缩放效果

话不多说,直接上代码!原创不易,转载请注明出处,谢谢~

水平有限,欢迎指正交流~~

void CImageViewDlg::OnSize(UINT nType, int cx, int cy)
{
   
	if (m_listRect.GetCount() > 0)
	{
   
		CRect dlgNow;
		GetWindowRect(&dlgNow);
		POSITION pos = m_listRect.GetHeadPosition();//第一个保存的是对话框的Rect  
		CRect dlgSaved;
		dlgSaved = m_listRect.GetNext(pos);
		ScreenToClient(dlgNow);
		float x = dlgNow.Width() * 1.0 / dlgSaved.Width();//根据当前和之前保存的对话框的宽高求比例  
		float y = dlgNow.Height()  *1.0 / dlgSaved.Height();
		ClientToScreen(dlgNow);
		CRect childSaved;
		CWnd* pWnd = GetWindow(GW_CHILD);
		while (pWnd)
		{
   
			childSaved = m_listRect.GetNext(pos);//依次获取子窗体的Rect  
			childSaved.left = dlgNow.left + (childSaved.left - dlgSaved.left)*x;//根据比例调整控件上下左右距离对话框的距离  
			childSaved.right = dlgNow.right + (childSaved.right - dlgSaved.right)*x;
			childSaved.top = dlgNow.top + (childSaved.top - dlgSaved.top)*y;
			childSaved.bottom = dlgNow.bottom + (childSaved.bottom - dlgSaved.bottom)*y;
			ScreenToClient(childSaved);
			pWnd->MoveWindow(childSaved);
			pWnd = pWnd->GetNextWindow();
		}
		CWnd *pwnd = GetDlgItem(IDC_Picture);
		pwnd->GetClientRect(&picRect);
		CDC *pDC = pwnd->GetDC();
		pDC->SetStretchBltMode(COLORONCOLOR);
		Image.Destroy();
		File_Open = Image.Load(FilePath);
		if (File_Open != 0)
		{
   
			File_Open = 2;
			return;
		}
		RectSize(Image, picRect, curRect, Image_scale);
		ZoomImage(Image, picRect, curRect, g_iZoom, Image_scale);
	}
}

打开文件。

void CImageViewDlg::OnBnClickedOpenFile()
{
   
	CString filter = L"所有文件(*.bmp,*.jpg,*.tiff)|*.bmp;*.jpg;*.gif;*.tiff| BMP(*.bmp)|*.bmp|JPG(*.jpg)|*.jpg|GIF(*.gif)|TIFF(*.tiff)|*.tiff";
	CFileDialog Ofile(TRUE, NULL, NULL, OFN_HIDEREADONLY, filter, NULL);
	g_iZoom = 1;
	g_iRadio = 0.5;
	if (IDOK == Ofile.DoModal())
	{
   
		FilePath = Ofile.GetPathName();
		CString fEnt = Ofile.GetFileExt();
		End_name = fEnt.MakeLower();
		File_Folder = FilePath.Left(FilePath.GetLength() - End_name.GetLength() - 2);
		CString tmp_count = FilePath.Left(FilePath.GetLength() - End_name.GetLength() - 1);
		tmp_count = tmp_count.Right(1);
		count = _ttoi(tmp_count);
		CWnd* pWnd = GetDlgItem(IDC_Picture);
		CDC* pDC = pWnd->GetDC();
		HDC hDC = pDC->m_hDC;
		pWnd->GetClientRect(&picRect);
		Image.Destroy();
		Image.Load(FilePath);
		Image_Rat = (float)Image.GetWidth() / (float)Image.GetHeight();
		RectSize(Image, picRect, curRect, Image_scale);
		::SetStretchBltMode(hDC, HALFTONE);
		::SetBrushOrgEx(hDC, 0, 0, NULL);
		ZoomImage(Image, picRect, curRect, g_iZoom, Image_scale);
		SetDlgItemText(IDC_Text1, FilePath);
		ReleaseDC(pDC);
	}
	// TODO: 在此添加控件通知处理程序代码
}

void CImageViewDlg::OnBnClickedNextFile()
{
   
	CString filter = L"所有文件(*.bmp,*.jpg,*.tiff)|*.bmp;*.jpg;*.gif;*.tiff| BMP(*.bmp)|*.bmp|JPG(*.jpg)|*.jpg|GIF(*.gif)|TIFF(*.tiff)|*.tiff";
	CFileDialog Ofile(TRUE, NULL, NULL, OFN_HIDEREADONLY, filter, NULL);
	CString tmp_Path, tmp_count;
	g_iZoom = 1;
	g_iRadio = 0.5;
	count++;
	tmp_count.Format(_T("%01d."), count);
	FilePath = File_Folder + tmp_count + End_name;
	CWnd* pWnd;
	pWnd = GetDlgItem(IDC_Picture);
	CDC* pDC = pWnd->GetDC();
	HDC hDC = pDC->m_hDC;
	pWnd->GetClientRect(&picRect);
	Image.Destroy();
	File_Open = Image.Load(FilePath);
	if (File_Open != 0)
	{
   
		count--;
		tmp_count.Format(_T("%01d."), count);
		FilePath = File_Folder + tmp_count + End_name;
		File_Open = Image.Load(FilePath);
		File_Open = 2;
		return;
	}
	Image_Rat = (float)Image.GetWidth() / (float)Image.GetHeight();
	RectSize(Image, picRect, curRect, Image_scale);
	::SetStretchBltMode(hDC, HALFTONE);
	::SetBrushOrgEx(hDC, 0, 0, NULL);
	ZoomImage(Image, picRect, curRect, g_iZoom, Image_scale);
	SetDlgItemText(IDC_Text1, FilePath);
	ReleaseDC(pDC);

	// TODO: 在此添加控件通知处理程序代码
}

缩放到边缘时,避免图像移出显示窗口。

void CImageViewDlg::RectSize(CImage &inputImage, CRect &inputRect, CRect &outputRect, float &imput_scale)
{
   
	float in_x, in_y;
	in_x = inputRect.Width();
	in_y = inputRect.Height();
	float rows, cols;
	rows = inputImage.GetHeight();
	cols = inputImage.GetWidth();
	float rat = cols / rows;
	if (rows > in_y && cols < in_x)
	{
   
		imput_scale = rows / in_y;
		outputRect.left = (in_x - (in_y * rat)) / 2;
		outputRect.right = outputRect.left + (in_y * rat);
		outputRect.top = 0;
		outputRect.bottom = in_y;
	}
	else if (rows < in_y && cols >in_x)
	{
   
		imput_scale = cols / in_x;
		outputRect.left = 0;
		outputRect.right = in_x;
		outputRect.top = (in_y - (in_x / rat)) / 2;
		outputRect.bottom = outputRect.top + (in_x / rat);
	}
	else if (rows > in_y && cols > in_x)
	{
   
		if ((rows / in_y) >= (cols / in_x))
		{
   
			imput_scale = rows / in_y;
			outputRect.left = (in_x - (in_y * rat)) / 2;
			outputRect.right = outputRect.left + (in_y * rat);
			outputRect.top = 0;
			outputRect.bottom = in_y;
		}
		else if ((rows / in_y) < (cols / in_x))
		{
   
			imput_scale = cols / in_x;
			outputRect.left = 0;
			outputRect.right = in_x;
			outputRect.top = (in_y - (in_x / rat)) / 2;
			outputRect.bottom = outputRect.top + (in_x / rat);
		}
	}
	else if (rows < in_y && cols < in_x)
	{
   
		if ((in_y / rows) >= (in_x / cols))
		{
   
			imput_scale = cols / in_x;
			outputRect.left = 0;
			outputRect.right = in_x;
			outputRect.top = (in_y - (in_x / rat)) / 2</
  • 4
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值