去年犯小人,万事不顺,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 为什么用依赖属性而不用属性

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

源代码:

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

wpf图片定点缩放的更多相关文章

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

    原文:WPF图片预览之移动.旋转.缩放 RT,这个功能比较常见,但凡涉及到图片预览的都跑不了,在说自己的实现方式前,介绍一个好用的控件:Extended.Toolkit中的Zoombox,感兴趣的同学 ...

  2. Android 图片的缩放与旋转

    本文实现Android中的图片的缩放效果 首先设计布局: <LinearLayout xmlns:android="http://schemas.android.com/apk/res ...

  3. OpenCV图像金字塔:高斯金字塔、拉普拉斯金字塔与图片尺寸缩放

    这篇已经写得很好,真心给作者点个赞.题目都是直接转过来的,直接去看吧. Reference Link : http://blog.csdn.net/poem_qianmo/article/detail ...

  4. Android动画及图片的缩放和旋转

    Android动画有2种,一种是Tween Animation,另一种是Frame Animation,先说说Tween动画吧. Tween动画是对视图对象中的内容进行一系列简单的转换,比如位置的移动 ...

  5. iOS实现图片的缩放和居中显示

    直接上代码 // // MoveScaleImageController.h // MoveScaleImage // // Created by on 12-4-24. // Copyright ( ...

  6. Android实战简易教程-第九枪(BitmapFactory.Options对资源图片进行缩放)

    我们知道,我们编写的应用程序都是有一定内存限制的.程序占用了过高的内存就easy出现OOM(OutOfMemory)异常.因此在展示高分辨率图片的时候,最好先将图片进行压缩,压缩后的图片大小应该和用来 ...

  7. 【OpenCV新手教程之十三】OpenCV图像金字塔:高斯金字塔、拉普拉斯金字塔与图片尺寸缩放

    本系列文章由@浅墨_毛星云 出品,转载请注明出处. 文章链接:http://blog.csdn.net/poem_qianmo/article/details/26157633 作者:毛星云(浅墨) ...

  8. WPF 图片浏览 伪3D效果

    原文:WPF 图片浏览 伪3D效果 首先上效果图: 因项目要求,需要把图片以"好看"."炫"的效果展示出来,特地研究了一下WPF关于3D方面的制作,奈何最终成果 ...

  9. Android多点触控(图片的缩放Demo)

    本文主要介绍Android的多点触控,使用了一个图片缩放的实例,来更好的说明其原理.须要实现OnTouchListener接口,重写当中的onTouch方法. 实现效果图:       源码: 布局文 ...

随机推荐

  1. Mingw/Code::Block/wxWidgets 搭建

    Mingw The MinGW project maintains and distributes a number of different core components and suppleme ...

  2. 详解RocketMQ中的consumer

    上述就是MQ中有关Consumer的类图,下面来介绍一下每个类 1.MQAdmin:底层类,上篇博客已经提过,就不再此重提 2.MQConsumer:Consumer公共的接口,常用的方法如下 如果消 ...

  3. 基于ACIS/HOOPS的3D应用开发简介 【转】

    (整理) 平台:                造型引擎——ACIS         显示引擎——Direct3D/OpenGL/GDI         应用框架——HOOPS   组件关系图     ...

  4. Neutron网络入门

    Neutron是OpenStack核心项目之中的一个,提供云计算环境下的虚拟网络功能.Neutron的功能日益强大,并在Horizon面板中已经集成该模块.作为Neutron的核心开发人员之中的一个. ...

  5. 关于Label::createWithBMFont中资源文件使用的坑爹问题解决方式

    1.问题 使用Label的createWithBMFont,结果.fnt的资源总是找不到或者获取数据失败.原来.fnt资源的使用须要配合该资源的.png共同 使用,如bitmapFontTest3.f ...

  6. Mybatis分页插件-PageHelper的使用

    转载:http://blog.csdn.net/u012728960/article/details/50791343 Mybatis分页插件-PageHelper的使用 怎样配置mybatis这里就 ...

  7. 微信授权网页登陆,oauth

    1.在微信公众号请求用户网页授权之前.开发人员须要先到公众平台官网中的开发人员中心页配置授权回调域名.请注意,这里填写的是域名(是一个字符串),而不是URL,因此请勿加http://等协议头. 2.授 ...

  8. C++11 并发指南系列(转)

    本系列文章主要介绍 C++11 并发编程,计划分为 9 章介绍 C++11 的并发和多线程编程,分别如下: C++11 并发指南一(C++11 多线程初探)(本章计划 1-2 篇,已完成 1 篇) C ...

  9. 【C语言】求两个数中不同的位的个数

    //求两个数中不同的位的个数 #include <stdio.h> int count_different(int a, int b) { int count = 0; int c = a ...

  10. VS中 build,rebuild,clean

    一般来说Rebuild=99%*(Clean+Build),效果在非常小的可能性下会不同,一般可以忽略. Rebuild是对Solution下的所有项目,逐个进行 Clean+Build.不论文件更改 ...