最近項目需要,要用到一個圖片查看器,類似於windows自帶的圖片查看器那樣,滑鼠滾動可以縮放,可以拖拽圖片,於是就寫了這個簡單的圖片查看器。前臺代碼: ...
最近項目需要,要用到一個圖片查看器,類似於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處理拖拽進來之後的事情
源碼:http://files.cnblogs.com/files/huangli321456/PictureViewer.zip
代碼參照:http://www.cnblogs.com/snake-hand/archive/2012/08/13/2636227.html