• wpf图片定点缩放


    去年犯小人,万事不顺,4月刚换工作,开始新工作

    遇到一个小问题,需要读取图片,然后对图片进行定点缩放,很简答的逻辑,很简单的代码,但是,这尼玛我被wpf给坑了,这一坑就是三天

    好了,很简单的一个UI

        <Canvas x:Name="canvas">
            <Image Stretch="Fill" Name="image" Source="test.png"></Image>
        </Canvas>

    为什么用Canvas,而不用Grid,这两个布局是一样的呢?
    原因很简单,我们要用到Canvas.Set()这类函数进行移位
    下面我们就图解一下定点缩放的所谓思路吧,小二,上图

    这尼玛图片有点坑爹是吧.....

    一个正方形,鼠标位置在15,5,以这个点进行缩放那缩放后的位置应该是12.5,7.5,图片有个属性是Scale,是缩放比例,1是正常,0.5是一半,依次类推
    那就这好办了,根据当前坐标和图片坐标进行一个相减,然后除以比例系数Scale,进行移位就行了

      public double ImagePointX
            {
                get { return (double)GetValue(ImagePointXProperty); }
                set { SetValue(ImagePointXProperty, value); }
            }
            public static readonly DependencyProperty ImagePointXProperty =
                DependencyProperty.Register("ImagePointX", typeof(double), typeof(MainWindow), new PropertyMetadata(0d, ImagePointXChangedCallBack));
    
            /// <summary>
            /// Image的y坐标
            /// </summary>
            public double ImagePointY
            {
                get { return (double)GetValue(ImagePointYProperty); }
                set
                {
                    SetValue(ImagePointYProperty, value);
                }
            }
            public static readonly DependencyProperty ImagePointYProperty =
                DependencyProperty.Register("ImagePointY", typeof(double), typeof(MainWindow), new PropertyMetadata(0d, ImagePointYChangedCallBack));

    我们设置两个依赖属性,定义image的x,y,在

        private void Window_MouseWheel(object sender, MouseWheelEventArgs e)

    内写方法,进行相应的变换,在代码里都有,代码在最下面
    很简单,点击鼠标移动,点击滑轮定点缩放

    作为一个有良知的愤青,我自己都会问自己,

    这么简单的一个东西还值得你这熊孩子上传所谓的代码??

    鄙人这里有两个问题

    1 为什么用属性,而不用Canvas.GetLeft()或者Canvas.GetTop来获取图片的位置

    这就是坑爹的地方!

      double currentScal = Scale / 0.5;
                    Scale += 0.5;
    
                    var currentPoint = Mouse.GetPosition(this);
                    image.Width = ImageWidth * Scale;
                    image.Height = ImageHeight * Scale;
    
                    ImagePointX = ImagePointX - (currentPoint.X - ImagePointX) / currentScal;
                    ImagePointY = ImagePointY - (currentPoint.Y - ImagePointY) / currentScal;

    看这里,看这里,看上面的代码,这里是简单的比例压缩,

    ImagePointX是当前image的x坐标,如果用Canvas.GetLeft会怎么样?
            var currentPoint = Mouse.GetPosition(this);
                    image.Width = ImageWidth * Scale;
                    image.Height = ImageHeight * Scale;
    
                    //ImagePointX = ImagePointX - (currentPoint.X - ImagePointX) / currentScal;
                    //ImagePointY = ImagePointY - (currentPoint.Y - ImagePointY) / currentScal;
    
                    var left = Canvas.GetLeft(image);
                    var top = Canvas.GetTop(image);
                    left = left - (currentPoint.X - left) / currentScal;
                    top = top - (currentPoint.Y - top) / currentScal;
                    Canvas.SetLeft(image, left);
                    Canvas.SetTop(image, top);

    效果是一样的
    Canvas是实时获取元素位置,在界面上,元素可能有自己模板,里面包含了多个元素,这时候获取的位置就不一定准确(由于是自己项目代码和界面不方便拿出来),这里只是做个介绍,我碰到的就是界面中获取元素位置的时候元素没有刷新,而只能用属性保存元素的上一个位置,当时我跟踪坐标,计算,计算了三天,获取的永远是没有更新的坐标,当鼠标移动后,Canvas才开始更新正确,宁死不知道什么原因,后来用属性的方式,解决了,回头继续研究它为什么没有刷新,原因就在于界面之间的路由和鼠标事件的顺序,与其每次去读取,不如用属性来设置,毕竟,我喜欢数字和程序,因为数字和程序不会骗人

    2 为什么用依赖属性而不用属性

     一方面它是一个自动绑定两方面通知,另一方面,还有一个一个回调机制,方便处理,界面看起来更平滑,易于维护和观赏性

    源代码:

    下载源代码(你妹,终于知道怎么设置连接了)

  • 相关阅读:
    如何解决由于启动用户实例的进程时出错,导致无法生成 SQL Server 的用户实例。该连接将关闭。
    客户端中检测到有潜在危险的Request.Form 值的处理办法 VS2010 .NET 4.0
    VS2010中解决数据集和ObjectDataSource无法自动生成UPDATA和DELETE方法
    使用Eclipse的几个必须掌握的快捷方式
    使用OjectDataSource数据源绑定ListView 高效分页
    NVIDIA SDK 10
    [转]我要的不多
    本月推荐电影
    加/解密
    GDC 2007 Presentations of NV now available.
  • 原文地址:https://www.cnblogs.com/fish124423/p/3690022.html
Copyright © 2020-2023  润新知