zoukankan      html  css  js  c++  java
  • wpf图片查看器,支持鼠标滚动缩放拖拽

    最近项目需要,要用到一个图片查看器,类似于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为垂直方向的偏移量)。

      另通过一个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处理拖拽进来之后的事情

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

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

  • 相关阅读:
    [poj_3469]多核CPU
    割点与桥,强连通分量,点双,边双[poj_1236]学校网络
    Iview 启动报错 TypeError [ERR_INVALID_CALLBACK]: Callback must be a function
    修改JAVA_HOME失效
    命令模式
    gradle implementation runtimeOnly 和api 区别
    spring boot 整合 RabbitMQ 错误
    关于技术的想法
    eclipse 背景绿豆沙颜色
    抽象工厂模式
  • 原文地址:https://www.cnblogs.com/huangli321456/p/5113554.html
Copyright © 2011-2022 走看看