你的位置:首页 > ASP.net教程

[ASP.net教程]wpf图片查看器,支持鼠标滚动缩放拖拽


最近项目需要,要用到一个图片查看器,类似于windows自带的图片查看器那样,鼠标滚动可以缩放,可以拖拽图片,于是就写了这个简单的图片查看器。

前台代码:

<Window x:Class="PictureViewer.MainWindow"    ="http://schemas.microsoft.com/winfx/2006/xaml/presentation"    ="http://schemas.microsoft.com/winfx/2006/xaml"    AllowDrop="True"     Title="图片查看器" Height="350" Width="525" Loaded="Window_Loaded"    SizeChanged="Window_SizeChanged" DragEnter="Window_DragEnter" Drop="Window_Drop">  <Grid x:Name="mainGrid">    <Grid.Resources>      <TransformGroup x:Key="TfGroup">        <ScaleTransform ScaleX="1" ScaleY="1"/>        <TranslateTransform X="0" Y="0"/>      </TransformGroup>    </Grid.Resources>    <Grid.RowDefinitions>      <RowDefinition Height="50"></RowDefinition>      <RowDefinition Height="*"></RowDefinition>    </Grid.RowDefinitions>        <Button Grid.Row="0" Width="50" Height="30" Cursor="Hand" Background="Transparent" BorderThickness="0" Content="打开图片" Click="OpenImg_Click" x:Name="OpenImg" HorizontalAlignment="Left" VerticalAlignment="Center" Margin="20,0,0,0"/>    <Label Content="缩放倍数:" HorizontalAlignment="Left" VerticalAlignment="Center" Margin="130,0,0,0"/>    <TextBox x:Name="txtMinSize" Width="40" Height="30" VerticalContentAlignment="Center" HorizontalAlignment="Left" VerticalAlignment="Center" Margin="200,0,0,0" TextChanged="txtMinSize_TextChanged" Text="0.1"/>    <Label Content="--" HorizontalAlignment="Left" VerticalAlignment="Center" Margin="240,0,0,0"/>    <TextBox x:Name="txtMaxSize" Width="40" Height="30" VerticalContentAlignment="Center" HorizontalAlignment="Left" VerticalAlignment="Center" Margin="260,0,0,0" TextChanged="txtMaxSize_TextChanged" Text="3"/>    <ScrollViewer x:Name="mainScrollv" HorizontalAlignment="Center" VerticalAlignment="Center" HorizontalScrollBarVisibility="Disabled"           VerticalScrollBarVisibility="Disabled" Cursor="SizeAll" Margin="0" Focusable="False" Grid.Row="1">      <ContentControl MouseLeftButtonDown="ContentControl_MouseLeftButtonDown"              MouseLeftButtonUp="ContentControl_MouseLeftButtonUp"              MouseMove="ContentControl_MouseMove"              MouseWheel="ContentControl_MouseWheel"              HorizontalAlignment="Center" VerticalAlignment="Center">        <Image x:Name="IMG" Margin="0" RenderTransform="{StaticResource TfGroup}" RenderOptions.BitmapScalingMode="NearestNeighbor"/>              </ContentControl>          </ScrollViewer>  </Grid></Window>

 

代码解析:

  通过一个定义一个TransformGroup,通过Key绑定到图片控件中,并且里面使用ScaleTransform实现缩放(scaleX是水平方向的缩放倍数,现默认为1倍,即无缩放,scaleY同理),TranslateTransform实现平移(鼠标拖动,X为水平方向的偏移量,Y为垂直方向的偏移量)。

  另通过一个ContentControl控件摆放图片控件,并为控件绑定各种事件(鼠标点下、抬起、拖动、滚动),图片控件的RenderOptions.BitmapscalingMode="NearestNeighbor"属性用于优化图片变换过程,防止出现图片移动或缩放模糊。

后台代码:

using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Windows;using System.Windows.Controls;using System.Windows.Data;using System.Windows.Documents;using System.Windows.Input;using System.Windows.Media;using System.Windows.Media.Imaging;using System.Windows.Navigation;using System.Windows.Shapes;namespace PictureViewer{  /// <summary>  /// MainWindow.xaml 的交互逻辑  /// </summary>  public partial class MainWindow : Window  {    public MainWindow()    {      InitializeComponent();    }    private bool mouseDown;    private Point mouseXY;    private double min = 0.1, max = 3.0;//最小/最大放大倍数    private void Domousemove(ContentControl img, MouseEventArgs e)    {      if (e.LeftButton != MouseButtonState.Pressed)      {        return;      }      var group = IMG.FindResource("TfGroup") as TransformGroup;      var transform = group.Children[1] as TranslateTransform;      var position = e.GetPosition(img);      transform.X -= mouseXY.X - position.X;      transform.Y -= mouseXY.Y - position.Y;      mouseXY = position;    }    private void DowheelZoom(TransformGroup group, Point point, double delta)    {      var pointToContent = group.Inverse.Transform(point);      var transform = group.Children[0] as ScaleTransform;      if (transform.ScaleX + delta < min) return;      if (transform.ScaleX + delta > max) return;      transform.ScaleX += delta;      transform.ScaleY += delta;      var transform1 = group.Children[1] as TranslateTransform;      transform1.X = -1 * ((pointToContent.X * transform.ScaleX) - point.X);      transform1.Y = -1 * ((pointToContent.Y * transform.ScaleY) - point.Y);    }    private void ContentControl_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)    {      var img = sender as ContentControl;      if (img == null)      {        return;      }      img.CaptureMouse();      mouseDown = true;      mouseXY = e.GetPosition(img);    }    private void ContentControl_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)    {      var img = sender as ContentControl;      if (img == null)      {        return;      }      img.ReleaseMouseCapture();      mouseDown = false;    }    private void ContentControl_MouseMove(object sender, MouseEventArgs e)    {      var img = sender as ContentControl;      if (img == null)      {        return;      }      if (mouseDown)      {        Domousemove(img, e);      }    }    private void ContentControl_MouseWheel(object sender, MouseWheelEventArgs e)    {      var img = sender as ContentControl;      if (img == null)      {        return;      }      var point = e.GetPosition(img);      var group = IMG.FindResource("TfGroup") as TransformGroup;      var delta = e.Delta * 0.001;      DowheelZoom(group, point, delta);    }    private void OpenImg_Click(object sender, RoutedEventArgs e)    {      // 在WPF中, OpenFileDialog位于Microsoft.Win32名称空间            Microsoft.Win32.OpenFileDialog dialog = new Microsoft.Win32.OpenFileDialog();      dialog.Filter = "Files (*.png)|*.png|Files(*.jpg)|*.jpg";      if (dialog.ShowDialog() == true)      {        //MessageBox.Show(dialog.FileName);        this.IMG.Source = new BitmapImage(new Uri(dialog.FileName));      }    }    private void Window_Loaded(object sender, RoutedEventArgs e)    {      setViewSize();    }    private void setViewSize()    {      mainScrollv.Width = this.ActualWidth;      mainScrollv.Height = this.ActualHeight - 50;    }    private void Window_SizeChanged(object sender, SizeChangedEventArgs e)    {      setViewSize();    }    private void txtMinSize_TextChanged(object sender, TextChangedEventArgs e)    {      this.min = double.Parse(txtMinSize.Text);    }    private void txtMaxSize_TextChanged(object sender, TextChangedEventArgs e)    {      this.max = double.Parse(txtMaxSize.Text);    }    private void Window_DragEnter(object sender, DragEventArgs e)    {      if (e.Data.GetDataPresent(DataFormats.FileDrop))        e.Effects = DragDropEffects.Link;//WinForm中为e.Effect = DragDropEffects.Link      else e.Effects = DragDropEffects.None;//WinFrom中为e.Effect = DragDropEffects.None    }    private void Window_Drop(object sender, DragEventArgs e)    {      string filename = ((System.Array)e.Data.GetData(DataFormats.FileDrop)).GetValue(0).ToString();      this.IMG.Source = new BitmapImage(new Uri(filename));    }  }}

 

可将图片拖拽到窗口打开,Window_DragEnter里验证拖拽进来的文件是否可用,Window_Drop处理拖拽进来之后的事情

 

源码:http://files.cnblogs.com/files/huangli321456/PictureViewer.zip

 

代码参照:http://www.cnblogs.com/snake-hand/archive/2012/08/13/2636227.html