wpf圖片查看器,支持鼠標滾動縮放拖拽

最近項目須要,要用到一個圖片查看器,相似於windows自帶的圖片查看器那樣,鼠標滾動能夠縮放,能夠拖拽圖片,因而就寫了這個簡單的圖片查看器。html

前臺代碼:windows

<Window x:Class="PictureViewer.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="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爲垂直方向的偏移量)。this

  另經過一個ContentControl控件擺放圖片控件,併爲控件綁定各類事件(鼠標點下、擡起、拖動、滾動),圖片控件的RenderOptions.BitmapscalingMode="NearestNeighbor"屬性用於優化圖片變換過程,防止出現圖片移動或縮放模糊。spa

後臺代碼:rest

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處理拖拽進來以後的事情code

 

源碼:http://files.cnblogs.com/files/huangli321456/PictureViewer.ziporm

 

代碼參照:http://www.cnblogs.com/snake-hand/archive/2012/08/13/2636227.htmlxml

相關文章
相關標籤/搜索