WPF图片预览之移动、旋转、缩放

RT,这个功能比较常见,但凡涉及到图片预览的都跑不了,在说自己的实现方式前,介绍一个好用的控件:Extended.Toolkit中的Zoombox,感兴趣的同学可以去搜一下这个控件,它封装了常用的预览功能。

开始撸代码,整理一下思路先:
首先打算用一个Window来展示图片,但是QQ、微信预览图片的时候,任务栏并没有出现图标,难道用了什么黑科技?不管它,将Window的ShowInTaskbar设置为False就可以不显示在任务栏了。
继续,提到移动、旋转、缩放之类的,WPF提供了与之对应的Transform:TranslateTransform、RotateTransform、ScaleTransform,所以我们必然要使用他们仨了。怎么触发呢?那就用到事件了,移动么MouseMove,缩放么MouseWheel,旋转的话就是固定的按钮的点击事件了。另外,缩放的话可以限制一下最大和最小的缩放系数,我这边只设了缩小时如果小于系数0.3就不再缩小了,放大系数没有设置。

说一下其中的坑:
MouseWheel事件参数里会取到鼠标的Delta,这个参数不好直接用来设置缩放系数,那多少合适呢,看到别人的经验之谈,用这个Delta/3000即可。

double delta = (double)e.Delta / 3000;
ScaleTransform scale = group.Children[0] as ScaleTransform;
if (scale.ScaleX < 0.3 && scale.ScaleY < 0.3 && e.Delta < 0)
{
        return;
}
scale.CenterX = this.imageControl.ActualWidth / 2;
scale.CenterY = this.imageControl.ActualHeight / 2;
scale.ScaleX += delta;
scale.ScaleY += delta;

MouseMove移动图片的时候,是可以将整个图片移到Window外面去的,这就要我们限制一下图片的移动范围了:

   private void TopMove(TranslateTransform translate, Point position, Point imagePos) 
        {
            if (scaleValue > 1.0)
            {
                if (mouseXY.Y - position.Y > 0.0)//up
                {
                    double wm = winHeight - position.Y;
                    double im = (this.imageControl.ActualHeight - imagePos.Y) * scaleValue;
                    if (wm - im <= -5.0)
                    {
                        translate.Y -= mouseXY.Y - position.Y;
                    }
                }
                else
                {
                    if (position.Y / scaleValue - imagePos.Y <= -5.0)
                    {
                        translate.Y -= mouseXY.Y - position.Y;
                    }
                }
                if (mouseXY.X - position.X > 0.0)//left
                {
                    double iw = (this.imageControl.ActualWidth - imagePos.X) * scaleValue;
                    double ww = winWidth - position.X;
                    if (ww - iw <= -5.0)
                    {
                        translate.X -= mouseXY.X - position.X;
                    }
                }
                else
                {
                    if (position.X / scaleValue - imagePos.X <= -5.0)
                    {
                        translate.X -= mouseXY.X - position.X;
                    }
                }
            }
            else
            {
                if (mouseXY.Y - position.Y > 0.0)//up
                {
                    if (position.Y / scaleValue >= imagePos.Y)
                    {
                        translate.Y -= mouseXY.Y - position.Y;
                    }
                }
                else
                {
                    double im = (this.imageControl.ActualHeight - imagePos.Y) * scaleValue;
                    double wm = winHeight - position.Y;
                    if (im <= wm)
                    {
                        translate.Y -= mouseXY.Y - position.Y;
                    }
                }
                if (mouseXY.X - position.X > 0.0)//left
                {
                    if (position.X / scaleValue >= imagePos.X)
                    {
                        translate.X -= mouseXY.X - position.X;
                    }
                }
                else
                {
                    double iw = (this.imageControl.ActualWidth - imagePos.X) * scaleValue;
                    double ww = winWidth - position.X;
                    if (iw <= ww)
                    {
                        translate.X -= mouseXY.X - position.X;
                    }
                }
            }
        }

稍微解释一下上面的代码,position是鼠标相对于Window的位置,imagePos是鼠标相对于图片的位置,scaleValue是图片当前的缩放比例,当图片是缩小状态(scaleValue<1)时,允许图片在整个Window里拖动,上移时,如果图片上边框触碰到了Window上边框,则不能再上移(另外3个方向原理相同),反之(scaleValue>1),只有当图片超出Window范围时才允许拖动,假设,图片上下超出了Window,则只能上下移动不能左右移动,并且,上移时,如果图片下边框触碰到了Window下边框,则不能再上移(另外3个方向原理相同)。
眼尖的同学可能注意到了上面这个方法名:TopMove,没错,这个算法只适用于图片正着放的时候的位移计算,我们不是有旋转吗,旋转了只有就不能这么算了,原因在于,imagePos始终是相对于图片来的,也就是说,如果图片旋转了90°,那么imagePos的坐标系也要旋转90°,但是我们最终要计算的是相对于Window的坐标系,所以要做相应的转换。

好了,上完整的代码:


    
        
            
                
                
                

你可能感兴趣的:(WPF,wpf,图片缩放,图片旋转,图片拖动)