图片浏览器开发日志-06(满画布显示)

按:因为模型的原因,图像显示时限定了了显示的区域以及锁定了长宽比,在缩小状态下没有任何问题,但是放大显示,如果还是锁定长宽比,就有些怪异了。因此,在放大状态下,要岁放大比例逐渐增大显示区域,此时长宽比就要根据实际情况进行变化,为了使图像不失真,对图像的裁剪也要变化。

改变显示区域的算法推导

根据本软件显示的模型,显示区域的矩形边界及其坐标是要参与计算的,图形的裁剪也要符合必须的比例关系,因此扩展显示区域,这些关系不能改变。否则,显示出来的图像的比例和位置关系就会出现问题。如图:
在这里插入图片描述
截取的图像用中间深蓝色矩形表示,显示范围 A0,屏幕(扩大的显示区域)为A1,其宽度为Sw,我们利用距离和比例关系进行计算。
问题简化描述为:已知Sub Img 与View A1 的位置关系,求Sub Img 在 Canvas A1 中的位置关系,A0 和A1 几何中心一致。
根据上面的条件,只要求得Sub img 的左上角到A1的左边和右边的距离即可
我们令水平距离为 X
根据比例关系
X=Sx + (Cw-Vw)/2
同理可以求得垂直距离Y
Y=Sy+(Ch-Vh)/2
而Sub Img 长宽不变。

任意显示区域而图像比例不变的代码

			if (!subImg.IsNull()) {
    
    
				subImg.Destroy();
			}
			//subImg.Create(m_ImgRect.Width(), m_ImgRect.Height(), 24); // 原来sub img的大小定义
			subImg.Create(canvasRect.Width(), canvasRect.Height(), 24);//区域改变后的大小

			CBilinearZoomFilter bzFilter;
			CImage tmpImg;
			//m_Ratio2 *= R;
			float ratioW, ratioH;
			ratioW = (float)orgImg.GetWidth() / subImgW;
			ratioH = (float)orgImg.GetHeight() / subImgH;

			CDC* pSrcDC = CDC::FromHandle(orgImg.GetDC());
			CDC* pDstDC = CDC::FromHandle(subImg.GetDC());


			int ModeOld = SetStretchBltMode(pDstDC->m_hDC, COLORONCOLOR);//设置指定设备环境中的位图拉伸模式, looks like STRETCH_HALFTONE mode,  0.16 ms or 0.00 ms
			float x, y, w, h;

			w = viewRec.Width()*ratioW;
			h = viewRec.Height()*ratioH;
			//原显示区域左上坐标
			x = (0 - subImgX) / subImgW*viewRec.Width() ;
			y = (0 - subImgY) / subImgH*viewRec.Height();

			//调整显示区域后的左上坐标
			x += (canvasRect.Width() - viewRec.Width()) / 2.0 +0.5;
			y += (canvasRect.Height() - viewRec.Height()) / 2.0 +0.5;
			pDstDC->StretchBlt(x, y, w, h, pSrcDC, 0, 0, orgImg.GetWidth(), orgImg.GetHeight(), SRCCOPY);
			SetStretchBltMode(pDstDC->m_hDC, ModeOld);
			subImg.ReleaseDC();
			orgImg.ReleaseDC();

说明:在计算中一定不要在中间过程采用整数,否则其舍入误差会影响显示效果,而且误差会累积。

2020-03-28 于泛五道口地区

ps:北京春日正好,明天去山里看杏花。
配图和主题无关

猜你喜欢

转载自blog.csdn.net/Uman/article/details/105163672
今日推荐