WPF/Silverlight实现图片局部放大的方法分析

 更新时间:2017年03月10日 11:32:47   作者:Rising_Sun  
这篇文章主要介绍了WPF/Silverlight实现图片局部放大的方法,结合实例形式分析了WPF/Silverlight针对图片属性操作相关实现技巧,需要的朋友可以参考下

本文实例讲述了WPF/Silverlight实现图片局部放大的方法。分享给大家供大家参考,具体如下:

最近的项目中也要用到一个局部图片放大的功能,前面这篇《silverlight实现图片局部放大效果的方法》虽然已经给出了原理、知识要点、尺寸要点及后端主要代码,但遗憾的是没有给出xaml的代码。这里按照前文中的提示,动手用WPF实践了一下,花了一个小时,终于搞出来了。这篇文章也就算是一个补充吧。

界面如下图所示:

实现的原理和用到的知识点请点击上面的链接,杨大侠已经说的很清楚了。这里主要强调的就是尺寸要点:

右侧大图可视区域与左侧半透明矩形的“长宽比例”应该相同
“图片原始尺寸长度比” 应该 “与左侧小图片长度比”相同
图片原始大小/左侧小图大小 = 右侧可视区域大小/半透明矩形大小

为了简单起见,我们把尺寸固定死(其实是可以搞成活的),这里仅为了演示,以下尺寸满足上面的条件。

准备一张原图:dog.jpg  分辨率:1920 * 1080

左侧小图片显示区域:用Canvas 显示,尺寸:320 * 180

半透明矩形框尺寸:50*50

右侧大图显示区域:用Canvas显示,尺寸:300 * 300

以下是XAML代码:

<Window x:Class="WpfZoom.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="WPF局部放大效果" Height="370" Width="700">
  <Canvas x:Name="RootCanvas">
    <!--左侧小图-->
    <Canvas x:Name="SmallBox" Width="320" Height="180" Canvas.Left="20" Canvas.Top="20">
      <Canvas.Background>
        <ImageBrush ImageSource="Images/dog.jpg" Stretch="UniformToFill" />
      </Canvas.Background>
      <!--半透明矩形框-->
      <Rectangle x:Name="MoveRect" Fill="White" Opacity="0.3" Stroke="Red" Width="50" Height="50" Canvas.Top="78" Canvas.Left="202"
          MouseMove="MoveRect_MouseMove"
          MouseLeftButtonDown="MoveRect_MouseLeftButtonDown"
          MouseLeftButtonUp="MoveRect_MouseLeftButtonUp"/>
    </Canvas>
    <!--右侧大图-->
    <Canvas x:Name="BigBox" Width="300" Height="300" Canvas.Left="360" Canvas.Top="20">
      <!--右侧原图片 注意尺寸-->
      <Image x:Name="bigImg" Width="1920" Height="1080" Canvas.Left="0" Canvas.Top="-780" Source="Images/dog.jpg" />
      <Canvas.Clip>
        <RectangleGeometry Rect="0,0,300,300" />
      </Canvas.Clip>
    </Canvas>
  </Canvas>
</Window>

cs 代码:

using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
namespace WpfZoom
{
  /// <summary>
  /// MainWindow.xaml 的交互逻辑
  /// </summary>
  public partial class MainWindow : Window
  {
    //移动标志
    bool trackingMouseMove = false;
    //鼠标按下去的位置
    Point mousePosition;
    public MainWindow()
    {
      InitializeComponent();
      this.Loaded += new RoutedEventHandler(MainWindow_Loaded);
    }
    void MainWindow_Loaded(object sender, RoutedEventArgs e)
    {
      AdjustBigImage();
    }
    /// <summary>
    /// 半透明矩形框鼠标左键按下
    /// </summary>
    private void MoveRect_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
    {
      FrameworkElement element = sender as FrameworkElement;
      mousePosition = e.GetPosition(element);
      trackingMouseMove = true;
      if (null != element)
      {
        //强制获取此元素
        element.CaptureMouse();
        element.Cursor = Cursors.Hand;
      }
    }
    /// <summary>
    /// 半透明矩形框鼠标左键弹起
    /// </summary>
    private void MoveRect_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
    {
      FrameworkElement element = sender as FrameworkElement;
      trackingMouseMove = false;
      element.ReleaseMouseCapture();
      mousePosition.X = mousePosition.Y = 0;
      element.Cursor = null;
    }
    /// <summary>
    /// 半透明矩形框移动
    /// </summary>
    private void MoveRect_MouseMove(object sender, MouseEventArgs e)
    {
      FrameworkElement element = sender as FrameworkElement;
      if (trackingMouseMove)
      {
        //计算鼠标在X轴的移动距离
        double deltaV = e.GetPosition(element).Y - mousePosition.Y;
        //计算鼠标在Y轴的移动距离
        double deltaH = e.GetPosition(element).X - mousePosition.X;
        //得到图片Top新位置
        double newTop = deltaV + (double)element.GetValue(Canvas.TopProperty);
        //得到图片Left新位置
        double newLeft = deltaH + (double)element.GetValue(Canvas.LeftProperty);
        //边界的判断
        if (newLeft <= 0)
        {
          newLeft = 0;
        }
        //左侧图片框宽度 - 半透明矩形框宽度
        if (newLeft >= (this.SmallBox.Width - this.MoveRect.Width))
        {
          newLeft = this.SmallBox.Width - this.MoveRect.Width;
        }
        if (newTop <= 0)
        {
          newTop = 0;
        }
        //左侧图片框高度度 - 半透明矩形框高度度
        if (newTop >= this.SmallBox.Height - this.MoveRect.Height)
        {
          newTop = this.SmallBox.Height - this.MoveRect.Height;
        }
        element.SetValue(Canvas.TopProperty, newTop);
        element.SetValue(Canvas.LeftProperty, newLeft);
        AdjustBigImage();
        if (mousePosition.X <= 0 || mousePosition.Y <= 0) { return; }
      }
    }
    /// <summary>
    /// 调整右侧大图的位置
    /// </summary>
    void AdjustBigImage()
    {
      //获取右侧大图框与透明矩形框的尺寸比率
      double n = this.BigBox.Width / this.MoveRect.Width;
      //获取半透明矩形框在左侧小图中的位置
      double left = (double)this.MoveRect.GetValue(Canvas.LeftProperty);
      double top = (double)this.MoveRect.GetValue(Canvas.TopProperty);
      //计算和设置原图在右侧大图框中的Canvas.Left 和 Canvas.Top
      double newLeft = -left * n;
      double newTop = -top * n;
      bigImg.SetValue(Canvas.LeftProperty, newLeft);
      bigImg.SetValue(Canvas.TopProperty, newTop);
    }
  }
}

附:完整实例代码点击此处本站下载

PS:这里再为大家推荐几款比较实用的图片处理工具供大家参考使用:

在线图片转换BASE64工具:
http://tools.jb51.net/transcoding/img2base64

ICO图标在线生成工具:
http://tools.jb51.net/aideddesign/ico_img

在线Email邮箱图标制作工具:
http://tools.jb51.net/email/emaillogo

在线图片格式转换(jpg/bmp/gif/png)工具:
http://tools.jb51.net/aideddesign/picext

更多相关内容感兴趣的读者可查看本站专题:《C#图片操作技巧汇总》、《C#常见控件用法教程》、《WinForm控件用法总结》、《C#数据结构与算法教程》、《C#面向对象程序设计入门教程》及《C#程序设计之线程使用技巧总结

希望本文所述对大家C#程序设计有所帮助。

相关文章

  • WPF调用ffmpeg实现屏幕录制

    WPF调用ffmpeg实现屏幕录制

    这篇文章主要为大家详细介绍了WPF如何调用ffmpeg实现屏幕录制,文中的示例代码讲解详细,对我们学习或工作有一定帮助,感兴趣的小伙伴可以了解一下
    2023-05-05
  • C#结束进程及子进程

    C#结束进程及子进程

    这篇文章介绍了C#操作结束进程及子进程的方法,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-06-06
  • 分享一个C#编写简单的聊天程序(详细介绍)

    分享一个C#编写简单的聊天程序(详细介绍)

    这是一篇基于Socket进行网络编程的入门文章,我对于网络编程的学习并不够深入,这篇文章是对于自己知识的一个巩固,同时希望能为初学的朋友提供一点参考。文章大体分为四个部分:程序的分析与设计、C#网络编程基础(篇外篇)、聊天程序的实现模式、程序实现
    2015-12-12
  • 浅谈c#开发者应该了解的15个特性

    浅谈c#开发者应该了解的15个特性

    本文列举了15个值得了解的C#特性,旨在让.NET开发人员更好的使用C#语言进行开发工作。
    2021-05-05
  • UnityShader使用速度映射图实现运动模糊

    UnityShader使用速度映射图实现运动模糊

    这篇文章主要为大家详细介绍了UnityShader使用速度映射图实现运动模糊,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-02-02
  • 利用lambda表达式树优化反射详解

    利用lambda表达式树优化反射详解

    这篇文章主要给大家介绍了关于如何利用lambda表达式树优化反射的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2018-12-12
  • C#中多线程更新UI控件的常用方案

    C#中多线程更新UI控件的常用方案

    在C#中,特别是在使用Windows窗体(WinForms)或WPF(Windows Presentation Foundation)进行UI开发时,处理多线程与UI控件的交互需要特别小心,本文给大家介绍了几种在C#中安全地从多线程更新UI控件的常用方案,需要的朋友可以参考下
    2024-07-07
  • 解析C# 程序结构

    解析C# 程序结构

    在我们学习 C# 编程语言的基础构件块之前,让我们先看一下 C# 的最小的程序结构,以便作为接下来章节的参考
    2021-07-07
  • c#中winform根据邮箱地址和密码一键发送email的实现

    c#中winform根据邮箱地址和密码一键发送email的实现

    本文主要介绍了c#winform根据邮箱地址和密码一键发送email的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-07-07
  • C#使用throw和throw ex抛出异常的区别介绍

    C#使用throw和throw ex抛出异常的区别介绍

    这篇文章介绍了C#使用throw和throw ex抛出异常的区别,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-10-10

最新评论