WPF图片的拖拽、移动和缩放事件是比较常用的,主要是通过操作前端的TransformGroup实现图片常用事件,回调函数不影响主要功能
前端代码(.xmal / .xaml.cs)
// .xaml
<UserControl.Resources>
<conv:ImageConverter2 x:Key="imageConv"></conv:ImageConverter2>
<TransformGroup x:Name="transformGroup" x:Key="imageView">
<ScaleTransform />
<TranslateTransform />
<RotateTransform />
</TransformGroup>
</UserControl.Resources>
<ScrollViewer Grid.Column="0" VerticalScrollBarVisibility="Disabled">
<ContentControl>
<Image
RenderOptions.BitmapScalingMode="HighQuality"
RenderTransform="{StaticResource imageView}"
x:Name="image"
Source="{Binding SelectedItem.Path, Converter={StaticResource imageConv}}">
</Image>
</ContentControl>
</ScrollViewer>
// .xaml.cs
private CustomMouseEventHandler handler { get; set; }
handler = new CustomMouseEventHandler(this.image);
handler.AddHandlers(UpdateOcrContent);
handler.IsUseCallback = true;
后台代码(.cs)
public enum EventState
{
MouseDown,
MouseUp,
MouseMove,
MouseWheel,
None
}
public class CustomMouseEventHandler
{
public bool isMouseDown { get; set; } = false;
public System.Windows.Point mousePos { get; set; }
public bool IsUseCallback { get; set; } = false;
public EventState EventState { get; set; } = EventState.None;
public Action Callback { get; set; } = null;
private double scaleX{get;set;}
private double scaleY { get; set; }
private Image image { get; set; }
public CustomMouseEventHandler(Image image)
{
this.image = image;
}
public void AddHandlers(Action callback = null)
{
image.MouseDown += Image_MouseDown;
image.MouseUp += Image_MouseUp;
image.MouseMove += Image_MouseMove;
image.MouseWheel += Image_MouseWheel;
this.Callback = callback;
}
public void Image_MouseDown(object sender, MouseButtonEventArgs e)
{
EventState = EventState.MouseDown;
if (e.ChangedButton == MouseButton.Left)
{
isMouseDown = true;
mousePos = e.GetPosition((IInputElement)image.Parent);
image.CaptureMouse();
}
}
public void Image_MouseMove(object sender, MouseEventArgs e)
{
EventState = EventState.MouseMove;
if (!isMouseDown) return;
var group = image.RenderTransform as TransformGroup;
var transform = group.Children[1] as TranslateTransform;
var position = e.GetPosition((IInputElement)image.Parent);
transform.X -= mousePos.X - position.X;
transform.Y -= mousePos.Y - position.Y;
mousePos = position;
if (IsUseCallback) Callback();
}
public void Image_MouseUp(object sender, MouseButtonEventArgs e)
{
EventState = EventState.MouseUp;
isMouseDown = false;
image.ReleaseMouseCapture();
}
public void Image_MouseWheel(object sender, MouseWheelEventArgs e)
{
EventState = EventState.MouseWheel;
var delta = e.Delta * 0.001;
var group = image.RenderTransform as TransformGroup;
var transform = group.Children[0] as ScaleTransform;
var previousPoint = e.GetPosition(image);
// 禁止无限缩小
if (transform.ScaleX + delta < 0.1) return;
transform.ScaleX += delta;
transform.ScaleY += delta;
var transform1 = group.Children[1] as TranslateTransform;
// 当前位置加偏移量
transform1.X += -1 * previousPoint.X * delta;
transform1.Y += -1 * previousPoint.Y * delta;
if (IsUseCallback) Callback();
}
public TransformGroup GetTransformGroup()
{
return this.image.RenderTransform as TransformGroup;
}
public void ResetTransform(DependencyObject d)
{
// 同步调用
d.Dispatcher.Invoke(new System.Action(() =>
{
TransformGroup group = new TransformGroup();
ScaleTransform scale = new ScaleTransform();
group.Children.Add(scale);
TranslateTransform translate = new TranslateTransform();
group.Children.Add(translate);
RotateTransform rotate = new RotateTransform();
group.Children.Add(rotate);
image.RenderTransform = group;
// 刷新页面
this.image.UpdateLayout();
}), System.Windows.Threading.DispatcherPriority.Background);
}
public void SetImageSource(string path)
{
if (string.IsNullOrEmpty(path))
{
this.image.Source = null;
return;
}
var bitmap = new BitmapImage();
var stream = File.OpenRead(path);
bitmap.BeginInit();
bitmap.CacheOption = BitmapCacheOption.OnLoad;
bitmap.StreamSource = stream;
bitmap.EndInit();
stream.Close();
stream.Dispose();
this.image.Source = bitmap;
}
}