WPF图片查看器

Posted redsky

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了WPF图片查看器相关的知识,希望对你有一定的参考价值。

一、功能需求:

1、打开图片、打开文件夹;

2、下一张、上一张图片;

3、支持拖动、缩放、还原图片显示适当大小;

cs部分代码

技术分享图片
  1     /// <summary>
  2     /// Interaction logic for ImageView.xaml
  3     /// </summary>
  4     public partial class ImageView : UserControl
  5     {
  6         public ImageView()
  7         {
  8             InitializeComponent();
  9         }
 10 
 11 
 12         bool mouseDown = false;
 13         Point prePo;
 14         private void Img_MouseDown(object sender, MouseButtonEventArgs e)
 15         {
 16             mouseDown = true;
 17             Cursor = Cursors.Hand;
 18             prePo = e.GetPosition(canvas);
 19         }
 20 
 21 
 22         /// <summary>
 23         /// 移动图片
 24         /// </summary>
 25         /// <param name="sender"></param>
 26         /// <param name="e"></param>
 27         private void Img_PreviewMouseMove(object sender, MouseEventArgs e)
 28         {
 29             Point currentPoint = e.GetPosition(canvas);
 30             if (mouseDown)
 31             {
 32                 double left = Canvas.GetLeft(img);
 33                 double top = Canvas.GetTop(img);
 34                 if (currentPoint.X != prePo.X)
 35                     Canvas.SetLeft(img, left + currentPoint.X - prePo.X);
 36                 if (currentPoint.Y != prePo.Y)
 37                     Canvas.SetTop(img, top + currentPoint.Y - prePo.Y);
 38                 prePo = currentPoint;
 39             }
 40         }
 41 
 42         private void Img_MouseUp(object sender, MouseButtonEventArgs e)
 43         {
 44             mouseDown = false;
 45             Cursor = Cursors.Arrow;
 46         }
 47         
 48         double scale = 1;
 49         /// <summary>
 50         /// 放大、缩小图片
 51         /// </summary>
 52         /// <param name="sender"></param>
 53         /// <param name="e"></param>
 54         private void Img_PreviewMouseWheel(object sender, MouseWheelEventArgs e)
 55         {
 56             double left = Canvas.GetLeft(img);
 57             double top = Canvas.GetTop(img);
 58             double preW = img.ActualWidth;
 59             double preH = img.ActualHeight;
 60 
 61             if (e.Delta > 0)
 62                 scale = scale + 0.01;
 63             else
 64                 scale = scale - 0.01;
 65             if (scale <= 0.01)
 66                 scale = 0.01;
 67             img.RenderTransform = new ScaleTransform(scale, scale);
 68         }
 69 
 70         /// <summary>
 71         /// 图片自适应显示
 72         /// </summary>
 73         /// <param name="sender"></param>
 74         /// <param name="e"></param>
 75         private void BtnDefault_Click(object sender, RoutedEventArgs e)
 76         {
 77             scale = 1;
 78             img.RenderTransform = new ScaleTransform(1, 1);
 79             InitImage();
 80         }
 81 
 82         /// <summary>
 83         /// 还原图片居中缩放适合尺寸显示
 84         /// 当图片宽(高)大于高(宽)时,如果图片宽(高)超过显示区域宽(高)则进行缩放
 85         /// 然后垂直水平居中
 86         /// </summary>
 87         void InitImage()
 88         {
 89             double areaH = canvas.ActualHeight;
 90             double areaW = canvas.ActualWidth;
 91             if (img.Width == 0) return;
 92             if(img.Width > img.Height)
 93             {
 94                 if (img.Width > areaW)
 95                 {
 96                     double scale = areaW / img.Width;
 97                     //img.RenderTransform = new ScaleTransform(scale, scale);
 98                     double scaleH = img.Height * scale;
 99                     Canvas.SetTop(img, (areaH - scaleH) / 2);
100                     Canvas.SetLeft(img, 0);
101                     img.Width = img.Width * scale;
102                     img.Height = scaleH;
103                     return;
104                 }
105                 Canvas.SetTop(img, (areaH - img.Height) / 2);
106                 Canvas.SetLeft(img, (areaW - img.Width) / 2);
107             }
108             else
109             {
110                 if (img.Height > areaH)
111                 {
112                     double scale = areaH / img.Height;
113                     //img.RenderTransform = new ScaleTransform(scale, scale);
114                     double scaleW = img.Width * scale;
115                     Canvas.SetTop(img, 0);
116                     Canvas.SetLeft(img, (areaW - scaleW) / 2);
117                     img.Width = scaleW;
118                     img.Height = img.Height * scale;
119                     return;
120                 }
121                 Canvas.SetTop(img, (areaH - img.Height) / 2);
122                 Canvas.SetLeft(img, (areaW - img.Width) / 2);
123             }
124         }
125 
126         /// <summary>
127         /// 上一张
128         /// </summary>
129         /// <param name="sender"></param>
130         /// <param name="e"></param>
131         private void BtnPreview_Click(object sender, RoutedEventArgs e)
132         {
133             if (images.Count <= 0) return;
134             index = --index < 0 ? images.Count - 1 : index;
135             ChangeSelect(index);
136         }
137 
138         /// <summary>
139         /// 下一张
140         /// </summary>
141         /// <param name="sender"></param>
142         /// <param name="e"></param>
143         private void BtnNext_Click(object sender, RoutedEventArgs e)
144         {
145             if (images.Count <= 0) return;
146             index = ++index >= images.Count ? 0 : index;
147             ChangeSelect(index);
148         }
149 
150         /// <summary>
151         /// 打开图片
152         /// </summary>
153         /// <param name="sender"></param>
154         /// <param name="e"></param>
155         private void BtnImage_Click(object sender, RoutedEventArgs e)
156         {
157             System.Windows.Forms.OpenFileDialog fileDialog = new System.Windows.Forms.OpenFileDialog();
158             fileDialog.Title = "请选择图片文件";
159             fileDialog.Filter = filter;
160             fileDialog.RestoreDirectory = true;
161             if(fileDialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
162             {
163                 tbNotice.Visibility = Visibility.Collapsed;
164                 if (fileDialog.FileNames.Length > 1)
165                     LoadImages(fileDialog.FileNames);
166                 else
167                     LoadFolder(System.IO.Path.GetDirectoryName(fileDialog.FileName), fileDialog.FileName);
168             }
169         }
170 
171         int index = 0;
172         string folder = null;
173         List<string> images = new List<string>();
174         string filter = "图像文件|*.png;*.jpg;*.jpeg;*.bmp";
175         /// <summary>
176         /// 打开文件夹
177         /// </summary>
178         /// <param name="sender"></param>
179         /// <param name="e"></param>
180         private void BtnFolder_Click(object sender, RoutedEventArgs e)
181         {
182             System.Windows.Forms.FolderBrowserDialog folderBrowser = new System.Windows.Forms.FolderBrowserDialog();
183             folderBrowser.Description = "请选择图片目录";
184             if (folderBrowser.ShowDialog() == System.Windows.Forms.DialogResult.OK)
185             {
186                 tbNotice.Visibility = Visibility.Collapsed;
187                 folder = folderBrowser.SelectedPath;
188                 LoadFolder(folder);
189             }
190         }
191 
192         /// <summary>
193         /// 切换当前图片
194         /// </summary>
195         /// <param name="select"></param>
196         void ChangeSelect(int select)
197         {
198             if (select < 0 || images.Count < 1)
199                 return;
200             if (select >= images.Count)
201                 select = images.Count - 1;
202 
203             string file = images[select];
204             ChangeSelect(file);
205         }
206 
207         /// <summary>
208         /// 切换当前图片
209         /// </summary>
210         /// <param name="select"></param>
211         void ChangeSelect(string select)
212         {
213             tbName.Text = System.IO.Path.GetFileName(select);
214             if (!File.Exists(select))
215             {
216                 int i = images.IndexOf(select);
217                 images.Remove(select);
218                 MessageBox.Show("图片丢失");
219                 if (images.Count <= 0)
220                     tbNotice.Visibility = Visibility.Visible;
221                 else
222                     ChangeSelect(i);
223                 return;
224             }
225             BitmapImage bitmap = new BitmapImage(new Uri(select));
226             img.Source = bitmap;
227             img.Width = bitmap.PixelWidth;
228             img.Height = bitmap.Height;
229             InitImage();
230         }
231 
232         /// <summary>
233         /// 加载文件到集合中
234         /// </summary>
235         /// <param name="files"></param>
236         void LoadImages(string[] files)
237         {
238             images.Clear();
239             images.AddRange(files);
240             index = 0;
241             ChangeSelect(index);
242         }
243 
244         /// <summary>
245         /// 加载目录图片到集合中
246         /// </summary>
247         /// <param name="folder"></param>
248         /// <param name="select"></param>
249         void LoadFolder(string folder, string select = null)
250         {
251             images.Clear();
252             string[] files = Directory.GetFiles(folder);
253             if (files == null)
254                 return;
255             foreach (var item in files)
256             {
257                 if (filter.Contains(System.IO.Path.GetExtension(item.ToLowerInvariant())))
258                     images.Add(item);
259             }
260             index = 0;
261             ChangeSelect(select ?? images[0]);
262         }
263     }
View Code

xaml部分代码:

<UserControl x:Class="MahAppsMetro.Demo.Views.ImageView"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:MahAppsMetro.Demo.Views"
             mc:Ignorable="d" 
             d:DesignHeight="450" d:DesignWidth="800">
    <Grid>
        <Canvas x:Name="canvas" Background="Beige">
            <Image x:Name="img" Canvas.Top="0" Canvas.Left="0"
               MouseDown="Img_MouseDown" PreviewMouseMove="Img_PreviewMouseMove" MouseUp="Img_MouseUp" PreviewMouseWheel="Img_PreviewMouseWheel" />
        </Canvas>
        <TextBlock x:Name="tbNotice" Text="请选择图片" VerticalAlignment="Center" HorizontalAlignment="Center" />
        <TextBlock x:Name="tbName" HorizontalAlignment="Center" Margin="20" />
        <WrapPanel HorizontalAlignment="Center" VerticalAlignment="Bottom" Margin="20">
            <Button x:Name="btnImage" Content="打开" Width="40" Height="20" VerticalAlignment="Bottom" Background="Transparent" BorderThickness="1"
                Click="BtnImage_Click" />
            <Button x:Name="btnFolder" Content="文件夹" Width="40" Height="20" VerticalAlignment="Bottom" Background="Transparent" BorderThickness="1"
                Click="BtnFolder_Click"/>
            <Button x:Name="btnPreview" Content="上一张" Width="40" Height="20" VerticalAlignment="Bottom" Background="Transparent" BorderThickness="1"
                Click="BtnPreview_Click" />
            <Button x:Name="btnDefault" Content="适应" Width="40" Height="20" VerticalAlignment="Bottom" Background="Transparent" BorderThickness="1"
                Click="BtnDefault_Click" Canvas.Left="378" Canvas.Bottom="20"/>
            <Button x:Name="btnNext" Content="下一张" Width="40" Height="20" VerticalAlignment="Bottom" Background="Transparent" BorderThickness="1"
                Click="BtnNext_Click" />
        </WrapPanel>
    </Grid>
</UserControl>

效果:

技术分享图片

待解决问题:拖动后释放鼠标有时没有释放状态

以上是关于WPF图片查看器的主要内容,如果未能解决你的问题,请参考以下文章

如何实现 WPF 代码查看器控件

持久片段和查看器

鼠标滚动在带有 wpf 数据网格和其他 UI 元素的滚动查看器中不起作用

片段中的Android选择器意图到图片照片

WPF实用小工具

如何将图片从资源管理器拖放到 WPF 控件上?