程序文件中
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
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;
using System.ComponentModel;
using System.Runtime.CompilerServices;
using OpenCvSharp;
using OpenCvSharp.WpfExtensions;
namespace CanvasTool
{
/// <summary>
/// ImageControl.xaml 的交互逻辑
/// </summary>
public partial class ImageControl : UserControl,INotifyPropertyChanged
{
private BitmapSource currentbitmapSource;
private double scale;
public event PropertyChangedEventHandler? PropertyChanged;
public Action<System.Windows.Point, System.Windows.Point> onDrawArrow;
public BitmapSource CurrentBitmapSource { get { return currentbitmapSource; } set { currentbitmapSource = value; OnPropertyChanged(); } }
public ImageControl()
{
InitializeComponent();
}
public void SetImage(BitmapSource bitmapSource)
{
BitmapSource bitmapSource2 = bitmapSource;
cameraImage.Dispatcher.Invoke(() =>
{
CurrentBitmapSource = bitmapSource2;
cameraImage.Source = bitmapSource2;
double num = _canvas.Width / bitmapSource2.Width;
double num2 = _canvas.Height / bitmapSource2.Height;
scale = Math.Min(num, num2);
_Scale.ScaleY = scale;
_Scale.ScaleY = scale;
});
}
public void SetImage(Mat src)
{
Mat src2 = src;
base.Dispatcher.Invoke(() => {
SetImage(src.Clone().ToBitmapSource());
}
);
}
public void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
private Polygon polygontemp;
public bool IsCanDrawArrow { get; set; } = true;
public bool isCandrawRectangle { get; set; } = false;
private System.Windows.Shapes.Rectangle rectangleTemp;
private void _mouseLeftButtonMouseDown(object sender, MouseButtonEventArgs e)
{
Canvas canvas = sender as Canvas;
canvas.CaptureMouse();
if (canvas == null)
{
return;
}
System.Windows.Point mouseXY = e.GetPosition(canvas);
//DrawPoint(mouseXY,Colors.Green);
if (IsCanDrawArrow)
polygontemp = DrawArrow(arrowName, mouseXY.X, mouseXY.Y, mouseXY.X, mouseXY.Y);
if (isCandrawRectangle)
{
}
}
private readonly string dotName = "dot";
private readonly string arrowName = "DrawArrow";
public List<System.Windows.Point> listPts = new List<System.Windows.Point>();
public void DrawPoint(System.Windows.Point pt, Color color, double radius = 5.0, double thickness = 5.0)
{
listPts.Add(pt);
Ellipse ellipse = new Ellipse();
ellipse.Width = radius;
ellipse.Height = radius;
ellipse.StrokeThickness = thickness;
ellipse.Visibility = Visibility.Visible;
ellipse.Name = dotName;
ellipse.Fill = new SolidColorBrush(color);
ellipse.Stroke = new SolidColorBrush(color);
ellipse.Opacity = 0.6;
Canvas.SetLeft(ellipse, pt.X - (radius / 2));
Canvas.SetTop(ellipse, pt.Y - (radius / 2));
_canvas.Children.Add(ellipse);
}
public Polygon DrawArrow(string name, double pt1x, double pt1y, double pt2x, double pt2y, double arrowAngle = Math.PI / 12, double arrowLength = 20.0)
{
System.Windows.Point point1 = new System.Windows.Point(pt1x, pt1y);
System.Windows.Point point2 = new System.Windows.Point(pt2x, pt2y);
double num = Math.Atan((pt2y - pt1y) / (pt2x - pt1x));
double num2 = num - arrowAngle;
double num3 = num + arrowAngle;
double num4 = pt2x > pt1x ? -1 : 1;
double pt3x = pt2x + arrowLength * Math.Cos(num2) * num4;
double pt3y = pt2y + arrowLength * Math.Sin(num2) * num4;
double pt4x = pt2x + arrowLength * Math.Cos(num3) * num4;
double pt4y = pt2y + arrowLength * Math.Sin(num3) * num4;
System.Windows.Point point3 = new System.Windows.Point(pt3x, pt3y);
System.Windows.Point point4 = new System.Windows.Point(pt4x, pt4y);
System.Windows.Point[] array = new System.Windows.Point[] { point1, point2, point3, point4, point2 };
Polygon polygon = new Polygon()
{
Stroke = new SolidColorBrush(Colors.Green),
StrokeThickness = 2.0
};
polygon.Name = arrowName;
for (int i = 0; i < array.Length; i++)
{
polygon.Points.Add(array[i]);
}
_canvas.Children.Add(polygon);
return polygon;
}
public void DrawArrow(System.Windows.Point curPoint, Polygon polygon, double arrowAngle = Math.PI / 12, double arrowLength = 20.0)
{
double pt2x = curPoint.X;
double pt2y = curPoint.Y;
double pt1x = polygon.Points[0].X;
double pt1y = polygon.Points[0].Y;
System.Windows.Point point1 = new System.Windows.Point(pt1x, pt1y);
System.Windows.Point point2 = new System.Windows.Point(pt2x, pt2y);
double num = Math.Atan((pt2y - pt1y) / (pt2x - pt1x));
double num2 = num - arrowAngle;
double num3 = num + arrowAngle;
double num4 = pt2x > pt1x ? -1 : 1;
double pt3x = pt2x + arrowLength * Math.Cos(num2) * num4;
double pt3y = pt2y + arrowLength * Math.Sin(num2) * num4;
double pt4x = pt2x + arrowLength * Math.Cos(num3) * num4;
double pt4y = pt2y + arrowLength * Math.Sin(num3) * num4;
System.Windows.Point point3 = new System.Windows.Point(pt3x, pt3y);
System.Windows.Point point4 = new System.Windows.Point(pt4x, pt4y);
polygon.Points[0] = point1;
polygon.Points[1] = point2;
polygon.Points[2] = point3;
polygon.Points[3] = point4;
polygon.Points[4] = point2;
}
private void _canvas_MouseMove(object sender, MouseEventArgs e)
{
Canvas canvas = (Canvas)sender;
System.Windows.Point mousePoint = e.GetPosition(canvas);
if (polygontemp != null)
{
if (IsCanDrawArrow)
DrawArrow(mousePoint, polygontemp);
}
}
private void _canvas_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
Canvas canvas = sender as Canvas;
if (canvas == null)
return;
System.Windows.Point mousePoint = e.GetPosition(canvas);
onDrawArrow?.Invoke(polygontemp.Points[0], polygontemp.Points[1]);
canvas.ReleaseMouseCapture();
IsCanDrawArrow = false;
}
}
}
xaml文件中
<UserControl x:Class="CanvasTool.ImageControl"
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:CanvasTool"
mc:Ignorable="d"
Background="White"
d:DesignHeight="650" d:DesignWidth="850">
<Grid>
<Border BorderBrush="AliceBlue" BorderThickness="3">
<Canvas x:Name="_canvas" Width="800"
Height="600"
HorizontalAlignment="Left"
VerticalAlignment="Top"
Grid.Row="0" MouseLeftButtonDown="_mouseLeftButtonMouseDown" MouseMove="_canvas_MouseMove" MouseLeftButtonUp="_canvas_MouseLeftButtonUp"
>
<Image Margin="0" x:Name="cameraImage" Stretch="Fill"
Source="{Binding CurrentBitmapSource,RelativeSource={RelativeSource AncestorType=Window,Mode=FindAncestor}}">
<Image.RenderTransform>
<ScaleTransform x:Name="_Scale" ></ScaleTransform>
</Image.RenderTransform>
</Image>
</Canvas>
</Border>
</Grid>
</UserControl>