C#关于HWindowControl实现一些便捷功能——(缩放与拖动图像)

C#关于HWindowControl实现一些便捷功能——(缩放与拖动图像)


一、关于Hwindow窗体显示的part

首先 HWindowControl 控件的尺寸是固定的,当我们在这个固定的尺寸中,相对原来显示的一幅完整的图像,现在只显示图像的一部分,即可达到放大效果。
即想放大时,我们便缩小 ImagePart ;想缩小时,我们便放大 ImagePart 。
例如:一幅 800600 的图像,
一开始我们将 ImagePart 设置为:左上角 (0, 0) ,右下角(800
600) ;
现在我们将其设置为 :左上角(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);
        }

源代码在快速移动的过程中,由于高刷新会造成图像闪烁的问题。将HWindow_MoveImage函数中的hWindow.HalconWindow.ClearWindow();函数前后做如下更改,则可以有效的解决闪烁问题。

                HOperatorSet.SetSystem("flush_graphic", "false");
                hWindow.HalconWindow.ClearWindow();
                HOperatorSet.SetSystem("flush_graphic", "true");

猜你喜欢

转载自blog.csdn.net/qq_42504097/article/details/129231042