2021-07-12

C#、WPF图片查看器

项目中需要用到图片查看器功能,记录一下自己的WPF实现,支持鼠标拖动、滑轮放大缩小和改变窗体大小。因为本文代码是整个工程中的一部分,有些变量没有删除。

1、界面

在这里插入图片描述

界面非常的简单,只有六个按键:

  1. 打开图片:选择自己想要预览的图片,支持多选。
  2. 还原:将图片还原回最初状态。
  3. 放大:本设计有所不同,这里是以上次鼠标点击位置为中心进行放大。
  4. 缩小:同上。
  5. 上一张、下一张:支持循环浏览图片。

下载链接:https://download.csdn.net/download/qq_44845723/20212511.

2、代码部分

2.1、MainWindow.xaml

<Window x:Class="WpfApplication2.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfApplication2"
        mc:Ignorable="d"
       Title="图片查看器" Height="600" Width="1000" 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>
            <!--按钮样式-->
            <Style x:Key="ImageToolBtn" TargetType="{x:Type Button}">
                <Setter Property="FocusVisualStyle" Value="{x:Null}"/>
                <Setter Property="BorderThickness" Value="1"/>
                <Setter Property="Foreground" Value="White"/>
                <Setter Property="HorizontalContentAlignment" Value="Center"/>
                <Setter Property="VerticalContentAlignment" Value="Center"/>
                <Setter Property="Padding" Value="1"/>
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="{x:Type Button}">
                            <Border x:Name="Chrome" BorderBrush="Transparent" Background="Transparent" SnapsToDevicePixels="true">
                                <ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
                            </Border>
                            <ControlTemplate.Triggers>
                                <Trigger Property="IsMouseOver" Value="true">
                                    <Setter Property="Foreground" Value="#FF288ADD"/>
                                </Trigger>
                                <Trigger Property="IsPressed" Value="true">
                                    <Setter Property="Foreground" Value="White"/>
                                </Trigger>
                                <Trigger Property="IsEnabled" Value="false">
                                    <Setter Property="Foreground" Value="#ADADAD"/>
                                </Trigger>
                            </ControlTemplate.Triggers>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Style>

        </Grid.Resources>
        <!--分割页面-->
        <Grid.RowDefinitions>
            <RowDefinition Height="*"></RowDefinition>
            <RowDefinition Height="50"></RowDefinition>
        </Grid.RowDefinitions>

        <!--上侧显示区-->
        <ScrollViewer x:Name="mainScrollv" HorizontalAlignment="Center" VerticalAlignment="Center" HorizontalScrollBarVisibility="Disabled"
                      VerticalScrollBarVisibility="Disabled" Cursor="SizeAll" Margin="0" Focusable="False" Grid.Row="0">
            <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>

        <!--按钮项-->
        <Border x:Name="border" BorderThickness="0" Margin="0,0,0,0" VerticalAlignment="Bottom" HorizontalAlignment="Center"  Background="White" Grid.Row="1">
            <StackPanel HorizontalAlignment="Center" VerticalAlignment="Bottom" Height="46" Orientation="Horizontal" Margin="0">
                <Button x:Name="btnOpenFiles"  Click="btnOpenFiles_Click" Width="50" Height="30"  Content="打开图片" Margin="10,0,0,10"  Cursor="Hand" Background="Transparent" BorderThickness="0"/>
                <Button x:Name="btnActualsize" Click="btnActualsize_Click"  Width="50" Height="30"  Content="还原" Margin="10,0,0,10"  Cursor="Hand" Background="Transparent" BorderThickness="0"/>
                <Button x:Name="btnEnlarge" Click="btnEnlarge_Click"  Width="50" Height="30"  Content="放大" Margin="10,0,0,10"  Cursor="Hand" Background="Transparent" BorderThickness="0"/>
                <Button x:Name="btnNarrow" Click="btnNarrow_Click"  Width="50" Height="30"  Content="缩小" Margin="10,0,0,10"  Cursor="Hand" Background="Transparent" BorderThickness="0"/>
                <Button x:Name="btnUpImg" Click="btnUpImg_Click"  Width="50" Height="30"  Content="上一张" Margin="10,0,0,10"  Cursor="Hand" Background="Transparent" BorderThickness="0"/>
                <Button x:Name="btnDownImg" Click="btnDownImg_Click"  Width="50" Height="30"  Content="下一张" Margin="10,0,0,10"  Cursor="Hand" Background="Transparent" BorderThickness="0"/>

            </StackPanel>
        </Border>
    </Grid>
</Window>

2.2、MainWindow.xaml.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
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;
using System.IO;



namespace WpfApplication2
{
    /// <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;//最小/最大放大倍数

        List<string> fileNames = new List<string>();
        int nowShowImgNumber = 0; //当前显示的是第几张图片

        double translateX = 0; //图片在 x y 方向上的移动距离
        double translateY = 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; translateX += transform.X;
            transform.Y -= mouseXY.Y - position.Y; translateY += transform.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); translateX += transform1.X;
            transform1.Y = -1 * ((pointToContent.Y * transform.ScaleY) - point.Y); translateY += transform1.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);  //获得鼠标在控件中的位置
            mouseXY = point; //鼠标当前位置
            var group = IMG.FindResource("TfGroup") as TransformGroup;
            var delta = e.Delta * 0.001; //放大倍数
            DowheelZoom(group, point, delta);
        }

        //打开文件,选择要读取的文件
        private void btnOpenFiles_Click(object sender, RoutedEventArgs e)
        {
            // 在WPF中, OpenFileDialog位于Microsoft.Win32名称空间            
            Microsoft.Win32.OpenFileDialog dialog = new Microsoft.Win32.OpenFileDialog();
            dialog.Multiselect = true;//可以选择多个选项
            dialog.Title = "选择图片";
            dialog.Filter = "jpg文件(*.jpg)|*.jpg|png文件 (*.png)|*.png|全部(*.all)|*.*";
            if (dialog.ShowDialog() == true)
            {
                //MessageBox.Show(dialog.FileName);
                fileNames.RemoveRange(0, fileNames.Count());
                foreach (string name in dialog.FileNames)
                {
                    fileNames.Add(name);
                }
                nowShowImgNumber = 0; //显示第一张图片

                this.IMG.Source = new BitmapImage(new Uri(fileNames[0]));
                RestoreImgShowRuler(); RestoreImgShowRuler();

            }
        }

        //将图像显示尺寸还原为 1:1,原图大小
        private void RestoreImgShowRuler()
        {
            var group = IMG.FindResource("TfGroup") as TransformGroup;
            var transform = group.Children[0] as ScaleTransform; // 首先研究缩放
            transform.ScaleX = 1;
            transform.ScaleY = 1;

            var translate = group.Children[1] as TranslateTransform;
            translate.X = -translateX;
            translate.Y = -translateY;

            translateX = 0;
            translateY = 0;

            mouseXY.X = 0;
            mouseXY.Y = 0;
        }

        //将图片尺寸还原为 1:1
        private void btnActualsize_Click(object sender, RoutedEventArgs e)
        {
            var img = sender as ContentControl;
            if (img == null) //当前没有图片
            {
                return;
            }
            RestoreImgShowRuler(); RestoreImgShowRuler();
        }

        //图片放大按钮
        private void btnEnlarge_Click(object sender, RoutedEventArgs e)
        {

            var img = sender as ContentControl;
            if (img == null) //当前没有图片
            {
                return;
            }
            var group = IMG.FindResource("TfGroup") as TransformGroup;
            DowheelZoom(group, mouseXY, 0.1);

        }

        //图片缩小按钮
        private void btnNarrow_Click(object sender, RoutedEventArgs e)
        {
            var img = sender as ContentControl;
            if (img == null) //当前没有图片
            {
                return;
            }
            var group = IMG.FindResource("TfGroup") as TransformGroup;
            DowheelZoom(group, mouseXY, -0.1);
        }

        //上一张图片
        private void btnUpImg_Click(object sender, RoutedEventArgs e)
        {
            int imgNumber = fileNames.Count();
            if (imgNumber == 0)
            {
                MessageBox.Show("没有选择任何图片!");
            }
            else //图片数量不为 0 
            {
                if ((double)nowShowImgNumber / imgNumber > 0)
                {
                    nowShowImgNumber--;
                }
                else
                {
                    nowShowImgNumber = imgNumber - 1;
                }

                this.IMG.Source = new BitmapImage(new Uri(fileNames[nowShowImgNumber]));

                RestoreImgShowRuler(); RestoreImgShowRuler();

            }
        }

        //下一张图片
        private void btnDownImg_Click(object sender, RoutedEventArgs e)
        {
            int imgNumber = fileNames.Count();
            if (imgNumber == 0)
            {
                MessageBox.Show("没有选择任何图片!");
            }
            else
            {
                if (imgNumber > 1)
                {

                    if ((double)nowShowImgNumber / (imgNumber - 1) == 1)
                    {
                        nowShowImgNumber = 0;
                    }
                    else
                    {
                        nowShowImgNumber++;
                    }
                }
                else
                {
                    nowShowImgNumber = 0;
                }

                this.IMG.Source = new BitmapImage(new Uri(fileNames[nowShowImgNumber]));

                RestoreImgShowRuler(); RestoreImgShowRuler();

            }
        }
        //窗口加载,设置显示区窗口的尺寸
        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();
        }

        //直接拖动文件到窗口,相当于 ButtonDown
        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

        }

        //拖动文件到窗口松开按键,相当于ButtonUp
        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));
        }

       

    }
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值