WPF图片查看器
一、功能需求:
1、打开图片、打开文件夹;
2、下一张、上一张图片;
3、支持拖动、缩放、还原图片显示适当大小;
cs部分代码
查看代码
/// <summary>
/// Interaction logic for ImageView.xaml
/// </summary>
public partial class ImageView : UserControl
{
public ImageView()
{
InitializeComponent();
}
bool mouseDown = false;
Point prePo;
private void Img_MouseDown(object sender, MouseButtonEventArgs e)
{
mouseDown = true;
Cursor = Cursors.Hand;
prePo = e.GetPosition(canvas);
}
/// <summary>
/// 移动图片
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void Img_PreviewMouseMove(object sender, MouseEventArgs e)
{
Point currentPoint = e.GetPosition(canvas);
if (mouseDown)
{
double left = Canvas.GetLeft(img);
double top = Canvas.GetTop(img);
if (currentPoint.X != prePo.X)
Canvas.SetLeft(img, left + currentPoint.X - prePo.X);
if (currentPoint.Y != prePo.Y)
Canvas.SetTop(img, top + currentPoint.Y - prePo.Y);
prePo = currentPoint;
}
}
private void Img_MouseUp(object sender, MouseButtonEventArgs e)
{
mouseDown = false;
Cursor = Cursors.Arrow;
}
double scale = 1;
/// <summary>
/// 放大、缩小图片
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void Img_PreviewMouseWheel(object sender, MouseWheelEventArgs e)
{
double left = Canvas.GetLeft(img);
double top = Canvas.GetTop(img);
double preW = img.ActualWidth;
double preH = img.ActualHeight;
if (e.Delta > 0)
scale = scale + 0.01;
else
scale = scale - 0.01;
if (scale <= 0.01)
scale = 0.01;
img.RenderTransform = new ScaleTransform(scale, scale);
}
/// <summary>
/// 图片自适应显示
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void BtnDefault_Click(object sender, RoutedEventArgs e)
{
scale = 1;
img.RenderTransform = new ScaleTransform(1, 1);
InitImage();
}
/// <summary>
/// 还原图片居中缩放适合尺寸显示
/// 当图片宽(高)大于高(宽)时,如果图片宽(高)超过显示区域宽(高)则进行缩放
/// 然后垂直水平居中
/// </summary>
void InitImage()
{
double areaH = canvas.ActualHeight;
double areaW = canvas.ActualWidth;
if (img.Width == 0) return;
if(img.Width > img.Height)
{
if (img.Width > areaW)
{
double scale = areaW / img.Width;
//img.RenderTransform = new ScaleTransform(scale, scale);
double scaleH = img.Height * scale;
Canvas.SetTop(img, (areaH - scaleH) / 2);
Canvas.SetLeft(img, 0);
img.Width = img.Width * scale;
img.Height = scaleH;
return;
}
Canvas.SetTop(img, (areaH - img.Height) / 2);
Canvas.SetLeft(img, (areaW - img.Width) / 2);
}
else
{
if (img.Height > areaH)
{
double scale = areaH / img.Height;
//img.RenderTransform = new ScaleTransform(scale, scale);
double scaleW = img.Width * scale;
Canvas.SetTop(img, 0);
Canvas.SetLeft(img, (areaW - scaleW) / 2);
img.Width = scaleW;
img.Height = img.Height * scale;
return;
}
Canvas.SetTop(img, (areaH - img.Height) / 2);
Canvas.SetLeft(img, (areaW - img.Width) / 2);
}
}
/// <summary>
/// 上一张
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void BtnPreview_Click(object sender, RoutedEventArgs e)
{
if (images.Count <= 0) return;
index = --index < 0 ? images.Count - 1 : index;
ChangeSelect(index);
}
/// <summary>
/// 下一张
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void BtnNext_Click(object sender, RoutedEventArgs e)
{
if (images.Count <= 0) return;
index = ++index >= images.Count ? 0 : index;
ChangeSelect(index);
}
/// <summary>
/// 打开图片
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void BtnImage_Click(object sender, RoutedEventArgs e)
{
System.Windows.Forms.OpenFileDialog fileDialog = new System.Windows.Forms.OpenFileDialog();
fileDialog.Title = "请选择图片文件";
fileDialog.Filter = filter;
fileDialog.RestoreDirectory = true;
if(fileDialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
tbNotice.Visibility = Visibility.Collapsed;
if (fileDialog.FileNames.Length > 1)
LoadImages(fileDialog.FileNames);
else
LoadFolder(System.IO.Path.GetDirectoryName(fileDialog.FileName), fileDialog.FileName);
}
}
int index = 0;
string folder = null;
List<string> images = new List<string>();
string filter = "图像文件|*.png;*.jpg;*.jpeg;*.bmp";
/// <summary>
/// 打开文件夹
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void BtnFolder_Click(object sender, RoutedEventArgs e)
{
System.Windows.Forms.FolderBrowserDialog folderBrowser = new System.Windows.Forms.FolderBrowserDialog();
folderBrowser.Description = "请选择图片目录";
if (folderBrowser.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
tbNotice.Visibility = Visibility.Collapsed;
folder = folderBrowser.SelectedPath;
LoadFolder(folder);
}
}
/// <summary>
/// 切换当前图片
/// </summary>
/// <param name="select"></param>
void ChangeSelect(int select)
{
if (select < 0 || images.Count < 1)
return;
if (select >= images.Count)
select = images.Count - 1;
string file = images[select];
ChangeSelect(file);
}
/// <summary>
/// 切换当前图片
/// </summary>
/// <param name="select"></param>
void ChangeSelect(string select)
{
tbName.Text = System.IO.Path.GetFileName(select);
if (!File.Exists(select))
{
int i = images.IndexOf(select);
images.Remove(select);
MessageBox.Show("图片丢失");
if (images.Count <= 0)
tbNotice.Visibility = Visibility.Visible;
else
ChangeSelect(i);
return;
}
BitmapImage bitmap = new BitmapImage(new Uri(select));
img.Source = bitmap;
img.Width = bitmap.PixelWidth;
img.Height = bitmap.Height;
InitImage();
}
/// <summary>
/// 加载文件到集合中
/// </summary>
/// <param name="files"></param>
void LoadImages(string[] files)
{
images.Clear();
images.AddRange(files);
index = 0;
ChangeSelect(index);
}
/// <summary>
/// 加载目录图片到集合中
/// </summary>
/// <param name="folder"></param>
/// <param name="select"></param>
void LoadFolder(string folder, string select = null)
{
images.Clear();
string[] files = Directory.GetFiles(folder);
if (files == null)
return;
foreach (var item in files)
{
if (filter.Contains(System.IO.Path.GetExtension(item.ToLowerInvariant())))
images.Add(item);
}
index = 0;
ChangeSelect(select ?? images[0]);
}
}
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>
效果:
待解决问题:拖动后释放鼠标有时没有释放状态