C#关于HWindowControl实现一些便捷功能——(缩放与拖动图像)
- 一、关于Hwindow窗体显示的part
- 二、以鼠标为中心的缩放
- 三、以鼠标拖动移动图片
一、关于Hwindow窗体显示的part
首先 HWindowControl 控件的尺寸是固定的,当我们在这个固定的尺寸中,相对原来显示的一幅完整的图像,现在只显示图像的一部分,即可达到放大效果。
即想放大时,我们便缩小 ImagePart ;想缩小时,我们便放大 ImagePart 。
例如:一幅 800600 的图像,
一开始我们将 ImagePart 设置为:左上角 (0, 0) ,右下角(800600) ;
现在我们将其设置为 :左上角(0, 0) ,右下角(400, 300) ,
之前用整幅图像去填充 HWindowControl 控件,现在用半幅图像去填充它,显然这部分图像就会被放大。放大的倍数是 2 。
再有
现在我们将其设置为 :左上角(100, 100) ,右下角(500, 400) ,
则就相当于拖动图片向左上角移动。
而我们需要设置part需要的参数就是矩形的左上角与右下角的坐标值,或者左上角以及长宽值。
二、以鼠标为中心的缩放
现在可以缩放了,再看看如何实现以鼠标的当前位置作为中心,进行缩放?
要保证鼠标中心位置,即保证鼠标所指的图像相对位置不变即可。
如图,黑色框为原本图像,当
我们要放大图像时(将原图像变小再按比例填充至HWindowControl 窗口内),所以应该是变换为红色的;
我们要缩小图像时(将原图像变大再按比例压缩至HWindowControl 窗口内),所以应该是变换为蓝色的。
红色点为鼠标在HWindowControl 窗体控件中的坐标。
我们可获取原始图像显示时的part为LUPointX,LUPointY;
获取的鼠标的坐标为MouseX,MouseY;
放大比例Zoom为0.5;
则有红色矩形的左上角坐标为:
LUPointY2 = (MouseY - (Zoom * (MouseY - LUPointY)));
LUPointX2 = (MouseX - (Zoom * (MouseX - LUPointX)));
此处注意图像坐标是从上向下,从左至右递增的。
又有右下角坐标:
//Ht,Wt为原图像的右下角与左上角计算出来的长宽。
RBPointY2 = LUPointY2 + (Ht * Zoom);
RBPointX2 = LUPointX2 + (Wt * Zoom);
到此就可以通过part属性来设置显示区域啦。
全代码如下:
需要把下面的事件绑定到HWindowControl 的HMouseWheel上
public void Scale(object sender, HMouseEventArgs e)
{
double Zoom = 0.5;//缩放比例
HTuple MouseX, MouseY;//鼠标位于图片窗体的坐标
//左上角与右下角坐标
HTuple LUPointY, LUPointX, RBPointY, RBPointX;
HTuple LUPointY2, LUPointX2, RBPointY2, RBPointX2;
//当前显示的界面大小
HTuple Ht, Wt;
HTuple WindowID = hWindowControl1.HalconWindow;
MouseX = e.X;
MouseY = e.Y;
Zoom = e.Delta > 0 ? Zoom : (1 + Zoom);
HOperatorSet.GetPart(WindowID, out LUPointY, out LUPointX, out RBPointY, out RBPointX);
Ht = RBPointY - LUPointY;
Wt = RBPointX - LUPointX;
if ((Ht * Wt) < 32000 * 32000)
{
LUPointY2 = (MouseY - (Zoom * (MouseY - LUPointY)));
LUPointX2 = (MouseX - (Zoom * (MouseX - LUPointX)));
RBPointY2 = LUPointY2 + (Ht * Zoom);
RBPointX2 = LUPointX2 + (Wt * Zoom);
HOperatorSet.SetPart(WindowID, LUPointY2, LUPointX2, RBPointY2, RBPointX2);
hWindowControl.HalconWindow.ClearWindow();
hWindowControl.HalconWindow.DispObj(hImage);
}
}
三、以鼠标拖动移动图片
移动比较简单,
首先我们记录下左键按下时的鼠标坐标位置(startPointX,startPointY),
当鼠标左键释放时的坐标位置(endPointX,endPointY)
可以获得x方向与y方向的插值move_c,move_r;
则可得到:
移动后左上角坐标为:(originalImageUL_c + move_c , originalImageUL_r + move_r)
移动后右下角坐标为:(originalImageDR_c + move_c , originalImageDR_r + move_r)
全代码如下:
Point StartPoint = new Point();
Point EndPoint = new Point();
private void HMouseDown(object sender, HMouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
StartPoint.X = Convert.ToInt32(e.X);
StartPoint.Y = Convert.ToInt32(e.Y);
hWindowControl1.HMouseMove += HMouseMove;
}
}
private void HMouseUp(object sender, HMouseEventArgs e)
{
hWindowControl1.HMouseMove -= HMouseMove;
}
private void HMouseMove(object sender, HMouseEventArgs e)
{
EndPoint.X = Convert.ToInt32(e.X);
EndPoint.Y = Convert.ToInt32(e.Y);
HWindow_MoveImage(StartPoint, EndPoint, hWindowControl1, hImage);
}
public void HWindow_MoveImage(Point startPoint, Point endPoint, HWindowControl hWindow, HImage hImage)
{
int originalImageUL_r;
int originalImageUL_c;
int originalImageDR_r;
int originalImageDR_c;
hWindow.HalconWindow.GetPart(out originalImageUL_r, out originalImageUL_c, out originalImageDR_r, out originalImageDR_c);
int move_r = startPoint.Y - endPoint.Y;
int move_c = startPoint.X - endPoint.X;
hWindow.HalconWindow.SetPart(originalImageUL_r + move_r, originalImageUL_c + move_c, originalImageDR_r + move_r, originalImageDR_c + move_c);
hWindow.HalconWindow.ClearWindow();
hWindow.HalconWindow.DispObj(hImage);
}