如何在缩放时基于图像中的点重新定位图像 [英] How to relocate an Image based on a point in Image while zooming

查看:81
本文介绍了如何在缩放时基于图像中的点重新定位图像的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发一个基于MFC文档视图的图像查看器应用程序。观众可以选择缩放和平移图像。

用于显示图像我正在使用stretchBlt GDI功能。

StretchBlt(

int x,

int y,

int nWidth,

int nHeight,

CDC * pSrcDC,

int xSrc,

int ySrc,

int nSrcWidth,

int nSrcHeight,

DWORD dwRop

);







StretchBlt的目标拉伸窗口大小是根据图像宽高比(nSrcWidth / nSrcHeight)和窗口宽高比计算的。图像放在

窗口的中心。



我通过根据缩放系数(通过将宽度和高度值乘以缩放系数)来改变目标拉伸窗口大小(nWidth x nHeight)来实现缩放功能。





同时平移是通过根据平移值移动目标拉伸窗口起始点(x和y)值来实现的(通过添加相应的平移高度和宽度值到x和y)。



我将xSrc和ySrc值保持为0,将nSrcWidth和nSrcHeight值保持为原始图像。



图像查看器和缩放和平移操作正常工作。



我需要根据显示图像中的一个点实现缩放的实际问题。 br />


如果我通过单击相应的显示窗口点进行缩放选择图像上的一个点,则在缩放相同图像后,像素(在缩放图像中)应显示在同一窗口点。

我怎么能实现这个?



下面是我的代码的摘要

CMyView :: OnDraw(CDC pDC)

{

CRect rcClient(0,0,0,0);

GetClientRect(rcClient);

m_ImagActSize = pDoc-> GetImageSize();

// m_ImageSize是我班级的CSize全球成员,其中包含图像的实际大小。

const int cx = rcClient.right; //查看客户区宽度

const int cy = rcClient.bottom; //查看客户区高度

const int bx = m_ImagActSize.cx; //源位图拉伸宽度

const int by = m_ImagActSize.cy; //源位图拉伸高度





const int vx =(int)(bx * m_fZoom * m_pdnXMapRatio);

// vx: - 虚拟文件宽度



// m_fZoom:随所选缩放操作而变化



// m_pdnXMapRatio:此值是一个因子(宽度),它是根据图像和区域的宽高比计算的。这用于维护窗口中图像的纵横比。





const int vy =(int)(* m_fZoom * m_pdnYMapRatio) ;

xDtn = m_xShift + m_xPanValue;

yDtn = m_yShift + m_yPanValue;

// m_xShift:用于居中的恒定宽度偏移值客户端窗口中的图像。

// m_yShift:一个恒定的高度偏移值,用于在客户端窗口中居中图像。

// m_xPanValue& m_yPanValue:宽度&平移值将在平移操作中变化。

// vy: - 虚拟文档高度

// m_fZoom:随所选缩放操作而变化

// m_pdnYMapRatio:此值是一个因子(高度),它是根据图像和区域的宽高比计算的。这用于维护窗口中图像的纵横比。



CImage& Image = pDoc-> GetImage();

pDC-> SetStretchBltMode(COLORONCOLOR);

Image.StretchBlt(pDC-> GetSafeHdc(),xDtn,yDtn ,vx,vy,0,0,bx,by,SRCCOPY);

}







我想,这可以通过根据缩放改变Dest窗口的起始值(x和y)来实现。

为此,我需要知道

howBlt函数如何根据图像大小和显示屏幕窗口拉伸或缩小图像?

如何精确计算窗口起始点应移位多少(同时缩放)以关联两者之间的关系图像像素和窗口像素?



任何人都可以支持解决这个问题吗?

I'm developing an MFC doc-view based Image viewer application. The viewer have option for zooming & panning image.
For displaying the image I'm using stretchBlt GDI function.
StretchBlt(
int x,
int y,
int nWidth,
int nHeight,
CDC* pSrcDC,
int xSrc,
int ySrc,
int nSrcWidth,
int nSrcHeight,
DWORD dwRop
);



The destination stretch window size for StretchBlt is calculating based on Image aspect ratio (nSrcWidth / nSrcHeight) and window aspect ratio. And the image is placed on the center of the
window.

I implemented zoom functionality by varying the destination stretch window size(nWidth x nHeight) based on the zoom factor(by multiplying both width & height values with zoom factor).


Also panning is implemented by shifting destination stretch window start points(x & y) values based on pan shift values(by adding corresponding pan height & width values to x & y).

And I'm keeping xSrc & ySrc values as 0 and nSrcWidth and nSrcHeight value as such of the original image.

The image viewer and zoom and pan operations are working properly.

My actual problems I need to implement zooming based on a point in displaying image.

If I zoom select a point on the image by clicking in corresponding displaying window point, after zooming the same image pixel (in zoomed image)should be displayed in same window point.
How would I can implement this?

Below is an abstract of my code
CMyView:: OnDraw(CDC pDC)
{
CRect rcClient(0, 0, 0, 0);
GetClientRect(rcClient);
m_ImagActSize = pDoc->GetImageSize();
// m_ImageSize is CSize global member of my class which contain actual size of image.
const int cx = rcClient.right; // view client area width
const int cy = rcClient.bottom; // view client area height
const int bx = m_ImagActSize.cx; // source bitmap stretch width
const int by = m_ImagActSize.cy; // source bitmap stretch height


const int vx = (int)(bx * m_fZoom * m_pdnXMapRatio);
// vx:- virtual document width

// m_fZoom : which will vary with selected zoom operation

//m_pdnXMapRatio : This value is a factor (width) which is calculated based on aspect ratio of image and clent area. This is used to maintaion aspect ration of image in window.


const int vy = (int)(by * m_fZoom * m_pdnYMapRatio);
xDtn = m_xShift + m_xPanValue;
yDtn = m_yShift + m_yPanValue;
//m_xShift : a constant width shift value which is for centering the image in client window.
//m_yShift : a constant height shift value which is for centering the image in client window.
//m_xPanValue & m_yPanValue : width & height pan value which will be varied in pan operation.
// vy:- virtual document height
// m_fZoom : which will vary with selected zoom operation
//m_pdnYMapRatio : This value is a factor(height) which is calculated based on aspect ratio of image and clent area. This is used to maintaion aspect ration of image in window.

CImage& Image = pDoc->GetImage();
pDC->SetStretchBltMode(COLORONCOLOR);
Image.StretchBlt(pDC->GetSafeHdc(), xDtn, yDtn, vx, vy, 0, 0, bx, by, SRCCOPY);
}



I think ,this can be achieved by varying Dest window start values(x & y) based on the zoom .
For this I need to know
how stretchBlt function Stretches or Shrink the image based on sizes of image & displaying screen window?
how could exactly calculate how much the window start points should be shifted(while zoom) to correlate the relation between image pixel & window pixel?

Can anyone support to solve this issue?

推荐答案

我认为你的目标值应保持不变,但源值应更改以反映您的缩放状态。 (宽度/高度)



如果你想移动原点,你还需要用差值除以缩放系数来改变x和y。



StretchBlt的rastering操作非常简单。它插值线性。如果您需要更好的质量,您必须寻找更好的解决方案。在像Imagestone或CXImage这样的Codeproject上。



再次仔细阅读MSDN: http://msdn.microsoft.com/en-us/library/windows/desktop/dd145120(v = vs.85)的.aspx [ ^ ]



并尝试一下; - )
I think your destination values should stay constant, but the source values should change to reflect your zoom state. (width/heigth)

If you want to shift the origin, than you have also to change the x and y by the difference divided by zoom factor.

The rastering ops of StretchBlt is very simple. It interpolates linear. If you need better quality you have to look for some better solutions. At Codeproject like Imagestone or CXImage.

read the MSDN again carefully: http://msdn.microsoft.com/en-us/library/windows/desktop/dd145120(v=vs.85).aspx[^]

and try it out ;-)


这篇关于如何在缩放时基于图像中的点重新定位图像的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆