1.xaml实现
<UserControl
x:Class="HalconDemo.ImageUserControl"
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:local="clr-namespace:HalconDemo"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
d:DesignHeight="1024"
d:DesignWidth="1920"
mc:Ignorable="d">
<Grid>
<ContentControl
Name="Part_ImageContainer"
MaxWidth="1920"
MaxHeight="1024"
HorizontalAlignment="Left"
VerticalAlignment="Top"
HorizontalContentAlignment="Stretch"
VerticalContentAlignment="Stretch"
ClipToBounds="True"
Cursor="Hand">
<Image
Name="image"
HorizontalAlignment="Left"
VerticalAlignment="Top"
RenderOptions.BitmapScalingMode="NearestNeighbor">
<Image.RenderTransform>
<TransformGroup x:Name="group">
<ScaleTransform x:Name="scaler" />
<TranslateTransform x:Name="transer" />
</TransformGroup>
</Image.RenderTransform>
</Image>
</ContentControl>
</Grid>
</UserControl>
2.cs实现
/// <summary>
/// ImageUserControl.xaml 的交互逻辑
/// </summary>
public partial class ImageUserControl : UserControl
{
/// <summary>
/// 鼠标是否按下
/// </summary>
private bool mouseDown;
/// <summary>
/// 移动图片前,按下鼠标左键时,鼠标相对于Part_ImageContainer的点
/// </summary>
Point moveStart;
public ImageUserControl()
{
InitializeComponent();
}
~ImageUserControl()
{
Part_ImageContainer.MouseLeftButtonDown -= ImgMouseLeftButtonDown;
Part_ImageContainer.MouseMove -= ImgMouseMove;
Part_ImageContainer.MouseUp -= ImgMouseUp;
}
/// <summary>
/// 初始化加载图像
/// </summary>
/// <param name="filePath">图像路径</param>
/// <param name="IsMove">是否移动,true是,false否</param>
public void InitImage(string filePath,bool IsMove = true)
{
if (IsMove)
{
Part_ImageContainer.MouseLeftButtonDown += ImgMouseLeftButtonDown;
Part_ImageContainer.MouseMove += ImgMouseMove;
Part_ImageContainer.MouseUp += ImgMouseUp;
}
image.Source = new BitmapImage(new Uri(filePath, UriKind.Absolute));
}
private void ImgMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
//尝试将鼠标强制捕获到此元素
Part_ImageContainer.CaptureMouse();
mouseDown = true;
moveStart = e.GetPosition(Part_ImageContainer);
}
private void ImgMouseMove(object sender, MouseEventArgs e)
{
var mouseEnd = e.GetPosition(Part_ImageContainer); // 鼠标移动时,获取鼠标相对图片容器的点
if (mouseDown)
{
if (e.LeftButton == MouseButtonState.Pressed) // 按下鼠标左键,移动图片
{
DoMove(mouseEnd);
}
}
}
private void ImgMouseUp(object sender, MouseButtonEventArgs e)
{
Part_ImageContainer.ReleaseMouseCapture();
mouseDown = false;
}
private void ImgMouseWheel(object sender, MouseWheelEventArgs e)
{
var point = e.GetPosition(image);
double delta = e.Delta * 0.002;
DoScale(point, delta);
}
/// <summary>
/// 缩放图片。最小为0.1倍,最大为30倍
/// </summary>
/// <param name="point">相对于图片的点,以此点为中心缩放</param>
/// <param name="delta">缩放的倍数增量</param>
private void DoScale(Point point, double delta)
{
// 限制最大、最小缩放倍数
if (scaler.ScaleX + delta < 0.1 || scaler.ScaleX + delta > 30) return;
scaler.ScaleX += delta;
scaler.ScaleY += delta;
transer.X -= point.X * delta;
transer.Y -= point.Y * delta;
}
/// <summary>
/// 移动图片
/// </summary>
/// <param name="moveEndPoint">移动图片的终点(相对于Part_ImageContainer)</param>
private void DoMove(Point moveEndPoint)
{
// 考虑到旋转的影响,因此将两个点转换到Part_Image坐标系,计算x、y的增量
Point start = Part_ImageContainer.TranslatePoint(moveStart, image);
Point end = Part_ImageContainer.TranslatePoint(moveEndPoint, image);
// 判断一下,如果scale很大的时候,移动会很迟缓。此时应该将移动放大
if (scaler.ScaleX > 7)
{
transer.X += (end.X - start.X) * 4;
transer.Y += (end.Y - start.Y) * 4;
}
else if (scaler.ScaleX > 5)
{
transer.X += (end.X - start.X) * 3;
transer.Y += (end.Y - start.Y) * 3;
}
else if (scaler.ScaleX > 3)
{
transer.X += (end.X - start.X) * 2;
transer.Y += (end.Y - start.Y) * 2;
}
else if (scaler.ScaleX < 0.5)
{
transer.X += (end.X - start.X) * 0.5;
transer.Y += (end.Y - start.Y) * 0.5;
}
else
{
transer.X += (end.X - start.X);
transer.Y += (end.Y - start.Y);
}
moveStart = moveEndPoint;
// 以下代码,抄的https://blog.csdn.net/weixin_42975610/article/details/113741534
// W+w > 2*move_x > -((2*scale-1)*w + W) 水平平移限制条件
// H+h > 2*move_y > -((2*scale-1)*h + H) 垂直平移限制条件
if (transer.X * 2 > image.ActualWidth + Part_ImageContainer.ActualWidth - 20)
transer.X = (image.ActualWidth + Part_ImageContainer.ActualWidth - 20) / 2;
if (-transer.X * 2 > (2 * scaler.ScaleX - 1) * image.ActualWidth + Part_ImageContainer.ActualWidth - 20)
transer.X = -((scaler.ScaleX - 0.5) * image.ActualWidth + Part_ImageContainer.ActualWidth / 2 - 10);
if (transer.Y * 2 > image.ActualHeight + Part_ImageContainer.ActualHeight - 20)
transer.Y = (image.ActualHeight + Part_ImageContainer.ActualHeight - 20) / 2;
if (-transer.Y * 2 > (2 * scaler.ScaleY - 1) * image.ActualHeight + Part_ImageContainer.ActualHeight - 20)
transer.Y = -((scaler.ScaleY - 0.5) * image.ActualHeight + Part_ImageContainer.ActualHeight / 2 - 10);
}
/// <summary>
/// 图像缩放
/// </summary>
/// <param name="point">当前坐标</param>
/// <param name="scale">缩放倍数</param>
public void ImageScale(Point point, double scale)
{
DoScale(point, scale);
}
}
3.调用
//控件引用
<Canvas
x:Name="canvas"
Grid.Row="1"
Background="Black">
<HalconDemo:ImageUserControl
x:Name="ImageUserControl"
Grid.Row="1"
Width="{Binding ElementName=canvas, Path=ActualWidth}"
Height="{Binding ElementName=canvas, Path=ActualHeight}"
MouseWheel="ImageUserControl_MouseWheel" />
</Canvas>
//鼠标滚动缩放
private void ImageUserControl_MouseWheel(object sender, MouseWheelEventArgs e)
{
var point = e.GetPosition(image);
double delta = e.Delta * 0.002;
ImageUserControl.ImageScale(point, delta);
}
标签:scaler,自定义,缩放,C#,image,ImageContainer,transer,Part,start
From: https://www.cnblogs.com/qiutian-hao/p/18338034