欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

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

程序员文章站 2023-11-22 13:53:16
本文实例讲述了wpf/silverlight实现图片局部放大的方法。分享给大家供大家参考,具体如下: 最近的项目中也要用到一个局部图片放大的功能,前面这篇《》虽然已经给出...

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

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

界面如下图所示:

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

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

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

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

准备一张原图: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工具:

ico图标在线生成工具:

在线email邮箱图标制作工具:

在线图片格式转换(jpg/bmp/gif/png)工具:

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

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