Compare commits
50 Commits
e7736217db
...
dev_update
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b2ccd0c91a | ||
| 4765e0e5bd | |||
|
|
ab38ee029a | ||
|
|
dbf412713b | ||
|
|
67ba78f268 | ||
|
|
d63a6c42b3 | ||
| babc40d36a | |||
| 409089e2ca | |||
| e08386333a | |||
| b19feb5a44 | |||
|
|
0865af247a | ||
|
|
8d32269ee0 | ||
|
|
b4569f8ccc | ||
| 9e38ea85c8 | |||
|
|
3be4b185d6 | ||
| 5d77eebc67 | |||
| 8868915944 | |||
| 2d98b2d8b8 | |||
| bee7dc6f03 | |||
| 1046978877 | |||
| bc981fc7a9 | |||
|
|
09c2eb37fe | ||
|
|
2a6019bfbd | ||
| fabc7606e7 | |||
| fb1ae0bb08 | |||
| 8619d8ba2e | |||
| b60d2759b1 | |||
| 959a2bf642 | |||
| cb7e216b3a | |||
| 33c2994455 | |||
| 2b32e1a649 | |||
|
|
d881dc6ec0 | ||
| 126db6bf91 | |||
| 447cf4326b | |||
| 9973470e55 | |||
| b8d7371a56 | |||
| 8aec9ba7fa | |||
| f0f88624ae | |||
| 9a5d3be528 | |||
| 0dedff36fd | |||
| 25cd61c5cb | |||
| 0ac00af0ad | |||
| 01ccf476f1 | |||
| 5ec9a64b9e | |||
| c49c45d6e4 | |||
| ca6476b87c | |||
| 9a330c01f8 | |||
| 7828ca663f | |||
| a9d02a5a9d | |||
|
|
b8c83e459d |
28
CanFly.Canvas/CanFly.Canvas.csproj
Normal file
28
CanFly.Canvas/CanFly.Canvas.csproj
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>net8.0-windows</TargetFramework>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
<BaseOutputPath>..\</BaseOutputPath>
|
||||||
|
<AppendTargetFrameworkToOutputPath>output</AppendTargetFrameworkToOutputPath>
|
||||||
|
<UseWindowsForms>true</UseWindowsForms>
|
||||||
|
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||||
|
<Platforms>AnyCPU;x64</Platforms>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<!--<ItemGroup>
|
||||||
|
<PackageReference Include="SkiaSharp" Version="2.88.9" />
|
||||||
|
<PackageReference Include="SkiaSharp.Views" Version="2.88.9" />
|
||||||
|
<PackageReference Include="SkiaSharp.Views.Desktop.Common" Version="2.88.9" />
|
||||||
|
<PackageReference Include="SkiaSharp.Views.Forms" Version="2.88.9" />
|
||||||
|
</ItemGroup>-->
|
||||||
|
|
||||||
|
</Project>
|
||||||
88
CanFly.Canvas/Helper/PointHelper.cs
Normal file
88
CanFly.Canvas/Helper/PointHelper.cs
Normal file
@@ -0,0 +1,88 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Drawing.Drawing2D;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace CanFly.Canvas.Helper
|
||||||
|
{
|
||||||
|
public static class PointHelper
|
||||||
|
{
|
||||||
|
public static Point ToPoint(this PointF pf)
|
||||||
|
{
|
||||||
|
return new Point((int)pf.X, (int)pf.Y);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 将相对于控件的坐标转换为相对于图像的坐标
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="p">控件中指定点的点位坐标,坐标原点为控件左上角</param>
|
||||||
|
/// <returns>该点以图像坐标系为基准的坐标值,坐标原点为图像左上角</returns>
|
||||||
|
public static PointF ToImageCoordinate(this Point p, Matrix m)
|
||||||
|
{
|
||||||
|
PointF pf = new PointF(p.X, p.Y);
|
||||||
|
return ToImageCoordinate(pf, m);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 将相对于控件的坐标转换为相对于图像的坐标
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="p">控件中指定点的点位坐标,坐标原点为控件左上角</param>
|
||||||
|
/// <returns>该点以图像坐标系为基准的坐标值,坐标原点为图像左上角</returns>
|
||||||
|
public static PointF ToImageCoordinate(this PointF p, Matrix m)
|
||||||
|
{
|
||||||
|
PointF[] ps = new PointF[] { p };
|
||||||
|
Matrix invertMatrix = m.Clone();
|
||||||
|
//想要从旧空间到新空间的逆变换,所以我们需要对这个矩阵求逆
|
||||||
|
invertMatrix.Invert();
|
||||||
|
invertMatrix.TransformPoints(ps);
|
||||||
|
return ps[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 将相对于图像的坐标转换为相对于控件坐标系
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="p">图像中指定点的点位坐标,坐标原点为图像左上角</param>
|
||||||
|
/// <returns>该点以空间坐标系为基准的坐标值,坐标原点为空间坐左上角</returns>
|
||||||
|
public static PointF ToControlCoordinate(this PointF p, Matrix m)
|
||||||
|
{
|
||||||
|
PointF[] ps = new PointF[] { p };
|
||||||
|
m.TransformPoints(ps);
|
||||||
|
return ps[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public static float Distance(PointF p1, PointF p2)
|
||||||
|
{
|
||||||
|
return (float)Math.Sqrt(Math.Pow(p2.X - p1.X, 2) + Math.Pow(p2.Y - p1.Y, 2));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float DistanceToLine(PointF point, PointF start, PointF end)
|
||||||
|
{
|
||||||
|
float lineLengthSquared = DistanceSquared(start, end);
|
||||||
|
if (lineLengthSquared == 0)
|
||||||
|
{
|
||||||
|
return Distance(point, start); // 线段的两个端点重合
|
||||||
|
}
|
||||||
|
|
||||||
|
float t = ((point.X - start.X) * (end.X - start.X) + (point.Y - start.Y) * (end.Y - start.Y)) / lineLengthSquared;
|
||||||
|
t = Math.Clamp(t, 0, 1); // 限制 t 在 [0, 1] 范围内
|
||||||
|
|
||||||
|
PointF projection = new PointF(
|
||||||
|
start.X + t * (end.X - start.X),
|
||||||
|
start.Y + t * (end.Y - start.Y));
|
||||||
|
|
||||||
|
return Distance(point, projection);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static float DistanceSquared(PointF p1, PointF p2)
|
||||||
|
{
|
||||||
|
return (float)(Math.Pow(p2.X - p1.X, 2) + Math.Pow(p2.Y - p1.Y, 2));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
32
CanFly.Canvas/Model/ClickArea.cs
Normal file
32
CanFly.Canvas/Model/ClickArea.cs
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace CanFly.Canvas.Model
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 点击的区域
|
||||||
|
/// </summary>
|
||||||
|
internal enum ClickArea
|
||||||
|
{
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 未知区域
|
||||||
|
/// </summary>
|
||||||
|
AREA_UNKNOW,
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 图片区域
|
||||||
|
/// </summary>
|
||||||
|
AREA_IMG,
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 缺陷元素区域
|
||||||
|
/// </summary>
|
||||||
|
AREA_DEFECT,
|
||||||
|
}
|
||||||
|
}
|
||||||
22
CanFly.Canvas/Model/Cursor.cs
Normal file
22
CanFly.Canvas/Model/Cursor.cs
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace LabelSharp.Config
|
||||||
|
{
|
||||||
|
public static class CustomCursors
|
||||||
|
{
|
||||||
|
|
||||||
|
public static Cursor CURSOR_DEFAULT = Cursors.Arrow;
|
||||||
|
public static Cursor CURSOR_POINT = Cursors.Hand;
|
||||||
|
public static Cursor CURSOR_DRAW = Cursors.Cross;
|
||||||
|
public static Cursor CURSOR_MOVE = Cursors.Hand;
|
||||||
|
public static Cursor CURSOR_GRAB = Cursors.Hand;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
12
CanFly.Canvas/Model/Exception/InvalidShapeException.cs
Normal file
12
CanFly.Canvas/Model/Exception/InvalidShapeException.cs
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace CanFly.Canvas.Model.Exception
|
||||||
|
{
|
||||||
|
internal class InvalidShapeException : System.Exception
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
41
CanFly.Canvas/Shape/BaseShape.cs
Normal file
41
CanFly.Canvas/Shape/BaseShape.cs
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace CanFly.Canvas.Shape
|
||||||
|
{
|
||||||
|
public abstract class BaseShape
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
15
CanFly.Canvas/Shape/DoubleClickActionEnum.cs
Normal file
15
CanFly.Canvas/Shape/DoubleClickActionEnum.cs
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace CanFly.Canvas.Shape
|
||||||
|
{
|
||||||
|
internal enum DoubleClickActionEnum
|
||||||
|
{
|
||||||
|
None,
|
||||||
|
Close,
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
938
CanFly.Canvas/Shape/FlyShape.cs
Normal file
938
CanFly.Canvas/Shape/FlyShape.cs
Normal file
@@ -0,0 +1,938 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Drawing.Drawing2D;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Runtime.Serialization.Formatters.Binary;
|
||||||
|
using System.Runtime.Serialization;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using CanFly.Canvas.Helper;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.Net.NetworkInformation;
|
||||||
|
using System.Drawing;
|
||||||
|
|
||||||
|
|
||||||
|
namespace CanFly.Canvas.Shape
|
||||||
|
{
|
||||||
|
[Serializable]
|
||||||
|
public class FlyShape
|
||||||
|
{
|
||||||
|
private const float DFT_VTX_EPSILON = 4f;
|
||||||
|
private float _epsilon = DFT_VTX_EPSILON;
|
||||||
|
|
||||||
|
public float LineWidth { get; set; } = 2f;
|
||||||
|
|
||||||
|
|
||||||
|
#region Shape颜色
|
||||||
|
|
||||||
|
#region drawing
|
||||||
|
public Color line_color = Color.FromArgb(128, 0, 255, 0);
|
||||||
|
public Color fill_color = Color.FromArgb(64, 0, 0, 0);
|
||||||
|
public Color vertex_fill_color = Color.FromArgb(255, 0, 255, 0);
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region selecting / hovering
|
||||||
|
public Color select_line_color = Color.FromArgb(255, 255, 255, 255);
|
||||||
|
public Color select_fill_color = Color.FromArgb(64, 0, 255, 0);
|
||||||
|
public Color hvertex_fill_color = Color.FromArgb(255, 255, 255, 255);
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
private PointTypeEnum point_type = PointTypeEnum.ROUND;
|
||||||
|
private float point_size = 8.0f;
|
||||||
|
|
||||||
|
private float _scale = 1.0f;
|
||||||
|
private float scale
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return _scale;
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_scale = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private ShapeTypeEnum _shape_type;
|
||||||
|
private Matrix _matrix = new Matrix();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public ShapeTypeEnum ShapeType
|
||||||
|
{
|
||||||
|
get => _shape_type;
|
||||||
|
set { _shape_type = value; }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public string label = "";
|
||||||
|
public int? group_id = null;
|
||||||
|
private List<PointF> _points
|
||||||
|
{
|
||||||
|
get;
|
||||||
|
set;
|
||||||
|
} = new List<PointF>();
|
||||||
|
|
||||||
|
public List<PointF> Points
|
||||||
|
{
|
||||||
|
get { return _points; }
|
||||||
|
set
|
||||||
|
{
|
||||||
|
this._points = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private List<PointF> _pointsRaw = new List<PointF>();
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 辅助节点
|
||||||
|
/// </summary>
|
||||||
|
public List<PointF> GuidePoints = new List<PointF>();
|
||||||
|
|
||||||
|
public float _currentRotateAngle;
|
||||||
|
private bool _isRotating = false;
|
||||||
|
|
||||||
|
|
||||||
|
public List<int> point_labels = new List<int>();
|
||||||
|
|
||||||
|
|
||||||
|
private ShapeTypeEnum _shape_type_raw;
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 是否填充多边形。使用:select_fill_color 或 fill_color 填充。
|
||||||
|
/// </summary>
|
||||||
|
public bool fill = false;
|
||||||
|
|
||||||
|
|
||||||
|
public bool Selected { get; set; } = false;
|
||||||
|
public object? flags;
|
||||||
|
public string description = "";
|
||||||
|
private List<object> other_data = new List<object>();
|
||||||
|
|
||||||
|
|
||||||
|
private int _highlightIndex = -1;
|
||||||
|
private HighlightModeEnum _highlightMode = HighlightModeEnum.NEAR_VERTEX;
|
||||||
|
|
||||||
|
|
||||||
|
private Dictionary<HighlightModeEnum, HighlightSetting> _highlightSettings = new Dictionary<HighlightModeEnum, HighlightSetting>()
|
||||||
|
{
|
||||||
|
{ HighlightModeEnum.NEAR_VERTEX,new HighlightSetting(4,PointTypeEnum.ROUND)},
|
||||||
|
{ HighlightModeEnum.MOVE_VERTEX,new HighlightSetting(1.5f,PointTypeEnum.SQUARE)},
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
private bool _closed = false;
|
||||||
|
private Color _vertex_fill_color;
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 当图形是Line时,是否绘制辅助矩形框
|
||||||
|
/// </summary>
|
||||||
|
public bool IsDrawLineVirtualRect { get; set; } = false;
|
||||||
|
/// <summary>
|
||||||
|
/// 画Line时辅助矩形的宽度
|
||||||
|
/// </summary>
|
||||||
|
public float LineVirtualRectWidth = 40;
|
||||||
|
public PointF[] LineVirtualRectPoints = new PointF[4];
|
||||||
|
|
||||||
|
|
||||||
|
public FlyShape()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private PointF ScalePoint(PointF point)
|
||||||
|
{
|
||||||
|
return point;
|
||||||
|
|
||||||
|
//return new PointF(
|
||||||
|
// (float)(point.X * scale),
|
||||||
|
// (float)(point.Y * scale));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public void Close()
|
||||||
|
{
|
||||||
|
this._closed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void AddPoint(PointF point, int label = 1)
|
||||||
|
{
|
||||||
|
if (_points != null && _points.Count > 0 && point.Equals(_points.ElementAt(0)))
|
||||||
|
{
|
||||||
|
Close();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (_points.Count > 0 && this[-1].Equals(point))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
_points.Add(point);
|
||||||
|
point_labels.Add(label);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public bool CanAddPoint()
|
||||||
|
{
|
||||||
|
return ShapeType == ShapeTypeEnum.Polygon
|
||||||
|
|| ShapeType == ShapeTypeEnum.LineStrip;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public PointF? PopPoint()
|
||||||
|
{
|
||||||
|
if (_points != null && _points.Count > 0)
|
||||||
|
{
|
||||||
|
if (point_labels != null && point_labels.Count > 0)
|
||||||
|
{
|
||||||
|
point_labels.RemoveAt(point_labels.Count - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
PointF lastPoint = _points[_points.Count - 1];
|
||||||
|
_points.RemoveAt(_points.Count - 1);
|
||||||
|
return lastPoint;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public void InsertPoint(int i, PointF point, int label = 1)
|
||||||
|
{
|
||||||
|
_points.Insert(i, point);
|
||||||
|
point_labels.Insert(i, label);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void RemovePoint(int i)
|
||||||
|
{
|
||||||
|
if (!CanAddPoint())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ShapeType == ShapeTypeEnum.Polygon && _points.Count <= 3)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if (ShapeType == ShapeTypeEnum.LineStrip && _points.Count <= 2)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
_points.RemoveAt(_points.Count - 1);
|
||||||
|
point_labels.RemoveAt(point_labels.Count - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public bool IsClosed() => _closed;
|
||||||
|
|
||||||
|
|
||||||
|
public void SetOpen() { _closed = false; }
|
||||||
|
|
||||||
|
|
||||||
|
#region 矩形辅助函数
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 矩形模式下,选中的点索引
|
||||||
|
/// </summary>
|
||||||
|
[JsonIgnore]
|
||||||
|
private int _rectSelectedVertex = -1;
|
||||||
|
[JsonIgnore]
|
||||||
|
private PointF _rectSelectedMoveVertex;
|
||||||
|
[JsonIgnore]
|
||||||
|
private PointF _rectCenterPoint;
|
||||||
|
|
||||||
|
[JsonIgnore]
|
||||||
|
private bool isVertexMoving;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 正在移动节点
|
||||||
|
/// </summary>
|
||||||
|
[JsonIgnore]
|
||||||
|
public bool IsVertexMoving
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return isVertexMoving;
|
||||||
|
}
|
||||||
|
internal set
|
||||||
|
{
|
||||||
|
//float centerX = (_points[0].X + _points[2].X) / 2f;
|
||||||
|
//float centerY = (_points[0].Y + _points[2].Y) / 2f;
|
||||||
|
//_rectCenterVertex = new PointF(centerX, centerY);
|
||||||
|
isVertexMoving = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//private PointF[] TransformPoints(List<PointF> points, PointF center, float angle)
|
||||||
|
//{
|
||||||
|
// PointF[] ptsArray = points.ToArray();
|
||||||
|
// using (Matrix matrix = new Matrix())
|
||||||
|
// {
|
||||||
|
// matrix.RotateAt(angle, center);
|
||||||
|
// matrix.TransformPoints(ptsArray);
|
||||||
|
// }
|
||||||
|
// return ptsArray;
|
||||||
|
//}
|
||||||
|
//GraphicsPath vrtx_path = new GraphicsPath();
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
public void Paint(Graphics painter)
|
||||||
|
{
|
||||||
|
if (_points == null || _points.Count == 0)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Color color = Selected ? select_line_color : line_color;
|
||||||
|
using Pen pen = new Pen(color, LineWidth);
|
||||||
|
|
||||||
|
// Create paths
|
||||||
|
GraphicsPath line_path = new GraphicsPath();
|
||||||
|
GraphicsPath vrtx_path = new GraphicsPath();
|
||||||
|
GraphicsPath guide_vrtx_path = new GraphicsPath();
|
||||||
|
|
||||||
|
switch (ShapeType)
|
||||||
|
{
|
||||||
|
//case ShapeTypeEnum.Rectangle:
|
||||||
|
// {
|
||||||
|
// if (_points.Count == 2)
|
||||||
|
// {
|
||||||
|
// float centerX = (_points[0].X + _points[1].X) / 2f;
|
||||||
|
// float centerY = (_points[0].Y + _points[1].Y) / 2f;
|
||||||
|
// _rectCenterPoint = new PointF(centerX, centerY);
|
||||||
|
|
||||||
|
|
||||||
|
// line_path.StartFigure();
|
||||||
|
|
||||||
|
// if (_points[1].X < _points[0].X)
|
||||||
|
// {
|
||||||
|
// _points[1] = new PointF(_points[0].X + LineWidth / 2f, _points[1].Y);
|
||||||
|
// }
|
||||||
|
// if (_points[1].Y < _points[0].Y)
|
||||||
|
// {
|
||||||
|
// _points[1] = new PointF(_points[1].X, _points[0].Y + LineWidth / 2f);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// //float x = Math.Min(_points[0].X, _points[1].X);
|
||||||
|
// //float y = Math.Min(_points[0].Y, _points[1].Y);
|
||||||
|
|
||||||
|
// float w = Math.Abs(ScalePoint(_points[1]).X - ScalePoint(_points[0]).X);
|
||||||
|
// float h = Math.Abs(ScalePoint(_points[1]).Y - ScalePoint(_points[0]).Y);
|
||||||
|
|
||||||
|
// RectangleF drawRect = new(new PointF(_points[0].X, _points[0].Y), new SizeF(w, h));
|
||||||
|
|
||||||
|
// bool bRotated = false;
|
||||||
|
// NomalizeRotateAngle();
|
||||||
|
|
||||||
|
// Matrix oMatrix = null;
|
||||||
|
|
||||||
|
// if (_currentRotateAngle > 0)
|
||||||
|
// {
|
||||||
|
// // Create rotation matrix
|
||||||
|
// oMatrix = new Matrix();
|
||||||
|
// oMatrix.RotateAt(_currentRotateAngle, _rectCenterPoint, MatrixOrder.Append);
|
||||||
|
// painter.Transform = oMatrix;
|
||||||
|
// bRotated = true;
|
||||||
|
// }
|
||||||
|
// //Store rectangle region
|
||||||
|
// //Region _drawRectRegion = new Region(drawRect);
|
||||||
|
// if (oMatrix != null)
|
||||||
|
// line_path.Transform(oMatrix);
|
||||||
|
|
||||||
|
|
||||||
|
// line_path.AddRectangle(drawRect);
|
||||||
|
|
||||||
|
|
||||||
|
// // Reset transform
|
||||||
|
// if (bRotated)
|
||||||
|
// {
|
||||||
|
// bRotated = false;
|
||||||
|
// painter.ResetTransform();
|
||||||
|
// }
|
||||||
|
// //_matrix.Reset();
|
||||||
|
// //_matrix.RotateAt(_currentRotateAngle, new PointF(
|
||||||
|
// // (_points[0].X + _points[1].X) / 2,
|
||||||
|
// // (_points[0].Y + _points[1].Y) / 2));
|
||||||
|
// //line_path.Transform(_matrix);
|
||||||
|
|
||||||
|
|
||||||
|
// //line_path.AddPolygon(_pointsRaw.ToArray());
|
||||||
|
|
||||||
|
// }
|
||||||
|
|
||||||
|
// if (_regionVertex.Length != _points.Count)
|
||||||
|
// {
|
||||||
|
// _regionVertex = new Region[_points.Count];
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
|
// for (int i = 0; i < _points.Count; i++)
|
||||||
|
// {
|
||||||
|
// DrawVertex(vrtx_path, i);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// vrtx_path.Transform(_matrix);
|
||||||
|
|
||||||
|
// }
|
||||||
|
|
||||||
|
// break;
|
||||||
|
case ShapeTypeEnum.Rectangle:
|
||||||
|
{
|
||||||
|
if (_points.Count == 2)
|
||||||
|
{
|
||||||
|
float centerX = (_points[0].X + _points[1].X) / 2f;
|
||||||
|
float centerY = (_points[0].Y + _points[1].Y) / 2f;
|
||||||
|
_rectCenterPoint = new PointF(centerX, centerY);
|
||||||
|
|
||||||
|
line_path.StartFigure();
|
||||||
|
|
||||||
|
if (_points[1].X < _points[0].X)
|
||||||
|
{
|
||||||
|
_points[1] = new PointF(_points[0].X + LineWidth / 2f, _points[1].Y);
|
||||||
|
}
|
||||||
|
if (_points[1].Y < _points[0].Y)
|
||||||
|
{
|
||||||
|
_points[1] = new PointF(_points[1].X, _points[0].Y + LineWidth / 2f);
|
||||||
|
}
|
||||||
|
|
||||||
|
float w = Math.Abs(ScalePoint(_points[1]).X - ScalePoint(_points[0]).X);
|
||||||
|
float h = Math.Abs(ScalePoint(_points[1]).Y - ScalePoint(_points[0]).Y);
|
||||||
|
|
||||||
|
RectangleF drawRect = new(new PointF(_points[0].X, _points[0].Y), new SizeF(w, h));
|
||||||
|
|
||||||
|
line_path.AddRectangle(drawRect);
|
||||||
|
|
||||||
|
_matrix.Reset();
|
||||||
|
_matrix.RotateAt(_currentRotateAngle, _rectCenterPoint); // 使用更新后的旋转角度
|
||||||
|
line_path.Transform(_matrix);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_regionVertex.Length != _points.Count)
|
||||||
|
{
|
||||||
|
_regionVertex = new Region[_points.Count];
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < _points.Count; i++)
|
||||||
|
{
|
||||||
|
DrawVertex1(vrtx_path, i);
|
||||||
|
}
|
||||||
|
|
||||||
|
vrtx_path.Transform(_matrix);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ShapeTypeEnum.Circle:
|
||||||
|
{
|
||||||
|
if (_points.Count == 2)
|
||||||
|
{
|
||||||
|
float radius = PointHelper.Distance(ScalePoint(_points[0]), ScalePoint(_points[1]));
|
||||||
|
line_path.AddEllipse(
|
||||||
|
ScalePoint(_points[0]).X - radius,
|
||||||
|
ScalePoint(_points[0]).Y - radius,
|
||||||
|
radius * 2,
|
||||||
|
radius * 2);
|
||||||
|
}
|
||||||
|
for (int i = 0; i < _points.Count; i++)
|
||||||
|
{
|
||||||
|
DrawVertex(vrtx_path, i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ShapeTypeEnum.LineStrip:
|
||||||
|
{
|
||||||
|
line_path.StartFigure();
|
||||||
|
line_path.AddLine(ScalePoint(_points[0]), ScalePoint(_points[0]));
|
||||||
|
|
||||||
|
for (int i = 0; i < _points.Count; i++)
|
||||||
|
{
|
||||||
|
PointF pt = _points[i];
|
||||||
|
line_path.AddLine(ScalePoint(pt), ScalePoint(pt));
|
||||||
|
DrawVertex(vrtx_path, i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ShapeTypeEnum.Line:
|
||||||
|
{
|
||||||
|
// 添加框线到路径
|
||||||
|
var tmpPoints = _points.Select(p => ScalePoint(p)).ToList();
|
||||||
|
line_path.AddLines(tmpPoints.ToArray());
|
||||||
|
|
||||||
|
if (IsDrawLineVirtualRect && tmpPoints.Count == 2)
|
||||||
|
{
|
||||||
|
var center = new PointF((tmpPoints[0].X + tmpPoints[1].X) / 2,
|
||||||
|
(tmpPoints[0].Y + tmpPoints[1].Y) / 2);
|
||||||
|
|
||||||
|
// 计算两点之间的角度
|
||||||
|
float dx = tmpPoints[1].X - tmpPoints[0].X;
|
||||||
|
float dy = tmpPoints[1].Y - tmpPoints[0].Y;
|
||||||
|
float distance = PointHelper.Distance(tmpPoints[0], tmpPoints[1]);
|
||||||
|
double angle = Math.Atan2(dy, dx) * (180.0 / Math.PI); // 转换为度数
|
||||||
|
|
||||||
|
float l = center.X - distance / 2;
|
||||||
|
float t = center.Y - LineVirtualRectWidth / 2;
|
||||||
|
float r = center.X + distance / 2;
|
||||||
|
float b = center.Y + LineVirtualRectWidth / 2;
|
||||||
|
|
||||||
|
PointF ptLT = new PointF(l, t);
|
||||||
|
PointF ptRT = new PointF(r, t);
|
||||||
|
PointF ptRB = new PointF(r, b);
|
||||||
|
PointF ptLB = new PointF(l, b);
|
||||||
|
#if false
|
||||||
|
RectangleF rect = new RectangleF(ptLT, new SizeF(distance, LineVirtualRectWidth));
|
||||||
|
|
||||||
|
GraphicsPath rectPath = new GraphicsPath();
|
||||||
|
rectPath.AddRectangle(rect);
|
||||||
|
|
||||||
|
//// 设置矩阵以进行旋转和位移
|
||||||
|
Matrix matrix = new Matrix();
|
||||||
|
matrix.RotateAt((float)angle, center); // 旋转
|
||||||
|
|
||||||
|
// 应用变换
|
||||||
|
rectPath.Transform(matrix);
|
||||||
|
// 画框线
|
||||||
|
painter.DrawPath(pen, rectPath);
|
||||||
|
#else
|
||||||
|
RectangleF rect = new RectangleF(ptLT, new SizeF(distance, LineVirtualRectWidth));
|
||||||
|
|
||||||
|
LineVirtualRectPoints = new PointF[4] {
|
||||||
|
ptLT,ptRT,ptRB,ptLB
|
||||||
|
};
|
||||||
|
|
||||||
|
//// 设置矩阵以进行旋转和位移
|
||||||
|
Matrix matrix = new Matrix();
|
||||||
|
matrix.RotateAt((float)angle, center); // 旋转
|
||||||
|
matrix.TransformPoints(LineVirtualRectPoints);
|
||||||
|
|
||||||
|
GraphicsPath rectPath = new GraphicsPath();
|
||||||
|
rectPath.AddPolygon(LineVirtualRectPoints);
|
||||||
|
|
||||||
|
Pen rectpen = new Pen(Color.FromArgb(60, 0, 255, 0), 1);
|
||||||
|
|
||||||
|
// 画框线
|
||||||
|
painter.DrawPath(rectpen, rectPath);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 添加节点到路径
|
||||||
|
for (int i = 0; i < _points.Count; i++)
|
||||||
|
{
|
||||||
|
DrawVertex(vrtx_path, i);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (IsClosed())
|
||||||
|
{
|
||||||
|
line_path.AddLine(ScalePoint(_points[0]), ScalePoint(_points[0]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ShapeTypeEnum.Polygon:
|
||||||
|
case ShapeTypeEnum.Point:
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
// 添加多边形框线到路径
|
||||||
|
line_path.AddLines(_points.Select(p => ScalePoint(p)).ToArray());
|
||||||
|
|
||||||
|
// 添加节点到路径
|
||||||
|
for (int i = 0; i < _points.Count; i++)
|
||||||
|
{
|
||||||
|
DrawVertex(vrtx_path, i);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (IsClosed())
|
||||||
|
{
|
||||||
|
line_path.AddLine(ScalePoint(_points[0]), ScalePoint(_points[0]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#region 将点绘制到画布上
|
||||||
|
|
||||||
|
// 画框线
|
||||||
|
painter.DrawPath(pen, line_path);
|
||||||
|
|
||||||
|
// 填充节点
|
||||||
|
if (vrtx_path.PointCount > 0)
|
||||||
|
{
|
||||||
|
painter.DrawPath(pen, vrtx_path);
|
||||||
|
painter.FillPath(new SolidBrush(vertex_fill_color), vrtx_path);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (fill) // 是否填充多边形
|
||||||
|
{
|
||||||
|
Color fillColor = Selected ? select_fill_color : fill_color;
|
||||||
|
painter.FillPath(new SolidBrush(fillColor), line_path);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private Region[] _regionVertex = new Region[] { };
|
||||||
|
|
||||||
|
private void DrawVertex1(GraphicsPath path, int i)
|
||||||
|
{
|
||||||
|
PointF pt = _points[i];
|
||||||
|
_regionVertex[i] = new Region(new RectangleF(
|
||||||
|
pt.X - _epsilon, pt.Y - _epsilon,
|
||||||
|
_epsilon * 2, _epsilon * 2));
|
||||||
|
|
||||||
|
// 将节点变换
|
||||||
|
PointF[] transformedPoint = new PointF[] { pt };
|
||||||
|
_matrix.TransformPoints(transformedPoint); // 变换节点位置
|
||||||
|
|
||||||
|
pt = transformedPoint[0]; // 获取变换后的节点位置
|
||||||
|
|
||||||
|
// 绘制节点
|
||||||
|
float d = point_size; // Point size
|
||||||
|
PointTypeEnum shape = point_type; // Point shape
|
||||||
|
PointF point = ScalePoint(pt);
|
||||||
|
|
||||||
|
if (i == _highlightIndex)
|
||||||
|
{
|
||||||
|
var setting = _highlightSettings[_highlightMode];
|
||||||
|
var size = setting.PointSize;
|
||||||
|
shape = setting.PointType;
|
||||||
|
d *= size; // Example for highlighting
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_highlightIndex >= 0)
|
||||||
|
{
|
||||||
|
_vertex_fill_color = hvertex_fill_color;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_vertex_fill_color = vertex_fill_color;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (shape)
|
||||||
|
{
|
||||||
|
case PointTypeEnum.SQUARE:
|
||||||
|
path.AddRectangle(new RectangleF(point.X - d / 2, point.Y - d / 2, d, d));
|
||||||
|
break;
|
||||||
|
case PointTypeEnum.ROUND:
|
||||||
|
path.AddEllipse(point.X - d / 2, point.Y - d / 2, d, d);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new InvalidOperationException("Unsupported vertex shape");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private void DrawVertex(GraphicsPath path, int i)
|
||||||
|
{
|
||||||
|
PointF pt = _points[i];
|
||||||
|
|
||||||
|
float d = point_size; // Point size
|
||||||
|
PointTypeEnum shape = point_type; // Point shape
|
||||||
|
PointF point = ScalePoint(pt);
|
||||||
|
|
||||||
|
if (i == _highlightIndex)
|
||||||
|
{
|
||||||
|
var setting = _highlightSettings[_highlightMode];
|
||||||
|
var size = setting.PointSize;
|
||||||
|
shape = setting.PointType;
|
||||||
|
d *= size; // Example for highlighting
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_highlightIndex >= 0)
|
||||||
|
{
|
||||||
|
_vertex_fill_color = hvertex_fill_color;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_vertex_fill_color = vertex_fill_color;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (shape)
|
||||||
|
{
|
||||||
|
case PointTypeEnum.SQUARE:
|
||||||
|
path.AddRectangle(new RectangleF(point.X - d / 2, point.Y - d / 2, d, d));
|
||||||
|
break;
|
||||||
|
case PointTypeEnum.ROUND:
|
||||||
|
path.AddEllipse(point.X - d / 2, point.Y - d / 2, d, d);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new InvalidOperationException("Unsupported vertex shape");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 查找离鼠标最近且距离小于阈值的节点
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="point">鼠标位置</param>
|
||||||
|
/// <param name="epsilon">阈值</param>
|
||||||
|
/// <returns>返回节点的索引</returns>
|
||||||
|
public int NearestVertex(PointF point, float epsilon = DFT_VTX_EPSILON)
|
||||||
|
{
|
||||||
|
switch (ShapeType)
|
||||||
|
{
|
||||||
|
case ShapeTypeEnum.Rectangle:
|
||||||
|
{
|
||||||
|
|
||||||
|
for (int i = 0; i < _regionVertex.Length; i++)
|
||||||
|
{
|
||||||
|
if (_regionVertex[i] == null)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (_regionVertex[i].IsVisible(point))
|
||||||
|
{
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
_epsilon = epsilon;
|
||||||
|
float min_distance = float.MaxValue;
|
||||||
|
int min_i = -1;
|
||||||
|
|
||||||
|
PointF scaledPoint = new PointF(point.X * scale, point.Y * scale);
|
||||||
|
|
||||||
|
for (int i = 0; i < _points.Count; i++)
|
||||||
|
{
|
||||||
|
// 缩放顶点
|
||||||
|
PointF scaledVertex = new PointF(_points[i].X * scale, _points[i].Y * scale);
|
||||||
|
float dist = PointHelper.Distance(scaledVertex, scaledPoint);
|
||||||
|
|
||||||
|
// 检查距离是否在 epsilon 范围内
|
||||||
|
if (dist <= epsilon && dist < min_distance)
|
||||||
|
{
|
||||||
|
min_distance = dist;
|
||||||
|
min_i = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return min_i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public int NearestEdge(PointF point, float epsilon)
|
||||||
|
{
|
||||||
|
float min_distance = float.MaxValue;
|
||||||
|
int post_i = -1;
|
||||||
|
|
||||||
|
PointF scaledPoint = new PointF(point.X * scale, point.Y * scale);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
for (int i = 0; i < _points.Count; i++)
|
||||||
|
{
|
||||||
|
// 计算边的两个端点
|
||||||
|
PointF start = new PointF(this[i - 1].X * scale, this[i - 1].Y * scale);
|
||||||
|
PointF end = new PointF(this[i].X * scale, this[i].Y * scale);
|
||||||
|
|
||||||
|
// 计算到线段的距离
|
||||||
|
float dist = PointHelper.DistanceToLine(scaledPoint, start, end);
|
||||||
|
|
||||||
|
// 检查距离是否在 epsilon 范围内
|
||||||
|
if (dist <= epsilon && dist < min_distance)
|
||||||
|
{
|
||||||
|
min_distance = dist;
|
||||||
|
post_i = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return post_i;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public bool ContainsPoint(PointF point)
|
||||||
|
{
|
||||||
|
return MakePath().IsVisible(point);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private GraphicsPath MakePath()
|
||||||
|
{
|
||||||
|
GraphicsPath path = new GraphicsPath();
|
||||||
|
|
||||||
|
if (ShapeType == ShapeTypeEnum.Rectangle)
|
||||||
|
{
|
||||||
|
if (_points.Count == 2)
|
||||||
|
{
|
||||||
|
// 创建矩形路径
|
||||||
|
RectangleF rect = new RectangleF(
|
||||||
|
Math.Min(_points[0].X, _points[1].X),
|
||||||
|
Math.Min(_points[0].Y, _points[1].Y),
|
||||||
|
Math.Abs(_points[1].X - _points[0].X),
|
||||||
|
Math.Abs(_points[1].Y - _points[0].Y));
|
||||||
|
|
||||||
|
path.AddRectangle(rect);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (ShapeType == ShapeTypeEnum.Circle)
|
||||||
|
{
|
||||||
|
if (_points.Count == 2)
|
||||||
|
{
|
||||||
|
// 计算半径
|
||||||
|
float radius = PointHelper.Distance(_points[0], _points[1]);
|
||||||
|
path.AddEllipse(_points[0].X - radius, _points[0].Y - radius, radius * 2, radius * 2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// 处理多边形
|
||||||
|
path.StartFigure();
|
||||||
|
path.AddLine(_points[0], _points[1]);
|
||||||
|
|
||||||
|
for (int i = 2; i < _points.Count; i++)
|
||||||
|
{
|
||||||
|
path.AddLine(_points[i - 1], _points[i]);
|
||||||
|
}
|
||||||
|
path.CloseFigure(); // 结束图形
|
||||||
|
}
|
||||||
|
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public RectangleF BoundingRect()
|
||||||
|
{
|
||||||
|
return MakePath().GetBounds();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public void MoveBy(PointF offset)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < _points.Count; i++)
|
||||||
|
{
|
||||||
|
_points[i] = new PointF(_points[i].X + offset.X, _points[i].Y + offset.Y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 移动特定顶点
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="index"></param>
|
||||||
|
/// <param name="offset"></param>
|
||||||
|
/// <exception cref="ArgumentOutOfRangeException"></exception>
|
||||||
|
public void MoveVertexBy(int index, PointF offset)
|
||||||
|
{
|
||||||
|
if (index >= 0 && index < _points.Count)
|
||||||
|
{
|
||||||
|
_rectSelectedVertex = index;
|
||||||
|
_rectSelectedMoveVertex = new PointF(_points[index].X, _points[index].Y);
|
||||||
|
_points[index] = new PointF(_points[index].X + offset.X, _points[index].Y + offset.Y);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new ArgumentOutOfRangeException(nameof(index), "Index is out of range.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void HighlightVertex(int i, HighlightModeEnum action)
|
||||||
|
{
|
||||||
|
this._highlightIndex = i;
|
||||||
|
this._highlightMode = action;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public void HighlightClear()
|
||||||
|
{
|
||||||
|
_highlightIndex = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public FlyShape Copy()
|
||||||
|
{
|
||||||
|
var jsonStr = JsonConvert.SerializeObject(this);
|
||||||
|
FlyShape copyShp = JsonConvert.DeserializeObject<FlyShape>(jsonStr);
|
||||||
|
return copyShp;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public int Length => _points.Count();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public PointF this[int index]
|
||||||
|
{
|
||||||
|
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (index == -1)
|
||||||
|
{
|
||||||
|
return _points[_points.Count - 1];
|
||||||
|
}
|
||||||
|
return _points[index];
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (index == -1)
|
||||||
|
{
|
||||||
|
_points[_points.Count - 1] = value;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_points[index] = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private void NomalizeRotateAngle()
|
||||||
|
{
|
||||||
|
if (_currentRotateAngle >= 360)
|
||||||
|
{
|
||||||
|
_currentRotateAngle %= 360;
|
||||||
|
}
|
||||||
|
else if (_currentRotateAngle < 0)
|
||||||
|
{
|
||||||
|
_currentRotateAngle = 360 - (-_currentRotateAngle % 360);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
45
CanFly.Canvas/Shape/HighlightSetting.cs
Normal file
45
CanFly.Canvas/Shape/HighlightSetting.cs
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace CanFly.Canvas.Shape
|
||||||
|
{
|
||||||
|
|
||||||
|
public enum PointTypeEnum
|
||||||
|
{
|
||||||
|
SQUARE = 0,
|
||||||
|
ROUND = 1,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public enum HighlightModeEnum
|
||||||
|
{
|
||||||
|
MOVE_VERTEX = 0,
|
||||||
|
NEAR_VERTEX = 1,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
[Serializable]
|
||||||
|
public class HighlightSetting
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
public float PointSize { get; set; }
|
||||||
|
|
||||||
|
|
||||||
|
public PointTypeEnum PointType { get; set; }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public HighlightSetting(float pointSize, PointTypeEnum pointType)
|
||||||
|
{
|
||||||
|
this.PointSize = pointSize;
|
||||||
|
PointType = pointType;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
22
CanFly.Canvas/Shape/ShapeTypeEnum.cs
Normal file
22
CanFly.Canvas/Shape/ShapeTypeEnum.cs
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace CanFly.Canvas.Shape
|
||||||
|
{
|
||||||
|
public enum ShapeTypeEnum
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
Point,
|
||||||
|
Line,
|
||||||
|
Rectangle,
|
||||||
|
Circle,
|
||||||
|
Polygon,
|
||||||
|
LineStrip,
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
56
CanFly.Canvas/UI/FlyCanvas.Designer.cs
generated
Normal file
56
CanFly.Canvas/UI/FlyCanvas.Designer.cs
generated
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
namespace CanFly.Canvas.UI
|
||||||
|
{
|
||||||
|
partial class FlyCanvas
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 必需的设计器变量。
|
||||||
|
/// </summary>
|
||||||
|
private System.ComponentModel.IContainer components = null;
|
||||||
|
|
||||||
|
///// <summary>
|
||||||
|
///// 清理所有正在使用的资源。
|
||||||
|
///// </summary>
|
||||||
|
///// <param name="disposing">如果应释放托管资源,为 true;否则为 false。</param>
|
||||||
|
//protected override void Dispose(bool disposing)
|
||||||
|
//{
|
||||||
|
// if (disposing && (components != null))
|
||||||
|
// {
|
||||||
|
// components.Dispose();
|
||||||
|
// }
|
||||||
|
// base.Dispose(disposing);
|
||||||
|
//}
|
||||||
|
|
||||||
|
#region 组件设计器生成的代码
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 设计器支持所需的方法 - 不要修改
|
||||||
|
/// 使用代码编辑器修改此方法的内容。
|
||||||
|
/// </summary>
|
||||||
|
private void InitializeComponent()
|
||||||
|
{
|
||||||
|
components = new System.ComponentModel.Container();
|
||||||
|
|
||||||
|
SuspendLayout();
|
||||||
|
|
||||||
|
//
|
||||||
|
// Canvas
|
||||||
|
//
|
||||||
|
AutoScaleDimensions = new SizeF(7F, 17F);
|
||||||
|
AutoScaleMode = AutoScaleMode.Font;
|
||||||
|
Margin = new Padding(2);
|
||||||
|
Name = "Canvas";
|
||||||
|
Size = new Size(96, 106);
|
||||||
|
SizeChanged += Canvas_SizeChanged;
|
||||||
|
KeyDown += FlyCanvas_KeyDown;
|
||||||
|
MouseDoubleClick += FlyCanvas_MouseDoubleClick;
|
||||||
|
MouseDown += FlyCanvas_MouseDown;
|
||||||
|
MouseMove += FlyCanvas_OnMouseMove;
|
||||||
|
MouseUp += FlyCanvas_MouseUp;
|
||||||
|
MouseWheel += FlyCanvas_MouseWheel;
|
||||||
|
|
||||||
|
ResumeLayout(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
2019
CanFly.Canvas/UI/FlyCanvas.cs
Normal file
2019
CanFly.Canvas/UI/FlyCanvas.cs
Normal file
File diff suppressed because it is too large
Load Diff
120
CanFly.Canvas/UI/FlyCanvas.resx
Normal file
120
CanFly.Canvas/UI/FlyCanvas.resx
Normal file
@@ -0,0 +1,120 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<root>
|
||||||
|
<!--
|
||||||
|
Microsoft ResX Schema
|
||||||
|
|
||||||
|
Version 2.0
|
||||||
|
|
||||||
|
The primary goals of this format is to allow a simple XML format
|
||||||
|
that is mostly human readable. The generation and parsing of the
|
||||||
|
various data types are done through the TypeConverter classes
|
||||||
|
associated with the data types.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
... ado.net/XML headers & schema ...
|
||||||
|
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||||
|
<resheader name="version">2.0</resheader>
|
||||||
|
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||||
|
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||||
|
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||||
|
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||||
|
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||||
|
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||||
|
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||||
|
<comment>This is a comment</comment>
|
||||||
|
</data>
|
||||||
|
|
||||||
|
There are any number of "resheader" rows that contain simple
|
||||||
|
name/value pairs.
|
||||||
|
|
||||||
|
Each data row contains a name, and value. The row also contains a
|
||||||
|
type or mimetype. Type corresponds to a .NET class that support
|
||||||
|
text/value conversion through the TypeConverter architecture.
|
||||||
|
Classes that don't support this are serialized and stored with the
|
||||||
|
mimetype set.
|
||||||
|
|
||||||
|
The mimetype is used for serialized objects, and tells the
|
||||||
|
ResXResourceReader how to depersist the object. This is currently not
|
||||||
|
extensible. For a given mimetype the value must be set accordingly:
|
||||||
|
|
||||||
|
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||||
|
that the ResXResourceWriter will generate, however the reader can
|
||||||
|
read any of the formats listed below.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.binary.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.soap.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||||
|
value : The object must be serialized into a byte array
|
||||||
|
: using a System.ComponentModel.TypeConverter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
-->
|
||||||
|
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||||
|
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||||
|
<xsd:element name="root" msdata:IsDataSet="true">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:choice maxOccurs="unbounded">
|
||||||
|
<xsd:element name="metadata">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="assembly">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:attribute name="alias" type="xsd:string" />
|
||||||
|
<xsd:attribute name="name" type="xsd:string" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="data">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="resheader">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:choice>
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:schema>
|
||||||
|
<resheader name="resmimetype">
|
||||||
|
<value>text/microsoft-resx</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="version">
|
||||||
|
<value>2.0</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="reader">
|
||||||
|
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="writer">
|
||||||
|
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
</root>
|
||||||
676
CanFly/Helper/HDevEngineTool.cs
Normal file
676
CanFly/Helper/HDevEngineTool.cs
Normal file
@@ -0,0 +1,676 @@
|
|||||||
|
using HalconDotNet;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.Drawing.Imaging;
|
||||||
|
using System.Runtime.ExceptionServices;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
|
namespace CanFly.Helper
|
||||||
|
{
|
||||||
|
public class HDevEngineTool : IDisposable
|
||||||
|
{
|
||||||
|
#region 常量
|
||||||
|
|
||||||
|
// path of external procedures
|
||||||
|
readonly string ProcedurePath = Environment.CurrentDirectory + "\\Vision\\";
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region 成员变量
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 处理过程名
|
||||||
|
/// </summary>
|
||||||
|
public string ProcedureName;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// hdev程序启动引擎
|
||||||
|
/// </summary>
|
||||||
|
private readonly HDevEngine myEngine;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 过程载入工具 .hdvp
|
||||||
|
/// </summary>
|
||||||
|
private HDevProcedureCall procedureCall;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 程序运行是否成功
|
||||||
|
/// </summary>
|
||||||
|
public bool IsSuccessful { get; set; } = false;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 控制参数字典
|
||||||
|
/// </summary>
|
||||||
|
public Dictionary<string, HTuple> InputTupleDic { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 图形参数字典
|
||||||
|
/// </summary>
|
||||||
|
public Dictionary<string, HObject> InputImageDic { get; set; }
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region 初始化
|
||||||
|
/// <summary>
|
||||||
|
/// 实例化 默认搜索路径为: 启动路径//Vision//
|
||||||
|
/// </summary>
|
||||||
|
public HDevEngineTool()
|
||||||
|
{
|
||||||
|
ProcedureName = "";
|
||||||
|
myEngine = new HDevEngine();
|
||||||
|
myEngine.SetProcedurePath(ProcedurePath);
|
||||||
|
|
||||||
|
InputImageDic = new Dictionary<string, HObject>();
|
||||||
|
InputTupleDic = new Dictionary<string, HTuple>();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 实例化
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="path">外部函数搜索路径</param>
|
||||||
|
public HDevEngineTool(string path)
|
||||||
|
{
|
||||||
|
myEngine = new HDevEngine();
|
||||||
|
myEngine.SetProcedurePath(path);
|
||||||
|
|
||||||
|
InputImageDic = new Dictionary<string, HObject>();
|
||||||
|
InputTupleDic = new Dictionary<string, HTuple>();
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 设置函数运行所需参数
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="_tupleDictionary">控制参数</param>
|
||||||
|
/// <param name="_imageDictionary">图形参数</param>
|
||||||
|
public void SetDictionary(Dictionary<string, HTuple> _tupleDictionary, Dictionary<string, HObject> _imageDictionary)
|
||||||
|
{
|
||||||
|
InputTupleDic = _tupleDictionary;
|
||||||
|
InputImageDic = _imageDictionary;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 载入过程 .hdvp
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="procedureName">过程名</param>
|
||||||
|
public void LoadProcedure(string procedureName)
|
||||||
|
{
|
||||||
|
ProcedureName = procedureName;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
HDevProcedure procedure = new HDevProcedure(procedureName);
|
||||||
|
procedureCall = new HDevProcedureCall(procedure);
|
||||||
|
}
|
||||||
|
catch (HDevEngineException Ex)
|
||||||
|
{
|
||||||
|
Trace.TraceInformation("HDevProgram {0} Load fail ,Error Line : {1}, Line number: {2}, Halcon error number : {3}", Ex.ProcedureName, Ex.LineText, Ex.LineNumber, Ex.HalconError);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 执行过程
|
||||||
|
/// </summary>
|
||||||
|
[HandleProcessCorruptedStateExceptions]
|
||||||
|
public bool RunProcedure(out string errorMsg, out int timeElasped)
|
||||||
|
{
|
||||||
|
//lock (_runLock)
|
||||||
|
{
|
||||||
|
errorMsg = "";
|
||||||
|
Stopwatch sw = new Stopwatch();
|
||||||
|
sw.Start();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
foreach (KeyValuePair<string, HTuple> pair in InputTupleDic)
|
||||||
|
{
|
||||||
|
procedureCall.SetInputCtrlParamTuple(pair.Key, pair.Value);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (KeyValuePair<string, HObject> pair in InputImageDic)
|
||||||
|
{
|
||||||
|
procedureCall.SetInputIconicParamObject(pair.Key, pair.Value);
|
||||||
|
}
|
||||||
|
|
||||||
|
procedureCall.Execute();
|
||||||
|
|
||||||
|
IsSuccessful = true;
|
||||||
|
}
|
||||||
|
catch (HDevEngineException ex)
|
||||||
|
{
|
||||||
|
IsSuccessful = false;
|
||||||
|
errorMsg = $"HDevProgram {ex.ProcedureName} Run fail , Line number: {ex.LineNumber}, Halcon error number : {ex.HalconError},ex:{ex.Message}";
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
sw.Stop();
|
||||||
|
timeElasped = (int)sw.ElapsedMilliseconds;
|
||||||
|
}
|
||||||
|
return IsSuccessful;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
object _runLock = new object();
|
||||||
|
/// <summary>
|
||||||
|
/// 执行过程
|
||||||
|
/// </summary>
|
||||||
|
public Tuple<bool, Dictionary<string, HTuple>, Dictionary<string, HObject>, string, int> RunProcedure(Dictionary<string, HTuple> inputHTupleDict, Dictionary<string, HObject> inputImgDict, List<string> outputHTuples = null, List<string> outputObjs = null)
|
||||||
|
{
|
||||||
|
lock (_runLock)
|
||||||
|
{
|
||||||
|
string errorMsg = "";
|
||||||
|
int timeElasped = 0;
|
||||||
|
bool result = false;
|
||||||
|
Dictionary<string, HTuple> outputHTupleDict = new Dictionary<string, HTuple>();
|
||||||
|
Dictionary<string, HObject> outputObjDict = new Dictionary<string, HObject>();
|
||||||
|
|
||||||
|
Stopwatch sw = new Stopwatch();
|
||||||
|
sw.Start();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (inputHTupleDict != null && inputHTupleDict.Count > 0)
|
||||||
|
{
|
||||||
|
foreach (KeyValuePair<string, HTuple> pair in inputHTupleDict)
|
||||||
|
{
|
||||||
|
procedureCall.SetInputCtrlParamTuple(pair.Key, pair.Value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (InputImageDic != null && inputImgDict.Count > 0)
|
||||||
|
{
|
||||||
|
foreach (KeyValuePair<string, HObject> pair in inputImgDict)
|
||||||
|
{
|
||||||
|
procedureCall.SetInputIconicParamObject(pair.Key, pair.Value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
procedureCall.Execute();
|
||||||
|
|
||||||
|
result = true;
|
||||||
|
}
|
||||||
|
catch (HDevEngineException ex)
|
||||||
|
{
|
||||||
|
result = false;
|
||||||
|
errorMsg += $"HDevProgram {ex.ProcedureName} Run fail , Line number: {ex.LineNumber}, Halcon error number : {ex.HalconError},ex:{ex.Message}";
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
sw.Stop();
|
||||||
|
timeElasped = (int)sw.ElapsedMilliseconds;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result)
|
||||||
|
{
|
||||||
|
if (outputHTuples != null && outputHTuples.Count > 0)
|
||||||
|
{
|
||||||
|
outputHTuples.ForEach(t =>
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
outputHTupleDict[t] = procedureCall.GetOutputCtrlParamTuple(t);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
result = false;
|
||||||
|
errorMsg += $"\r\n获取{t}结果异常:{ex.Message}";
|
||||||
|
|
||||||
|
outputHTupleDict[t] = null;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (outputObjs != null && outputObjs.Count > 0)
|
||||||
|
{
|
||||||
|
outputObjs.ForEach(t =>
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
outputObjDict[t] = procedureCall.GetOutputIconicParamObject(t);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
result = false;
|
||||||
|
errorMsg += $"\r\n获取{t}结果异常:{ex.Message}";
|
||||||
|
|
||||||
|
outputObjDict[t] = null;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Tuple<bool, Dictionary<string, HTuple>, Dictionary<string, HObject>, string, int> ret = new Tuple<bool, Dictionary<string, HTuple>, Dictionary<string, HObject>, string, int>(result, outputHTupleDict, outputObjDict, errorMsg, timeElasped);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public HTuple GetResultTuple(string key)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (IsSuccessful)
|
||||||
|
{
|
||||||
|
return procedureCall.GetOutputCtrlParamTuple(key);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return new HTuple();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
return new HTuple();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public HObject GetResultObject(string key, bool ignoreError = false)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (ignoreError || IsSuccessful)
|
||||||
|
{
|
||||||
|
return procedureCall.GetOutputIconicParamObject(key);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return new HObject();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
return new HObject();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
procedureCall?.Dispose();
|
||||||
|
myEngine?.Dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class HalconHelper
|
||||||
|
{
|
||||||
|
[DllImport("kernel32.dll", EntryPoint = "CopyMemory", SetLastError = false)]
|
||||||
|
public static extern void CopyMemory(IntPtr dest, IntPtr src, uint count);
|
||||||
|
|
||||||
|
public static HImage Convert8GrayBitmapToHImage(this Bitmap bmp)
|
||||||
|
{
|
||||||
|
HImage himage = new HImage();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
//判断输入图像不为null
|
||||||
|
if (bmp == null)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
//重绘himage
|
||||||
|
//HImage curImage = new HImage();
|
||||||
|
BitmapData bmpData = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadOnly, PixelFormat.Format8bppIndexed);
|
||||||
|
himage.GenImage1("byte", bmp.Width, bmp.Height, bmpData.Scan0);
|
||||||
|
bmp.UnlockBits(bmpData);
|
||||||
|
//himage = curImage;
|
||||||
|
}
|
||||||
|
return himage;
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Bitmap ConvertHImageToBitmap(this HObject hImage)
|
||||||
|
{
|
||||||
|
HOperatorSet.CountChannels(hImage, out HTuple chanels);
|
||||||
|
if (chanels.I == 1)
|
||||||
|
{
|
||||||
|
return hImage.ConvertHImageTo8GrayBitmap();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return hImage.ConvertHImageToRGBBitmap();
|
||||||
|
//return hImage.HObject2BitmapRGB();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Bitmap HObject2BitmapRGB(this HObject hObject)
|
||||||
|
{
|
||||||
|
////获取图像尺寸
|
||||||
|
HTuple width0, height0, type, width, height;
|
||||||
|
//获取图像尺寸
|
||||||
|
HOperatorSet.GetImageSize(hObject, out width0, out height0);
|
||||||
|
// 创建交错格式图像
|
||||||
|
HOperatorSet.InterleaveChannels(hObject, out HObject InterImage, "argb", "match", 255); //"rgb", 4 * width0, 0 "argb", "match", 255
|
||||||
|
|
||||||
|
//获取交错格式图像指针
|
||||||
|
HOperatorSet.GetImagePointer1(InterImage, out HTuple Pointer, out type, out width, out height);
|
||||||
|
IntPtr ptr = Pointer;
|
||||||
|
//构建新Bitmap图像
|
||||||
|
Bitmap res32 = new Bitmap(width / 4, height, width, PixelFormat.Format32bppArgb, ptr); // Format32bppArgb Format24bppRgb
|
||||||
|
|
||||||
|
//32位Bitmap转24位
|
||||||
|
var res24 = new Bitmap(res32.Width, res32.Height, PixelFormat.Format24bppRgb);
|
||||||
|
Graphics graphics = Graphics.FromImage(res24);
|
||||||
|
graphics.DrawImage(res32, new Rectangle(0, 0, res32.Width, res32.Height));
|
||||||
|
|
||||||
|
return res24;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Bitmap ConvertHImageTo8GrayBitmap(this HObject hImage)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
HTuple type, width, height, pointer;
|
||||||
|
HOperatorSet.GetImagePointer1(hImage, out pointer, out type, out width, out height);
|
||||||
|
|
||||||
|
Bitmap bmp = new Bitmap(width.I, height.I, PixelFormat.Format8bppIndexed);
|
||||||
|
ColorPalette pal = bmp.Palette;
|
||||||
|
for (int i = 0; i <= 255; i++)
|
||||||
|
{
|
||||||
|
pal.Entries[i] = Color.FromArgb(255, i, i, i);
|
||||||
|
}
|
||||||
|
bmp.Palette = pal;
|
||||||
|
|
||||||
|
BitmapData bitmapData = bmp.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.WriteOnly, PixelFormat.Format8bppIndexed);
|
||||||
|
|
||||||
|
if (width % 4 == 0)
|
||||||
|
{
|
||||||
|
CopyMemory(bitmapData.Scan0, (IntPtr)pointer.D, (uint)(bitmapData.Stride * height.I));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Parallel.For(0, height.I, h =>
|
||||||
|
{
|
||||||
|
CopyMemory(bitmapData.Scan0 + h * bitmapData.Stride, (IntPtr)(pointer.D + h * width.I), (uint)width.I);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
bmp.UnlockBits(bitmapData);
|
||||||
|
return bmp;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Bitmap ConvertHImageToRGBBitmap(this HObject hImage)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
HOperatorSet.GetImagePointer3(hImage, out HTuple pointRed, out HTuple pointGreen, out HTuple pointBlue, out HTuple type, out HTuple width, out HTuple height);
|
||||||
|
Bitmap image = new Bitmap(width.I, height.I, PixelFormat.Format24bppRgb);
|
||||||
|
BitmapData imageData = image.LockBits(new Rectangle(0, 0, width.I, height.I), ImageLockMode.ReadWrite, image.PixelFormat);
|
||||||
|
IntPtr pR = (IntPtr)pointRed.D;
|
||||||
|
IntPtr pG = (IntPtr)pointGreen.D;
|
||||||
|
IntPtr pB = (IntPtr)pointBlue.D;
|
||||||
|
Parallel.For(0, imageData.Height, h =>
|
||||||
|
{
|
||||||
|
Parallel.For(0, imageData.Width, w =>
|
||||||
|
{
|
||||||
|
int dest = h * imageData.Stride + w * 3;
|
||||||
|
int source = h * imageData.Width + w;
|
||||||
|
|
||||||
|
Marshal.WriteByte(imageData.Scan0, dest, Marshal.ReadByte(pB, source));
|
||||||
|
Marshal.WriteByte(imageData.Scan0, dest + 1, Marshal.ReadByte(pG, source));
|
||||||
|
Marshal.WriteByte(imageData.Scan0, dest + 2, Marshal.ReadByte(pR, source));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
image.UnlockBits(imageData);
|
||||||
|
return image;
|
||||||
|
}
|
||||||
|
catch (Exception exc)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Bitmap ConvertHImageTo16GrayBitmap(this HImage originHImage)
|
||||||
|
{
|
||||||
|
//IntPtr pointer = hImage.GetImagePointer1(out string type, out int width, out int height);
|
||||||
|
|
||||||
|
//int widthIn4 = (int)Math.Ceiling(width / 4.0) * 4;
|
||||||
|
|
||||||
|
////Bitmap bmp = new Bitmap(widthIn4, height, PixelFormat.Format48bppRgb);
|
||||||
|
//Bitmap showImage = new Bitmap(widthIn4, height, PixelFormat.Format48bppRgb);
|
||||||
|
|
||||||
|
//Rectangle rect = new Rectangle(0, 0, widthIn4, height);
|
||||||
|
////BitmapData bitmapData = bmp.LockBits(rect, ImageLockMode.WriteOnly, PixelFormat.Format48bppRgb);
|
||||||
|
//BitmapData showImageData = showImage.LockBits(rect, ImageLockMode.WriteOnly, PixelFormat.Format48bppRgb);
|
||||||
|
//unsafe
|
||||||
|
//{
|
||||||
|
// byte* data = (byte*)pointer;
|
||||||
|
// //byte* bitmapBuffer = (byte*)bitmapData.Scan0;
|
||||||
|
// byte* showBitmapBuffer = (byte*)showImageData.Scan0;
|
||||||
|
|
||||||
|
// Parallel.For(0, width * height, i =>
|
||||||
|
// {
|
||||||
|
// int index = (i + 1) % width + widthIn4 * ((int)Math.Floor((double)(i + 1) / width)) - 1;
|
||||||
|
|
||||||
|
// //showBitmapBuffer[index * 6] = bitmapBuffer[index * 6] = data[i * 2];
|
||||||
|
// //showBitmapBuffer[index * 6 + 1] = bitmapBuffer[index * 6 + 1] = data[i * 2 + 1];
|
||||||
|
// showBitmapBuffer[index * 6] = data[i * 2];
|
||||||
|
// showBitmapBuffer[index * 6 + 1] = data[i * 2 + 1];
|
||||||
|
// });
|
||||||
|
//}
|
||||||
|
|
||||||
|
////bmp.UnlockBits(bitmapData);
|
||||||
|
//showImage.UnlockBits(showImageData);
|
||||||
|
|
||||||
|
//return showImage;
|
||||||
|
|
||||||
|
// dev_set_draw('margin')
|
||||||
|
//read_image(Image, '0.tif')
|
||||||
|
|
||||||
|
HImage hImage = originHImage.Clone();
|
||||||
|
|
||||||
|
//* 如果16位图像非常暗的话,建议在这一步进行提亮,因为后面8位图像大幅度提亮易造成色阶断裂,出现不连续的像素块
|
||||||
|
// * scale_image(Image, Image, 25, 0)
|
||||||
|
//hImage = hImage.ScaleImage(25.0, 0.0);
|
||||||
|
|
||||||
|
//get_domain(Image, rectangle)
|
||||||
|
//* 获取全图中像素灰度值的最大和最小值
|
||||||
|
//min_max_gray(rectangle, Image, 0, Min, Max, range)
|
||||||
|
hImage.MinMaxGray(hImage.GetDomain(), 0, out double min, out double max, out double range);
|
||||||
|
|
||||||
|
//* 将16位图的灰度值映射到0 - 255上
|
||||||
|
double mult = 255.0 / (max - min);
|
||||||
|
double add = -mult * min;
|
||||||
|
hImage = hImage.ScaleImage(mult, add);
|
||||||
|
|
||||||
|
//* 转换为'byte'类型
|
||||||
|
//convert_image_type(Image_scaled, ImageConverted, 'byte')
|
||||||
|
hImage = hImage.ConvertImageType("byte");
|
||||||
|
|
||||||
|
Bitmap showImage = hImage.ConvertHImageTo8GrayBitmap();
|
||||||
|
|
||||||
|
hImage.Dispose();
|
||||||
|
|
||||||
|
return showImage;
|
||||||
|
|
||||||
|
//* 如果转换以后图像整体对比度太低的话,可以提高对比度(这里是对8位图像处理)
|
||||||
|
//Min:= 20
|
||||||
|
//Max:= 160
|
||||||
|
//Mult:= 255.0 / (Max - Min)
|
||||||
|
//Add:= -Mult * Min
|
||||||
|
//scale_image(ImageConverted, ImageConverted_scaled, Mult, Add)
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<double> HTupleToDouble(this HTuple tuple)
|
||||||
|
{
|
||||||
|
List<double> list = new List<double>();
|
||||||
|
|
||||||
|
for (int i = 0; i < tuple.Length; i++)
|
||||||
|
{
|
||||||
|
list.Add(tuple[i].D);
|
||||||
|
}
|
||||||
|
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public static HImage ConvertHObjectToHImage(this HObject obj)
|
||||||
|
{
|
||||||
|
HOperatorSet.CountChannels(obj, out HTuple channels);
|
||||||
|
|
||||||
|
HImage img = new HImage();
|
||||||
|
if (channels.I == 1)
|
||||||
|
{
|
||||||
|
HTuple pointer, type, width, height;
|
||||||
|
HOperatorSet.GetImagePointer1(obj, out pointer, out type, out width, out height);
|
||||||
|
|
||||||
|
img.GenImage1(type, width, height, pointer);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
HTuple pRed, pGreen, pBlue, type, width, height;
|
||||||
|
HOperatorSet.GetImagePointer3(obj, out pRed, out pGreen, out pBlue, out type, out width, out height);
|
||||||
|
|
||||||
|
img.GenImage3(type, width, height, pRed, pGreen, pBlue);
|
||||||
|
}
|
||||||
|
|
||||||
|
return img;
|
||||||
|
}
|
||||||
|
|
||||||
|
#region 灰度图转换为伪彩图
|
||||||
|
public static Bitmap ConvertGrayImageToPesudoColorfulImage(this HImage hImage, double max = 0, double min = 0, double zoom = 1, bool isShowHeightTip = false, int zResolution = 100000)
|
||||||
|
{
|
||||||
|
hImage.GetImageSize(out int width, out int height);
|
||||||
|
hImage.MinMaxGray(new HRegion(0.0, 0.0, width, height), 3, out HTuple roiMin, out HTuple roiMax, out _);
|
||||||
|
|
||||||
|
if (max == 0)
|
||||||
|
{
|
||||||
|
max = roiMax;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (min == 0)
|
||||||
|
{
|
||||||
|
min = roiMin;
|
||||||
|
}
|
||||||
|
|
||||||
|
double mult = 235 / (zoom * (max - min));
|
||||||
|
double add = (0 - mult) * min * zoom + 10;
|
||||||
|
HOperatorSet.ScaleImage(hImage, out HObject imageScaled, mult, add);
|
||||||
|
HOperatorSet.ConvertImageType(imageScaled, out imageScaled, "byte");
|
||||||
|
Stopwatch sw = new Stopwatch();
|
||||||
|
sw.Start();
|
||||||
|
|
||||||
|
HOperatorSet.GetImagePointer1(imageScaled, out HTuple pointer, out HTuple type, out _, out _);
|
||||||
|
Bitmap bitmap = new Bitmap(width, height, PixelFormat.Format24bppRgb);
|
||||||
|
BitmapData bitmapData = bitmap.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadWrite, bitmap.PixelFormat);
|
||||||
|
|
||||||
|
unsafe
|
||||||
|
{
|
||||||
|
byte* data = (byte*)(IntPtr)pointer;
|
||||||
|
byte* bitmapDataBuff = (byte*)bitmapData.Scan0;
|
||||||
|
|
||||||
|
if (width % 4 != 0)
|
||||||
|
{
|
||||||
|
Parallel.For(0, height, h =>
|
||||||
|
{
|
||||||
|
Parallel.For(0, width, w =>
|
||||||
|
{
|
||||||
|
byte gray = data[h * width + w];
|
||||||
|
byte[] convertBytes = ConvertByteToColorfulArray(gray);
|
||||||
|
|
||||||
|
Marshal.Copy(convertBytes, 0, (IntPtr)(bitmapDataBuff + h * bitmapData.Stride + w * 3), 3);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Parallel.For(0, width * height, i =>
|
||||||
|
{
|
||||||
|
byte gray = data[i];
|
||||||
|
byte[] convertBytes = ConvertByteToColorfulArray(gray);
|
||||||
|
|
||||||
|
Marshal.Copy(convertBytes, 0, (IntPtr)(bitmapDataBuff + i * 3), 3);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
bitmap.UnlockBits(bitmapData);
|
||||||
|
|
||||||
|
if (isShowHeightTip)
|
||||||
|
{
|
||||||
|
List<byte> lableList = new List<byte>() { 5, 30, 60, 90, 120, 150, 180, 210, 240, 255 };
|
||||||
|
Dictionary<double, Color> lableColorDict = lableList.ToDictionary(
|
||||||
|
u => (u - add) / (mult * zResolution),
|
||||||
|
u =>
|
||||||
|
{
|
||||||
|
byte[] colorBytes = ConvertByteToColorfulArray(u);
|
||||||
|
return Color.FromArgb(colorBytes[2], colorBytes[1], colorBytes[0]);
|
||||||
|
});
|
||||||
|
|
||||||
|
using (Graphics g = Graphics.FromImage(bitmap))
|
||||||
|
{
|
||||||
|
int rectHeight = (int)(bitmap.Height / (5.0 * lableColorDict.Count));
|
||||||
|
Font font = new Font("宋体", (int)(rectHeight * 0.75), GraphicsUnit.Pixel);
|
||||||
|
|
||||||
|
string lable = lableColorDict.ElementAt(0).Key.ToString("f3");
|
||||||
|
SizeF lableSize = g.MeasureString(lable, font);
|
||||||
|
int rectWidth = (int)(lableSize.Width * 1.5);
|
||||||
|
|
||||||
|
int startX = 0;
|
||||||
|
int startY = 0;
|
||||||
|
foreach (KeyValuePair<double, Color> pair in lableColorDict)
|
||||||
|
{
|
||||||
|
g.FillRectangle(new SolidBrush(pair.Value), startX, startY, rectWidth, rectHeight);
|
||||||
|
g.DrawString(pair.Key.ToString("f3"), font, new SolidBrush(Color.White), (float)(startX + (rectWidth - lableSize.Width) / 2.0), (float)(startY + (rectHeight - lableSize.Height) / 2.0));
|
||||||
|
|
||||||
|
startY += rectHeight;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sw.Stop();
|
||||||
|
//LogAsync(DateTime.Now, EnumHelper.LogLevel.Information, $"转换耗时{sw.ElapsedMilliseconds}ms");
|
||||||
|
return bitmap;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static byte[] ConvertByteToColorfulArray(byte gray)
|
||||||
|
{
|
||||||
|
byte[] bytes = new byte[3];
|
||||||
|
if (gray == 0)
|
||||||
|
{
|
||||||
|
bytes[2] = 255;
|
||||||
|
bytes[1] = 255;
|
||||||
|
bytes[0] = 255;
|
||||||
|
}
|
||||||
|
if (gray > 0 && gray <= 63)
|
||||||
|
{
|
||||||
|
bytes[2] = 0;
|
||||||
|
bytes[+1] = (byte)(254 - 4 * gray);
|
||||||
|
bytes[0] = 255;
|
||||||
|
}
|
||||||
|
if (gray >= 64 && gray <= 127)
|
||||||
|
{
|
||||||
|
bytes[2] = 0;
|
||||||
|
bytes[1] = (byte)(4 * gray - 254);
|
||||||
|
bytes[0] = (byte)(510 - 4 * gray);
|
||||||
|
}
|
||||||
|
if (gray >= 128 && gray <= 191)
|
||||||
|
{
|
||||||
|
bytes[2] = (byte)(4 * gray - 510);
|
||||||
|
bytes[1] = 255;
|
||||||
|
bytes[0] = 0;
|
||||||
|
}
|
||||||
|
if (gray >= 192 && gray <= 255)
|
||||||
|
{
|
||||||
|
bytes[2] = 255;
|
||||||
|
bytes[1] = (byte)(1022 - 4 * gray);
|
||||||
|
bytes[0] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return bytes;
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
17
CanFly/Program.cs
Normal file
17
CanFly/Program.cs
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
namespace CanFly
|
||||||
|
{
|
||||||
|
//internal static class Program
|
||||||
|
//{
|
||||||
|
// /// <summary>
|
||||||
|
// /// The main entry point for the application.
|
||||||
|
// /// </summary>
|
||||||
|
// [STAThread]
|
||||||
|
// static void Main()
|
||||||
|
// {
|
||||||
|
// // To customize application configuration such as set high DPI settings or default font,
|
||||||
|
// // see https://aka.ms/applicationconfiguration.
|
||||||
|
// ApplicationConfiguration.Initialize();
|
||||||
|
// Application.Run(new FrmMain2());
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
}
|
||||||
73
CanFly/Properties/Resources.Designer.cs
generated
Normal file
73
CanFly/Properties/Resources.Designer.cs
generated
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// <auto-generated>
|
||||||
|
// 此代码由工具生成。
|
||||||
|
// 运行时版本:4.0.30319.42000
|
||||||
|
//
|
||||||
|
// 对此文件的更改可能会导致不正确的行为,并且如果
|
||||||
|
// 重新生成代码,这些更改将会丢失。
|
||||||
|
// </auto-generated>
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
namespace XKRS.CanFly.Properties {
|
||||||
|
using System;
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 一个强类型的资源类,用于查找本地化的字符串等。
|
||||||
|
/// </summary>
|
||||||
|
// 此类是由 StronglyTypedResourceBuilder
|
||||||
|
// 类通过类似于 ResGen 或 Visual Studio 的工具自动生成的。
|
||||||
|
// 若要添加或移除成员,请编辑 .ResX 文件,然后重新运行 ResGen
|
||||||
|
// (以 /str 作为命令选项),或重新生成 VS 项目。
|
||||||
|
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
|
||||||
|
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||||
|
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||||
|
internal class Resources {
|
||||||
|
|
||||||
|
private static global::System.Resources.ResourceManager resourceMan;
|
||||||
|
|
||||||
|
private static global::System.Globalization.CultureInfo resourceCulture;
|
||||||
|
|
||||||
|
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
|
||||||
|
internal Resources() {
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 返回此类使用的缓存的 ResourceManager 实例。
|
||||||
|
/// </summary>
|
||||||
|
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||||
|
internal static global::System.Resources.ResourceManager ResourceManager {
|
||||||
|
get {
|
||||||
|
if (object.ReferenceEquals(resourceMan, null)) {
|
||||||
|
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("XKRS.CanFly.Properties.Resources", typeof(Resources).Assembly);
|
||||||
|
resourceMan = temp;
|
||||||
|
}
|
||||||
|
return resourceMan;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 重写当前线程的 CurrentUICulture 属性,对
|
||||||
|
/// 使用此强类型资源类的所有资源查找执行重写。
|
||||||
|
/// </summary>
|
||||||
|
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||||
|
internal static global::System.Globalization.CultureInfo Culture {
|
||||||
|
get {
|
||||||
|
return resourceCulture;
|
||||||
|
}
|
||||||
|
set {
|
||||||
|
resourceCulture = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 查找 System.Drawing.Bitmap 类型的本地化资源。
|
||||||
|
/// </summary>
|
||||||
|
internal static System.Drawing.Bitmap Close {
|
||||||
|
get {
|
||||||
|
object obj = ResourceManager.GetObject("Close", resourceCulture);
|
||||||
|
return ((System.Drawing.Bitmap)(obj));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
124
CanFly/Properties/Resources.resx
Normal file
124
CanFly/Properties/Resources.resx
Normal file
@@ -0,0 +1,124 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<root>
|
||||||
|
<!--
|
||||||
|
Microsoft ResX Schema
|
||||||
|
|
||||||
|
Version 2.0
|
||||||
|
|
||||||
|
The primary goals of this format is to allow a simple XML format
|
||||||
|
that is mostly human readable. The generation and parsing of the
|
||||||
|
various data types are done through the TypeConverter classes
|
||||||
|
associated with the data types.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
... ado.net/XML headers & schema ...
|
||||||
|
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||||
|
<resheader name="version">2.0</resheader>
|
||||||
|
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||||
|
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||||
|
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||||
|
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||||
|
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||||
|
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||||
|
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||||
|
<comment>This is a comment</comment>
|
||||||
|
</data>
|
||||||
|
|
||||||
|
There are any number of "resheader" rows that contain simple
|
||||||
|
name/value pairs.
|
||||||
|
|
||||||
|
Each data row contains a name, and value. The row also contains a
|
||||||
|
type or mimetype. Type corresponds to a .NET class that support
|
||||||
|
text/value conversion through the TypeConverter architecture.
|
||||||
|
Classes that don't support this are serialized and stored with the
|
||||||
|
mimetype set.
|
||||||
|
|
||||||
|
The mimetype is used for serialized objects, and tells the
|
||||||
|
ResXResourceReader how to depersist the object. This is currently not
|
||||||
|
extensible. For a given mimetype the value must be set accordingly:
|
||||||
|
|
||||||
|
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||||
|
that the ResXResourceWriter will generate, however the reader can
|
||||||
|
read any of the formats listed below.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.binary.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.soap.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||||
|
value : The object must be serialized into a byte array
|
||||||
|
: using a System.ComponentModel.TypeConverter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
-->
|
||||||
|
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||||
|
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||||
|
<xsd:element name="root" msdata:IsDataSet="true">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:choice maxOccurs="unbounded">
|
||||||
|
<xsd:element name="metadata">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="assembly">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:attribute name="alias" type="xsd:string" />
|
||||||
|
<xsd:attribute name="name" type="xsd:string" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="data">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="resheader">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:choice>
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:schema>
|
||||||
|
<resheader name="resmimetype">
|
||||||
|
<value>text/microsoft-resx</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="version">
|
||||||
|
<value>2.0</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="reader">
|
||||||
|
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="writer">
|
||||||
|
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
|
||||||
|
<data name="Close" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||||
|
<value>..\Resources\Close.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||||
|
</data>
|
||||||
|
</root>
|
||||||
BIN
CanFly/Resources/Close.png
Normal file
BIN
CanFly/Resources/Close.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 836 B |
BIN
CanFly/Resources/circle.png
Normal file
BIN
CanFly/Resources/circle.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.0 KiB |
117
CanFly/UI/BaseFrmGuide.Designer.cs
generated
Normal file
117
CanFly/UI/BaseFrmGuide.Designer.cs
generated
Normal file
@@ -0,0 +1,117 @@
|
|||||||
|
namespace CanFly.UI
|
||||||
|
{
|
||||||
|
partial class BaseFrmGuide
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Required designer variable.
|
||||||
|
/// </summary>
|
||||||
|
private System.ComponentModel.IContainer components = null;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Clean up any resources being used.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||||
|
protected override void Dispose(bool disposing)
|
||||||
|
{
|
||||||
|
if (disposing && (components != null))
|
||||||
|
{
|
||||||
|
components.Dispose();
|
||||||
|
}
|
||||||
|
base.Dispose(disposing);
|
||||||
|
}
|
||||||
|
|
||||||
|
#region Windows Form Designer generated code
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Required method for Designer support - do not modify
|
||||||
|
/// the contents of this method with the code editor.
|
||||||
|
/// </summary>
|
||||||
|
private void InitializeComponent()
|
||||||
|
{
|
||||||
|
flowLayoutPanel = new FlowLayoutPanel();
|
||||||
|
pbLogo = new PictureBox();
|
||||||
|
lblTitle = new Label();
|
||||||
|
flowPanelContent = new FlowLayoutPanel();
|
||||||
|
panelMain = new Panel();
|
||||||
|
flowLayoutPanel.SuspendLayout();
|
||||||
|
((System.ComponentModel.ISupportInitialize)pbLogo).BeginInit();
|
||||||
|
panelMain.SuspendLayout();
|
||||||
|
SuspendLayout();
|
||||||
|
//
|
||||||
|
// flowLayoutPanel
|
||||||
|
//
|
||||||
|
flowLayoutPanel.Controls.Add(pbLogo);
|
||||||
|
flowLayoutPanel.Controls.Add(lblTitle);
|
||||||
|
flowLayoutPanel.Dock = DockStyle.Top;
|
||||||
|
flowLayoutPanel.Location = new Point(0, 0);
|
||||||
|
flowLayoutPanel.Name = "flowLayoutPanel1";
|
||||||
|
flowLayoutPanel.Size = new Size(692, 36);
|
||||||
|
flowLayoutPanel.TabIndex = 0;
|
||||||
|
//
|
||||||
|
// pbLogo
|
||||||
|
//
|
||||||
|
pbLogo.Location = new Point(3, 3);
|
||||||
|
pbLogo.Name = "pbLogo";
|
||||||
|
pbLogo.Size = new Size(30, 30);
|
||||||
|
pbLogo.SizeMode = PictureBoxSizeMode.StretchImage;
|
||||||
|
pbLogo.TabIndex = 0;
|
||||||
|
pbLogo.TabStop = false;
|
||||||
|
pbLogo.Visible = false;
|
||||||
|
//
|
||||||
|
// lblTitle
|
||||||
|
//
|
||||||
|
lblTitle.AutoSize = true;
|
||||||
|
lblTitle.Dock = DockStyle.Fill;
|
||||||
|
lblTitle.Font = new Font("Microsoft YaHei UI", 12F, FontStyle.Bold, GraphicsUnit.Point);
|
||||||
|
lblTitle.Location = new Point(39, 0);
|
||||||
|
lblTitle.Name = "lblTitle";
|
||||||
|
lblTitle.Size = new Size(20, 36);
|
||||||
|
lblTitle.TabIndex = 1;
|
||||||
|
lblTitle.Text = " ";
|
||||||
|
lblTitle.TextAlign = ContentAlignment.MiddleLeft;
|
||||||
|
//
|
||||||
|
// flowPanelContent
|
||||||
|
//
|
||||||
|
flowPanelContent.Dock = DockStyle.Fill;
|
||||||
|
flowPanelContent.Location = new Point(0, 0);
|
||||||
|
flowPanelContent.Name = "flowPanelContent";
|
||||||
|
flowPanelContent.Size = new Size(692, 511);
|
||||||
|
flowPanelContent.TabIndex = 1;
|
||||||
|
//
|
||||||
|
// panelMain
|
||||||
|
//
|
||||||
|
panelMain.AutoScroll = true;
|
||||||
|
panelMain.Controls.Add(flowPanelContent);
|
||||||
|
panelMain.Dock = DockStyle.Fill;
|
||||||
|
panelMain.Location = new Point(0, 36);
|
||||||
|
panelMain.Name = "panelMain";
|
||||||
|
panelMain.Size = new Size(692, 511);
|
||||||
|
panelMain.TabIndex = 2;
|
||||||
|
//
|
||||||
|
// BaseFrmGuide
|
||||||
|
//
|
||||||
|
AutoScaleDimensions = new SizeF(7F, 17F);
|
||||||
|
AutoScaleMode = AutoScaleMode.Font;
|
||||||
|
ClientSize = new Size(692, 547);
|
||||||
|
Controls.Add(panelMain);
|
||||||
|
Controls.Add(flowLayoutPanel);
|
||||||
|
FormBorderStyle = FormBorderStyle.None;
|
||||||
|
Name = "BaseFrmGuide";
|
||||||
|
Text = "BaseFrmGuide";
|
||||||
|
Load += BaseFrmGuide_Load;
|
||||||
|
flowLayoutPanel.ResumeLayout(false);
|
||||||
|
flowLayoutPanel.PerformLayout();
|
||||||
|
((System.ComponentModel.ISupportInitialize)pbLogo).EndInit();
|
||||||
|
panelMain.ResumeLayout(false);
|
||||||
|
ResumeLayout(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
private FlowLayoutPanel flowLayoutPanel;
|
||||||
|
private PictureBox pbLogo;
|
||||||
|
private Label lblTitle;
|
||||||
|
protected FlowLayoutPanel flowPanelContent;
|
||||||
|
private Panel panelMain;
|
||||||
|
}
|
||||||
|
}
|
||||||
53
CanFly/UI/BaseFrmGuide.cs
Normal file
53
CanFly/UI/BaseFrmGuide.cs
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.ComponentModel;
|
||||||
|
using System.Data;
|
||||||
|
using System.Drawing;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Windows.Forms;
|
||||||
|
|
||||||
|
namespace CanFly.UI
|
||||||
|
{
|
||||||
|
public partial class BaseFrmGuide : Form
|
||||||
|
{
|
||||||
|
public BaseFrmGuide()
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
|
||||||
|
// 处理 Panel 的大小变化事件,以动态更新控件宽度
|
||||||
|
panelMain.SizeChanged += PanelMain_SizeChanged; ;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void PanelMain_SizeChanged(object? sender, EventArgs e)
|
||||||
|
{
|
||||||
|
foreach (Control control in flowPanelContent.Controls)
|
||||||
|
{
|
||||||
|
control.Width = panelMain.Width - 6; // 根据 Panel 的宽度调整控件
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void SetTitle(string title)
|
||||||
|
{
|
||||||
|
this.lblTitle.Text = title;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void SetLogo(Image logo)
|
||||||
|
{
|
||||||
|
this.pbLogo.BackgroundImage = logo;
|
||||||
|
this.pbLogo.SizeMode = PictureBoxSizeMode.StretchImage;
|
||||||
|
this.pbLogo.Refresh();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void BaseFrmGuide_Load(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
120
CanFly/UI/BaseFrmGuide.resx
Normal file
120
CanFly/UI/BaseFrmGuide.resx
Normal file
@@ -0,0 +1,120 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<root>
|
||||||
|
<!--
|
||||||
|
Microsoft ResX Schema
|
||||||
|
|
||||||
|
Version 2.0
|
||||||
|
|
||||||
|
The primary goals of this format is to allow a simple XML format
|
||||||
|
that is mostly human readable. The generation and parsing of the
|
||||||
|
various data types are done through the TypeConverter classes
|
||||||
|
associated with the data types.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
... ado.net/XML headers & schema ...
|
||||||
|
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||||
|
<resheader name="version">2.0</resheader>
|
||||||
|
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||||
|
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||||
|
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||||
|
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||||
|
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||||
|
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||||
|
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||||
|
<comment>This is a comment</comment>
|
||||||
|
</data>
|
||||||
|
|
||||||
|
There are any number of "resheader" rows that contain simple
|
||||||
|
name/value pairs.
|
||||||
|
|
||||||
|
Each data row contains a name, and value. The row also contains a
|
||||||
|
type or mimetype. Type corresponds to a .NET class that support
|
||||||
|
text/value conversion through the TypeConverter architecture.
|
||||||
|
Classes that don't support this are serialized and stored with the
|
||||||
|
mimetype set.
|
||||||
|
|
||||||
|
The mimetype is used for serialized objects, and tells the
|
||||||
|
ResXResourceReader how to depersist the object. This is currently not
|
||||||
|
extensible. For a given mimetype the value must be set accordingly:
|
||||||
|
|
||||||
|
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||||
|
that the ResXResourceWriter will generate, however the reader can
|
||||||
|
read any of the formats listed below.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.binary.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.soap.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||||
|
value : The object must be serialized into a byte array
|
||||||
|
: using a System.ComponentModel.TypeConverter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
-->
|
||||||
|
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||||
|
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||||
|
<xsd:element name="root" msdata:IsDataSet="true">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:choice maxOccurs="unbounded">
|
||||||
|
<xsd:element name="metadata">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="assembly">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:attribute name="alias" type="xsd:string" />
|
||||||
|
<xsd:attribute name="name" type="xsd:string" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="data">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="resheader">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:choice>
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:schema>
|
||||||
|
<resheader name="resmimetype">
|
||||||
|
<value>text/microsoft-resx</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="version">
|
||||||
|
<value>2.0</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="reader">
|
||||||
|
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="writer">
|
||||||
|
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
</root>
|
||||||
279
CanFly/UI/FrmMain.Designer.cs
generated
Normal file
279
CanFly/UI/FrmMain.Designer.cs
generated
Normal file
@@ -0,0 +1,279 @@
|
|||||||
|
|
||||||
|
|
||||||
|
namespace CanFly
|
||||||
|
{
|
||||||
|
partial class FrmMain
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Required designer variable.
|
||||||
|
/// </summary>
|
||||||
|
private System.ComponentModel.IContainer components = null;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Clean up any resources being used.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||||
|
protected override void Dispose(bool disposing)
|
||||||
|
{
|
||||||
|
if (disposing && (components != null))
|
||||||
|
{
|
||||||
|
components.Dispose();
|
||||||
|
}
|
||||||
|
base.Dispose(disposing);
|
||||||
|
}
|
||||||
|
|
||||||
|
#region Windows Form Designer generated code
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Required method for Designer support - do not modify
|
||||||
|
/// the contents of this method with the code editor.
|
||||||
|
/// </summary>
|
||||||
|
private void InitializeComponent()
|
||||||
|
{
|
||||||
|
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(FrmMain));
|
||||||
|
panel1 = new Panel();
|
||||||
|
canvas = new Canvas.UI.FlyCanvas();
|
||||||
|
statusStrip1 = new StatusStrip();
|
||||||
|
lblStatus = new ToolStripStatusLabel();
|
||||||
|
flowLayoutPanel1 = new FlowLayoutPanel();
|
||||||
|
btnLoadImage = new Button();
|
||||||
|
btnCreateCircle = new Button();
|
||||||
|
btnCreateRect = new Button();
|
||||||
|
btnStopDraw = new Button();
|
||||||
|
btnTestOutsideDraw = new Button();
|
||||||
|
btnTestClearDraw = new Button();
|
||||||
|
btnTestCircleMeasure = new Button();
|
||||||
|
btnTest = new Button();
|
||||||
|
splitContainer = new SplitContainer();
|
||||||
|
panelGuide = new Panel();
|
||||||
|
btnRotateTest = new Button();
|
||||||
|
panel1.SuspendLayout();
|
||||||
|
statusStrip1.SuspendLayout();
|
||||||
|
flowLayoutPanel1.SuspendLayout();
|
||||||
|
((System.ComponentModel.ISupportInitialize)splitContainer).BeginInit();
|
||||||
|
splitContainer.Panel1.SuspendLayout();
|
||||||
|
splitContainer.Panel2.SuspendLayout();
|
||||||
|
splitContainer.SuspendLayout();
|
||||||
|
SuspendLayout();
|
||||||
|
//
|
||||||
|
// panel1
|
||||||
|
//
|
||||||
|
panel1.BorderStyle = BorderStyle.FixedSingle;
|
||||||
|
panel1.Controls.Add(canvas);
|
||||||
|
panel1.Controls.Add(statusStrip1);
|
||||||
|
panel1.Dock = DockStyle.Fill;
|
||||||
|
panel1.Location = new Point(0, 0);
|
||||||
|
panel1.Name = "panel1";
|
||||||
|
panel1.Size = new Size(947, 791);
|
||||||
|
panel1.TabIndex = 1;
|
||||||
|
//
|
||||||
|
// canvas
|
||||||
|
//
|
||||||
|
canvas.AllowMultiSelect = false;
|
||||||
|
canvas.CreateMode = Canvas.Shape.ShapeTypeEnum.Polygon;
|
||||||
|
canvas.Dock = DockStyle.Fill;
|
||||||
|
canvas.Enabled = false;
|
||||||
|
canvas.FillDrawing = false;
|
||||||
|
canvas.Location = new Point(0, 0);
|
||||||
|
canvas.Margin = new Padding(2);
|
||||||
|
canvas.Name = "canvas";
|
||||||
|
canvas.OutsideShapes = (List<Canvas.Shape.FlyShape>)resources.GetObject("canvas.OutsideShapes");
|
||||||
|
canvas.Scale = 1F;
|
||||||
|
canvas.Shapes = (List<Canvas.Shape.FlyShape>)resources.GetObject("canvas.Shapes");
|
||||||
|
canvas.Size = new Size(945, 767);
|
||||||
|
canvas.TabIndex = 2;
|
||||||
|
//
|
||||||
|
// statusStrip1
|
||||||
|
//
|
||||||
|
statusStrip1.Items.AddRange(new ToolStripItem[] { lblStatus });
|
||||||
|
statusStrip1.Location = new Point(0, 767);
|
||||||
|
statusStrip1.Name = "statusStrip1";
|
||||||
|
statusStrip1.Size = new Size(945, 22);
|
||||||
|
statusStrip1.TabIndex = 1;
|
||||||
|
statusStrip1.Text = "statusStrip1";
|
||||||
|
//
|
||||||
|
// lblStatus
|
||||||
|
//
|
||||||
|
lblStatus.Name = "lblStatus";
|
||||||
|
lblStatus.Size = new Size(44, 17);
|
||||||
|
lblStatus.Text = " ";
|
||||||
|
//
|
||||||
|
// flowLayoutPanel1
|
||||||
|
//
|
||||||
|
flowLayoutPanel1.BorderStyle = BorderStyle.FixedSingle;
|
||||||
|
flowLayoutPanel1.Controls.Add(btnLoadImage);
|
||||||
|
flowLayoutPanel1.Controls.Add(btnCreateCircle);
|
||||||
|
flowLayoutPanel1.Controls.Add(btnCreateRect);
|
||||||
|
flowLayoutPanel1.Controls.Add(btnStopDraw);
|
||||||
|
flowLayoutPanel1.Controls.Add(btnTestOutsideDraw);
|
||||||
|
flowLayoutPanel1.Controls.Add(btnTestClearDraw);
|
||||||
|
flowLayoutPanel1.Controls.Add(btnTestCircleMeasure);
|
||||||
|
flowLayoutPanel1.Controls.Add(btnTest);
|
||||||
|
flowLayoutPanel1.Controls.Add(btnRotateTest);
|
||||||
|
flowLayoutPanel1.Dock = DockStyle.Top;
|
||||||
|
flowLayoutPanel1.Location = new Point(0, 0);
|
||||||
|
flowLayoutPanel1.Name = "flowLayoutPanel1";
|
||||||
|
flowLayoutPanel1.Size = new Size(1185, 40);
|
||||||
|
flowLayoutPanel1.TabIndex = 2;
|
||||||
|
//
|
||||||
|
// btnLoadImage
|
||||||
|
//
|
||||||
|
btnLoadImage.Location = new Point(3, 3);
|
||||||
|
btnLoadImage.Name = "btnLoadImage";
|
||||||
|
btnLoadImage.Size = new Size(75, 30);
|
||||||
|
btnLoadImage.TabIndex = 0;
|
||||||
|
btnLoadImage.Text = "加载图像";
|
||||||
|
btnLoadImage.UseVisualStyleBackColor = true;
|
||||||
|
btnLoadImage.Click += btnLoadImage_Click;
|
||||||
|
//
|
||||||
|
// btnCreateCircle
|
||||||
|
//
|
||||||
|
btnCreateCircle.Enabled = false;
|
||||||
|
btnCreateCircle.Location = new Point(84, 3);
|
||||||
|
btnCreateCircle.Name = "btnCreateCircle";
|
||||||
|
btnCreateCircle.Size = new Size(75, 30);
|
||||||
|
btnCreateCircle.TabIndex = 1;
|
||||||
|
btnCreateCircle.Text = "绘制圆形";
|
||||||
|
btnCreateCircle.UseVisualStyleBackColor = true;
|
||||||
|
btnCreateCircle.Click += btnCreateCircle_Click;
|
||||||
|
//
|
||||||
|
// btnCreateRect
|
||||||
|
//
|
||||||
|
btnCreateRect.Location = new Point(165, 3);
|
||||||
|
btnCreateRect.Name = "btnCreateRect";
|
||||||
|
btnCreateRect.Size = new Size(75, 30);
|
||||||
|
btnCreateRect.TabIndex = 6;
|
||||||
|
btnCreateRect.Text = "绘制矩形";
|
||||||
|
btnCreateRect.UseVisualStyleBackColor = true;
|
||||||
|
btnCreateRect.Click += btnCreateRect_Click;
|
||||||
|
//
|
||||||
|
// btnStopDraw
|
||||||
|
//
|
||||||
|
btnStopDraw.Enabled = false;
|
||||||
|
btnStopDraw.Location = new Point(246, 3);
|
||||||
|
btnStopDraw.Name = "btnStopDraw";
|
||||||
|
btnStopDraw.Size = new Size(75, 30);
|
||||||
|
btnStopDraw.TabIndex = 2;
|
||||||
|
btnStopDraw.Text = "停止绘制";
|
||||||
|
btnStopDraw.UseVisualStyleBackColor = true;
|
||||||
|
btnStopDraw.Click += btnStopDraw_Click;
|
||||||
|
//
|
||||||
|
// btnTestOutsideDraw
|
||||||
|
//
|
||||||
|
btnTestOutsideDraw.Location = new Point(327, 3);
|
||||||
|
btnTestOutsideDraw.Name = "btnTestOutsideDraw";
|
||||||
|
btnTestOutsideDraw.Size = new Size(75, 30);
|
||||||
|
btnTestOutsideDraw.TabIndex = 3;
|
||||||
|
btnTestOutsideDraw.Text = "测试绘图";
|
||||||
|
btnTestOutsideDraw.UseVisualStyleBackColor = true;
|
||||||
|
btnTestOutsideDraw.Click += btnTestOutsideDraw_Click;
|
||||||
|
//
|
||||||
|
// btnTestClearDraw
|
||||||
|
//
|
||||||
|
btnTestClearDraw.Location = new Point(408, 3);
|
||||||
|
btnTestClearDraw.Name = "btnTestClearDraw";
|
||||||
|
btnTestClearDraw.Size = new Size(75, 30);
|
||||||
|
btnTestClearDraw.TabIndex = 4;
|
||||||
|
btnTestClearDraw.Text = "清除绘图";
|
||||||
|
btnTestClearDraw.UseVisualStyleBackColor = true;
|
||||||
|
btnTestClearDraw.Click += btnTestClearDraw_Click;
|
||||||
|
//
|
||||||
|
// btnTestCircleMeasure
|
||||||
|
//
|
||||||
|
btnTestCircleMeasure.Location = new Point(489, 3);
|
||||||
|
btnTestCircleMeasure.Name = "btnTestCircleMeasure";
|
||||||
|
btnTestCircleMeasure.Size = new Size(89, 30);
|
||||||
|
btnTestCircleMeasure.TabIndex = 5;
|
||||||
|
btnTestCircleMeasure.Text = "测试圆形算法";
|
||||||
|
btnTestCircleMeasure.UseVisualStyleBackColor = true;
|
||||||
|
btnTestCircleMeasure.Click += btnTestCircleMeasure_Click;
|
||||||
|
//
|
||||||
|
// btnTest
|
||||||
|
//
|
||||||
|
btnTest.Location = new Point(584, 3);
|
||||||
|
btnTest.Name = "btnTest";
|
||||||
|
btnTest.Size = new Size(89, 30);
|
||||||
|
btnTest.TabIndex = 7;
|
||||||
|
btnTest.Text = "测试";
|
||||||
|
btnTest.UseVisualStyleBackColor = true;
|
||||||
|
btnTest.Click += btnTest_Click;
|
||||||
|
//
|
||||||
|
// splitContainer
|
||||||
|
//
|
||||||
|
splitContainer.Dock = DockStyle.Fill;
|
||||||
|
splitContainer.Location = new Point(0, 40);
|
||||||
|
splitContainer.Name = "splitContainer";
|
||||||
|
//
|
||||||
|
// splitContainer.Panel1
|
||||||
|
//
|
||||||
|
splitContainer.Panel1.Controls.Add(panelGuide);
|
||||||
|
splitContainer.Panel1MinSize = 150;
|
||||||
|
//
|
||||||
|
// splitContainer.Panel2
|
||||||
|
//
|
||||||
|
splitContainer.Panel2.Controls.Add(panel1);
|
||||||
|
splitContainer.Size = new Size(1185, 791);
|
||||||
|
splitContainer.SplitterDistance = 234;
|
||||||
|
splitContainer.TabIndex = 3;
|
||||||
|
//
|
||||||
|
// panelGuide
|
||||||
|
//
|
||||||
|
panelGuide.BorderStyle = BorderStyle.FixedSingle;
|
||||||
|
panelGuide.Dock = DockStyle.Fill;
|
||||||
|
panelGuide.Location = new Point(0, 0);
|
||||||
|
panelGuide.Name = "panelGuide";
|
||||||
|
panelGuide.Size = new Size(234, 791);
|
||||||
|
panelGuide.TabIndex = 0;
|
||||||
|
//
|
||||||
|
// btnRotateTest
|
||||||
|
//
|
||||||
|
btnRotateTest.Location = new Point(679, 3);
|
||||||
|
btnRotateTest.Name = "btnRotateTest";
|
||||||
|
btnRotateTest.Size = new Size(89, 30);
|
||||||
|
btnRotateTest.TabIndex = 8;
|
||||||
|
btnRotateTest.Text = "测试旋转";
|
||||||
|
btnRotateTest.UseVisualStyleBackColor = true;
|
||||||
|
btnRotateTest.Click += btnRotateTest_Click;
|
||||||
|
//
|
||||||
|
// FrmMain
|
||||||
|
//
|
||||||
|
AutoScaleDimensions = new SizeF(7F, 17F);
|
||||||
|
AutoScaleMode = AutoScaleMode.Font;
|
||||||
|
ClientSize = new Size(1185, 831);
|
||||||
|
Controls.Add(splitContainer);
|
||||||
|
Controls.Add(flowLayoutPanel1);
|
||||||
|
Name = "FrmMain";
|
||||||
|
Text = "Form1";
|
||||||
|
WindowState = FormWindowState.Maximized;
|
||||||
|
Load += FrmMain_Load;
|
||||||
|
panel1.ResumeLayout(false);
|
||||||
|
panel1.PerformLayout();
|
||||||
|
statusStrip1.ResumeLayout(false);
|
||||||
|
statusStrip1.PerformLayout();
|
||||||
|
flowLayoutPanel1.ResumeLayout(false);
|
||||||
|
splitContainer.Panel1.ResumeLayout(false);
|
||||||
|
splitContainer.Panel2.ResumeLayout(false);
|
||||||
|
((System.ComponentModel.ISupportInitialize)splitContainer).EndInit();
|
||||||
|
splitContainer.ResumeLayout(false);
|
||||||
|
ResumeLayout(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
private Panel panel1;
|
||||||
|
private FlowLayoutPanel flowLayoutPanel1;
|
||||||
|
private SplitContainer splitContainer;
|
||||||
|
private Panel panelGuide;
|
||||||
|
private Button btnLoadImage;
|
||||||
|
private Button btnCreateCircle;
|
||||||
|
private Button btnStopDraw;
|
||||||
|
private StatusStrip statusStrip1;
|
||||||
|
private Canvas.UI.FlyCanvas canvas;
|
||||||
|
private ToolStripStatusLabel lblStatus;
|
||||||
|
private Button btnTestOutsideDraw;
|
||||||
|
private Button btnTestClearDraw;
|
||||||
|
private Button btnTestCircleMeasure;
|
||||||
|
private Button btnCreateRect;
|
||||||
|
private Button btnTest;
|
||||||
|
private Button btnRotateTest;
|
||||||
|
}
|
||||||
|
}
|
||||||
345
CanFly/UI/FrmMain.cs
Normal file
345
CanFly/UI/FrmMain.cs
Normal file
@@ -0,0 +1,345 @@
|
|||||||
|
using CanFly.Canvas.Shape;
|
||||||
|
using CanFly.Helper;
|
||||||
|
using CanFly.UI;
|
||||||
|
using CanFly.UI.GuidePanel;
|
||||||
|
using CanFly.Util;
|
||||||
|
using HalconDotNet;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
using System.Windows.Forms;
|
||||||
|
|
||||||
|
namespace CanFly
|
||||||
|
{
|
||||||
|
public partial class FrmMain : Form
|
||||||
|
{
|
||||||
|
|
||||||
|
private string _currentImageFile = "";
|
||||||
|
private System.Windows.Forms.Timer _statusTimer = new System.Windows.Forms.Timer();
|
||||||
|
private BaseGuideControl? _currentGuideCtrl;
|
||||||
|
|
||||||
|
|
||||||
|
public FrmMain()
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
this.canvas.mouseMoved += Canvas_mouseMoved;
|
||||||
|
this.canvas.OnShapeUpdateEvent += Canvas_OnShapeUpdateEvent;
|
||||||
|
this.canvas.selectionChanged += Canvas_selectionChanged;
|
||||||
|
|
||||||
|
this.canvas.OnShapeMoving += Canvas_OnShapeMoving;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private void FrmMain_Load(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
_currentImageFile = @"C:\Users\DEV\Desktop\<5C><>˿\Cam7_130252457.jpg";
|
||||||
|
Bitmap bitmap = (Bitmap)Image.FromFile(_currentImageFile);
|
||||||
|
this.canvas.LoadPixmap(bitmap);
|
||||||
|
this.btnCreateCircle.Enabled = true;
|
||||||
|
this.canvas.Enabled = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void btnLoadImage_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
OpenFileDialog ofd = new OpenFileDialog();
|
||||||
|
ofd.Filter = "ͼ<><CDBC><EFBFBD>ļ<EFBFBD>|*.jpg;*.png";
|
||||||
|
ofd.Multiselect = false;
|
||||||
|
if (ofd.ShowDialog() == DialogResult.OK)
|
||||||
|
{
|
||||||
|
_currentImageFile = ofd.FileName;
|
||||||
|
//this.canvasMain.LoadImageFile(_currentImageFile);
|
||||||
|
Bitmap bitmap = (Bitmap)Image.FromFile(_currentImageFile);
|
||||||
|
this.canvas.LoadPixmap(bitmap);
|
||||||
|
this.btnCreateCircle.Enabled = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void btnCreateCircle_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
//FrmGuideCircle frmGuideCircle = new FrmGuideCircle();
|
||||||
|
//panelGuide.ShowForm(frmGuideCircle);
|
||||||
|
|
||||||
|
SwitchGuideForm(ShapeTypeEnum.Circle);
|
||||||
|
this.canvas.StartDraw(ShapeTypeEnum.Circle);
|
||||||
|
|
||||||
|
this.btnCreateCircle.Enabled = false;
|
||||||
|
this.btnStopDraw.Enabled = true;
|
||||||
|
this.canvas.Enabled = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private void btnCreateRect_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
this.canvas.StartDraw(ShapeTypeEnum.Rectangle);
|
||||||
|
|
||||||
|
this.btnCreateCircle.Enabled = false;
|
||||||
|
this.btnStopDraw.Enabled = true;
|
||||||
|
this.canvas.Enabled = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private void btnStopDraw_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
//panelGuide.Controls.Clear();
|
||||||
|
StopDrawMode();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private void StartDrawMode()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void StopDrawMode()
|
||||||
|
{
|
||||||
|
this.canvas.StopDraw();
|
||||||
|
|
||||||
|
|
||||||
|
this.btnStopDraw.Enabled = false;
|
||||||
|
this.btnCreateCircle.Enabled = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private void Status(string message, int delay = 5000)
|
||||||
|
{
|
||||||
|
_statusTimer.Stop();
|
||||||
|
// <20><>ʾ<EFBFBD><CABE>Ϣ
|
||||||
|
lblStatus.Text = message;
|
||||||
|
|
||||||
|
// <20><><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1>
|
||||||
|
|
||||||
|
_statusTimer.Interval = delay; // <20><><EFBFBD><EFBFBD><EFBFBD>ӳ<EFBFBD>ʱ<EFBFBD><CAB1>
|
||||||
|
_statusTimer.Tick += (sender, e) =>
|
||||||
|
{
|
||||||
|
_statusTimer.Stop(); // ֹͣ<CDA3><D6B9>ʱ<EFBFBD><CAB1>
|
||||||
|
lblStatus.Text = string.Empty; // <20><><EFBFBD><EFBFBD>״̬<D7B4><CCAC>Ϣ
|
||||||
|
};
|
||||||
|
_statusTimer.Start(); // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1>
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private void Canvas_mouseMoved(PointF pos)
|
||||||
|
{
|
||||||
|
if (InvokeRequired)
|
||||||
|
{
|
||||||
|
Invoke(Canvas_mouseMoved, pos);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
lblStatus.Text = $"X:{pos.X}, Y:{pos.Y}";
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private void Canvas_selectionChanged(List<FlyShape> shapes)
|
||||||
|
{
|
||||||
|
if (shapes.Count != 1)
|
||||||
|
{
|
||||||
|
// panelGuide.Controls.Clear();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
//SwitchGuideForm(shapes[0].ShapeType);
|
||||||
|
Canvas_OnShapeUpdateEvent(shapes[0]);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private void SwitchGuideForm(ShapeTypeEnum shapeType)
|
||||||
|
{
|
||||||
|
if (_currentGuideCtrl == null)
|
||||||
|
{
|
||||||
|
switch (shapeType)
|
||||||
|
{
|
||||||
|
case ShapeTypeEnum.Point:
|
||||||
|
break;
|
||||||
|
case ShapeTypeEnum.Line:
|
||||||
|
break;
|
||||||
|
case ShapeTypeEnum.Rectangle:
|
||||||
|
break;
|
||||||
|
case ShapeTypeEnum.Circle:
|
||||||
|
_currentGuideCtrl = new GuideCircleCtrl();
|
||||||
|
_currentGuideCtrl.CurrentImageFile = _currentImageFile;
|
||||||
|
|
||||||
|
_currentGuideCtrl.OnControlCloseEvent += () =>
|
||||||
|
{
|
||||||
|
panelGuide.Controls.Clear();
|
||||||
|
StopDrawMode();
|
||||||
|
};
|
||||||
|
break;
|
||||||
|
case ShapeTypeEnum.Polygon:
|
||||||
|
break;
|
||||||
|
case ShapeTypeEnum.LineStrip:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//_currentGuideCtrl?.AddToPanel(panelGuide);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private void Canvas_OnShapeMoving(List<FlyShape> shapes)
|
||||||
|
{
|
||||||
|
if (shapes.Count != 1)
|
||||||
|
{
|
||||||
|
panelGuide.Controls.Clear();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// _currentGuideCtrl?.UpdateShape(shapes[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private void Canvas_OnShapeUpdateEvent(FlyShape shape)
|
||||||
|
{
|
||||||
|
switch (shape.ShapeType)
|
||||||
|
{
|
||||||
|
case ShapeTypeEnum.Point:
|
||||||
|
break;
|
||||||
|
case ShapeTypeEnum.Line:
|
||||||
|
break;
|
||||||
|
case ShapeTypeEnum.Rectangle:
|
||||||
|
break;
|
||||||
|
case ShapeTypeEnum.Circle:
|
||||||
|
{
|
||||||
|
//_currentGuideCtrl?.UpdateShape(shape);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ShapeTypeEnum.Polygon:
|
||||||
|
break;
|
||||||
|
case ShapeTypeEnum.LineStrip:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private void btnTestOutsideDraw_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
Random random = new Random((int)DateTime.Now.Ticks);
|
||||||
|
|
||||||
|
for (int i = 0; i < 10; i++)
|
||||||
|
{
|
||||||
|
// this.canvas.DrawCircle(new PointF(500, 500), 100);
|
||||||
|
|
||||||
|
int x = random.Next() % 500;
|
||||||
|
int y = random.Next() % 500;
|
||||||
|
int r = random.Next() % 200;
|
||||||
|
|
||||||
|
Debug.WriteLine($"X:{x}\tY:{y}\tR:{r}");
|
||||||
|
|
||||||
|
this.canvas.DrawCircle(new PointF(x, y), r);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void btnTestClearDraw_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
this.canvas.ClearDraw();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private async void btnTestCircleMeasure_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
//string dir = Path.Combine(Environment.CurrentDirectory, "hscripts");
|
||||||
|
//string file = "CircleMeasure.hdvp";
|
||||||
|
//string filePath = Path.Combine(dir, file);
|
||||||
|
//if (!File.Exists(filePath))
|
||||||
|
//{
|
||||||
|
// MessageBox.Show($"<22>ļ<EFBFBD> {filePath} <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>");
|
||||||
|
// return;
|
||||||
|
//}
|
||||||
|
|
||||||
|
//HObject? hImage = null;
|
||||||
|
|
||||||
|
//try
|
||||||
|
//{
|
||||||
|
// HDevEngineTool tool = new HDevEngineTool(dir);
|
||||||
|
// tool.LoadProcedure(Path.GetFileNameWithoutExtension(file));
|
||||||
|
|
||||||
|
// // string imageFile = Path.Combine(Environment.CurrentDirectory, "hscripts", "image.png");
|
||||||
|
|
||||||
|
// HOperatorSet.ReadImage(out hImage, _currentImageFile);
|
||||||
|
// tool.InputImageDic["INPUT_Image"] = hImage;
|
||||||
|
// tool.InputTupleDic["XCenter"] = 981.625;
|
||||||
|
// tool.InputTupleDic["YCenter"] = 931.823;
|
||||||
|
// tool.InputTupleDic["Radius"] = 900.141;
|
||||||
|
|
||||||
|
// Stopwatch sw = new Stopwatch();
|
||||||
|
// sw.Start();
|
||||||
|
// if (!tool.RunProcedure(out string error, out _))
|
||||||
|
// {
|
||||||
|
// throw new Exception();
|
||||||
|
// }
|
||||||
|
// sw.Stop();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// var flag = tool.GetResultTuple("OUTPUT_Flag").HTupleToDouble();
|
||||||
|
// List<double> x = tool.GetResultTuple("RXCenter").HTupleToDouble();
|
||||||
|
// var y = tool.GetResultTuple("RYCenter").HTupleToDouble();
|
||||||
|
// var r = tool.GetResultTuple("RRadius").HTupleToDouble();
|
||||||
|
|
||||||
|
// if (flag.Count > 0 && x.Count > 0 && y.Count > 0 && r.Count > 0)
|
||||||
|
// {
|
||||||
|
// this.canvas.DrawCircle(new PointF((float)x[0], (float)y[0]), (float)r[0]);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// //
|
||||||
|
// Debug.WriteLine("");
|
||||||
|
//}
|
||||||
|
//catch (Exception)
|
||||||
|
//{
|
||||||
|
// throw;
|
||||||
|
//}
|
||||||
|
//finally
|
||||||
|
//{
|
||||||
|
// hImage?.Dispose();
|
||||||
|
//}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void btnTest_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
this.canvas.DrawRectangle(new PointF(300, 300),
|
||||||
|
new PointF(800, 500), 33f);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void btnRotateTest_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
if (this.canvas.Shapes.Count == 0)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.canvas.Shapes[0]._currentRotateAngle += 10;
|
||||||
|
|
||||||
|
//var shp = this.canvas.Shapes[this.canvas.Shapes.Count - 1].Copy();
|
||||||
|
//shp.Rotate += 10;
|
||||||
|
//this.canvas.Shapes.Add(shp);
|
||||||
|
|
||||||
|
|
||||||
|
this.canvas.Invalidate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
148
CanFly/UI/FrmMain.resx
Normal file
148
CanFly/UI/FrmMain.resx
Normal file
@@ -0,0 +1,148 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<root>
|
||||||
|
<!--
|
||||||
|
Microsoft ResX Schema
|
||||||
|
|
||||||
|
Version 2.0
|
||||||
|
|
||||||
|
The primary goals of this format is to allow a simple XML format
|
||||||
|
that is mostly human readable. The generation and parsing of the
|
||||||
|
various data types are done through the TypeConverter classes
|
||||||
|
associated with the data types.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
... ado.net/XML headers & schema ...
|
||||||
|
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||||
|
<resheader name="version">2.0</resheader>
|
||||||
|
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||||
|
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||||
|
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||||
|
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||||
|
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||||
|
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||||
|
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||||
|
<comment>This is a comment</comment>
|
||||||
|
</data>
|
||||||
|
|
||||||
|
There are any number of "resheader" rows that contain simple
|
||||||
|
name/value pairs.
|
||||||
|
|
||||||
|
Each data row contains a name, and value. The row also contains a
|
||||||
|
type or mimetype. Type corresponds to a .NET class that support
|
||||||
|
text/value conversion through the TypeConverter architecture.
|
||||||
|
Classes that don't support this are serialized and stored with the
|
||||||
|
mimetype set.
|
||||||
|
|
||||||
|
The mimetype is used for serialized objects, and tells the
|
||||||
|
ResXResourceReader how to depersist the object. This is currently not
|
||||||
|
extensible. For a given mimetype the value must be set accordingly:
|
||||||
|
|
||||||
|
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||||
|
that the ResXResourceWriter will generate, however the reader can
|
||||||
|
read any of the formats listed below.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.binary.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.soap.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||||
|
value : The object must be serialized into a byte array
|
||||||
|
: using a System.ComponentModel.TypeConverter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
-->
|
||||||
|
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||||
|
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||||
|
<xsd:element name="root" msdata:IsDataSet="true">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:choice maxOccurs="unbounded">
|
||||||
|
<xsd:element name="metadata">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="assembly">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:attribute name="alias" type="xsd:string" />
|
||||||
|
<xsd:attribute name="name" type="xsd:string" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="data">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="resheader">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:choice>
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:schema>
|
||||||
|
<resheader name="resmimetype">
|
||||||
|
<value>text/microsoft-resx</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="version">
|
||||||
|
<value>2.0</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="reader">
|
||||||
|
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="writer">
|
||||||
|
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
<metadata name="statusStrip1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||||
|
<value>17, 17</value>
|
||||||
|
</metadata>
|
||||||
|
<data name="canvas.OutsideShapes" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||||
|
<value>
|
||||||
|
AAEAAAD/////AQAAAAAAAAAMAgAAAERDYW5GbHkuQ2FudmFzLCBWZXJzaW9uPTEuMC4wLjAsIEN1bHR1
|
||||||
|
cmU9bmV1dHJhbCwgUHVibGljS2V5VG9rZW49bnVsbAQBAAAAdlN5c3RlbS5Db2xsZWN0aW9ucy5HZW5l
|
||||||
|
cmljLkxpc3RgMVtbQ2FuRmx5LkNhbnZhcy5TaGFwZS5GbHlTaGFwZSwgQ2FuRmx5LkNhbnZhcywgQ3Vs
|
||||||
|
dHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1udWxsXV0DAAAABl9pdGVtcwVfc2l6ZQhfdmVyc2lv
|
||||||
|
bgQAAB5DYW5GbHkuQ2FudmFzLlNoYXBlLkZseVNoYXBlW10CAAAACAgJAwAAAAAAAAAAAAAADAQAAAAz
|
||||||
|
Q2FuRmx5LkNhbnZhcywgQ3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1udWxsBwMAAAAAAQAA
|
||||||
|
AAAAAAAEHENhbkZseS5DYW52YXMuU2hhcGUuRmx5U2hhcGUEAAAACw==
|
||||||
|
</value>
|
||||||
|
</data>
|
||||||
|
<data name="canvas.Shapes" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||||
|
<value>
|
||||||
|
AAEAAAD/////AQAAAAAAAAAMAgAAAERDYW5GbHkuQ2FudmFzLCBWZXJzaW9uPTEuMC4wLjAsIEN1bHR1
|
||||||
|
cmU9bmV1dHJhbCwgUHVibGljS2V5VG9rZW49bnVsbAQBAAAAdlN5c3RlbS5Db2xsZWN0aW9ucy5HZW5l
|
||||||
|
cmljLkxpc3RgMVtbQ2FuRmx5LkNhbnZhcy5TaGFwZS5GbHlTaGFwZSwgQ2FuRmx5LkNhbnZhcywgQ3Vs
|
||||||
|
dHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1udWxsXV0DAAAABl9pdGVtcwVfc2l6ZQhfdmVyc2lv
|
||||||
|
bgQAAB5DYW5GbHkuQ2FudmFzLlNoYXBlLkZseVNoYXBlW10CAAAACAgJAwAAAAAAAAAAAAAADAQAAAAz
|
||||||
|
Q2FuRmx5LkNhbnZhcywgQ3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1udWxsBwMAAAAAAQAA
|
||||||
|
AAAAAAAEHENhbkZseS5DYW52YXMuU2hhcGUuRmx5U2hhcGUEAAAACw==
|
||||||
|
</value>
|
||||||
|
</data>
|
||||||
|
<metadata name="statusStrip1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||||
|
<value>17, 17</value>
|
||||||
|
</metadata>
|
||||||
|
</root>
|
||||||
75
CanFly/UI/FrmMain3.Designer.cs
generated
Normal file
75
CanFly/UI/FrmMain3.Designer.cs
generated
Normal file
@@ -0,0 +1,75 @@
|
|||||||
|
|
||||||
|
|
||||||
|
namespace XKRS.CanFly
|
||||||
|
{
|
||||||
|
partial class FrmMain3
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Required designer variable.
|
||||||
|
/// </summary>
|
||||||
|
private System.ComponentModel.IContainer components = null;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Clean up any resources being used.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||||
|
protected override void Dispose(bool disposing)
|
||||||
|
{
|
||||||
|
if (disposing && (components != null))
|
||||||
|
{
|
||||||
|
components.Dispose();
|
||||||
|
}
|
||||||
|
base.Dispose(disposing);
|
||||||
|
}
|
||||||
|
|
||||||
|
#region Windows Form Designer generated code
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Required method for Designer support - do not modify
|
||||||
|
/// the contents of this method with the code editor.
|
||||||
|
/// </summary>
|
||||||
|
private void InitializeComponent()
|
||||||
|
{
|
||||||
|
statusStrip1 = new StatusStrip();
|
||||||
|
panelContent = new Panel();
|
||||||
|
SuspendLayout();
|
||||||
|
//
|
||||||
|
// statusStrip1
|
||||||
|
//
|
||||||
|
statusStrip1.Location = new Point(0, 808);
|
||||||
|
statusStrip1.Name = "statusStrip1";
|
||||||
|
statusStrip1.Size = new Size(1185, 22);
|
||||||
|
statusStrip1.TabIndex = 4;
|
||||||
|
statusStrip1.Text = "statusStrip1";
|
||||||
|
//
|
||||||
|
// panelContent
|
||||||
|
//
|
||||||
|
panelContent.Dock = DockStyle.Fill;
|
||||||
|
panelContent.Location = new Point(0, 0);
|
||||||
|
panelContent.Margin = new Padding(4, 3, 4, 3);
|
||||||
|
panelContent.Name = "panelContent";
|
||||||
|
panelContent.Size = new Size(1185, 808);
|
||||||
|
panelContent.TabIndex = 5;
|
||||||
|
//
|
||||||
|
// FrmMain3
|
||||||
|
//
|
||||||
|
AutoScaleDimensions = new SizeF(7F, 17F);
|
||||||
|
AutoScaleMode = AutoScaleMode.Font;
|
||||||
|
ClientSize = new Size(1185, 830);
|
||||||
|
Controls.Add(panelContent);
|
||||||
|
Controls.Add(statusStrip1);
|
||||||
|
FormBorderStyle = FormBorderStyle.FixedSingle;
|
||||||
|
Margin = new Padding(2, 3, 2, 3);
|
||||||
|
Name = "FrmMain3";
|
||||||
|
StartPosition = FormStartPosition.CenterScreen;
|
||||||
|
Text = "尺寸测量";
|
||||||
|
Load += FrmMain_Load;
|
||||||
|
ResumeLayout(false);
|
||||||
|
PerformLayout();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
private StatusStrip statusStrip1;
|
||||||
|
private Panel panelContent;
|
||||||
|
}
|
||||||
|
}
|
||||||
435
CanFly/UI/FrmMain3.cs
Normal file
435
CanFly/UI/FrmMain3.cs
Normal file
@@ -0,0 +1,435 @@
|
|||||||
|
using CanFly.Canvas.Shape;
|
||||||
|
using CanFly.Helper;
|
||||||
|
using CanFly.UI;
|
||||||
|
using CanFly.UI.GuidePanel;
|
||||||
|
using CanFly.Util;
|
||||||
|
using HalconDotNet;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
using System.Windows.Forms;
|
||||||
|
|
||||||
|
namespace XKRS.CanFly
|
||||||
|
{
|
||||||
|
|
||||||
|
public partial class FrmMain3 : Form
|
||||||
|
{
|
||||||
|
|
||||||
|
private string _currentImageFile = "";
|
||||||
|
private System.Windows.Forms.Timer _statusTimer = new System.Windows.Forms.Timer();
|
||||||
|
private BaseGuideControl? _currentGuideCtrl;
|
||||||
|
|
||||||
|
|
||||||
|
private GuideCircleCtrl guideCircleCtrl = new GuideCircleCtrl();
|
||||||
|
private GuideLineCircleCtrl guideLineCircleCtrl = new GuideLineCircleCtrl();
|
||||||
|
private GuideLineLineCtrl guideLineLineCtrl = new GuideLineLineCtrl();
|
||||||
|
private GuideLineCtrl guideLineCtrl = new GuideLineCtrl();
|
||||||
|
private GuideHeightCtrl guideHeightCtrl = new GuideHeightCtrl();
|
||||||
|
string Type=string.Empty;
|
||||||
|
|
||||||
|
|
||||||
|
public string inputtext=string.Empty;
|
||||||
|
public string outtext = string.Empty;
|
||||||
|
public FrmMain3(string type)
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
|
||||||
|
Type=type;
|
||||||
|
|
||||||
|
guideCircleCtrl.Dock = DockStyle.Fill;
|
||||||
|
guideCircleCtrl.OnControlCloseEvent -= () => panelContent.Controls.Clear();
|
||||||
|
guideCircleCtrl.OnControlCloseEvent += () => panelContent.Controls.Clear();
|
||||||
|
|
||||||
|
|
||||||
|
guideLineCircleCtrl.Dock = DockStyle.Fill;
|
||||||
|
guideLineCircleCtrl.OnControlCloseEvent -= () => panelContent.Controls.Clear();
|
||||||
|
guideLineCircleCtrl.OnControlCloseEvent += () => panelContent.Controls.Clear();
|
||||||
|
|
||||||
|
guideLineLineCtrl.Dock = DockStyle.Fill;
|
||||||
|
guideLineLineCtrl.OnControlCloseEvent -= () => panelContent.Controls.Clear();
|
||||||
|
guideLineLineCtrl.OnControlCloseEvent += () => panelContent.Controls.Clear();
|
||||||
|
|
||||||
|
guideLineCtrl.Dock = DockStyle.Fill;
|
||||||
|
guideLineCtrl.OnControlCloseEvent -= () => panelContent.Controls.Clear();
|
||||||
|
guideLineCtrl.OnControlCloseEvent += () => panelContent.Controls.Clear();
|
||||||
|
|
||||||
|
|
||||||
|
guideHeightCtrl.Dock = DockStyle.Fill;
|
||||||
|
guideHeightCtrl.OnControlCloseEvent -= () => panelContent.Controls.Clear();
|
||||||
|
guideHeightCtrl.OnControlCloseEvent += () => panelContent.Controls.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private void FrmMain_Load(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
switch (Type)
|
||||||
|
{
|
||||||
|
case "1":
|
||||||
|
SwitchMeasureMode(guideCircleCtrl);
|
||||||
|
break;
|
||||||
|
case "2":
|
||||||
|
SwitchMeasureMode(guideLineCtrl);
|
||||||
|
break;
|
||||||
|
case "3":
|
||||||
|
SwitchMeasureMode(guideLineLineCtrl);
|
||||||
|
break;
|
||||||
|
case "4":
|
||||||
|
SwitchMeasureMode(guideLineCircleCtrl);
|
||||||
|
break;
|
||||||
|
case "5":
|
||||||
|
SwitchMeasureMode(guideHeightCtrl);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void btnLoadImage_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
//OpenFileDialog ofd = new OpenFileDialog();
|
||||||
|
//ofd.Filter = "ͼ<><CDBC><EFBFBD>ļ<EFBFBD>|*.jpg;*.png";
|
||||||
|
//ofd.Multiselect = false;
|
||||||
|
//if (ofd.ShowDialog() == DialogResult.OK)
|
||||||
|
//{
|
||||||
|
// _currentImageFile = ofd.FileName;
|
||||||
|
// Bitmap bitmap = (Bitmap)Image.FromFile(_currentImageFile);
|
||||||
|
// this.canvas.LoadPixmap(bitmap);
|
||||||
|
// this.btnCreateCircle.Enabled = true;
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private void btnMeasureCircle_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
//var contentCtrls = panelContent.Controls;
|
||||||
|
|
||||||
|
//if (contentCtrls.Count > 0)
|
||||||
|
//{
|
||||||
|
// if (contentCtrls[0] == guideCircleCtrl)
|
||||||
|
// {
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
|
||||||
|
//panelContent.Controls.Clear();
|
||||||
|
//panelContent.Controls.Add(guideCircleCtrl);
|
||||||
|
|
||||||
|
SwitchMeasureMode(guideCircleCtrl);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void btnMeasureLineCircle_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
SwitchMeasureMode(guideLineCircleCtrl);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void SwitchMeasureMode(BaseGuideControl control)
|
||||||
|
{
|
||||||
|
var contentCtrls = panelContent.Controls;
|
||||||
|
|
||||||
|
if (contentCtrls.Count > 0)
|
||||||
|
{
|
||||||
|
if (contentCtrls[0] == control)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
panelContent.Controls.Clear();
|
||||||
|
|
||||||
|
control.OnDataPassed -= Control_OnDataPassed;
|
||||||
|
control.OnDataPassed += Control_OnDataPassed;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//control.Dock = DockStyle.Fill;
|
||||||
|
//control.OnControlCloseEvent -= () => panelContent.Controls.Clear();
|
||||||
|
//control.OnControlCloseEvent += () => panelContent.Controls.Clear();
|
||||||
|
panelContent.Controls.Add(control);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Control_OnDataPassed(string obj,string obj1)
|
||||||
|
{
|
||||||
|
inputtext = obj;
|
||||||
|
outtext = obj1;
|
||||||
|
this.Close();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void btnCreateRect_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
//this.canvas.StartDraw(ShapeTypeEnum.Rectangle);
|
||||||
|
//this.btnCreateCircle.Enabled = false;
|
||||||
|
//this.btnStopDraw.Enabled = true;
|
||||||
|
//this.canvas.Enabled = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private void btnStopDraw_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
//panelGuide.Controls.Clear();
|
||||||
|
StopDrawMode();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private void StartDrawMode()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void StopDrawMode()
|
||||||
|
{
|
||||||
|
//this.canvas.StopDraw();
|
||||||
|
|
||||||
|
|
||||||
|
//this.btnStopDraw.Enabled = false;
|
||||||
|
//this.btnCreateCircle.Enabled = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private void Status(string message, int delay = 5000)
|
||||||
|
{
|
||||||
|
//_statusTimer.Stop();
|
||||||
|
//// <20><>ʾ<EFBFBD><CABE>Ϣ
|
||||||
|
//lblStatus.Text = message;
|
||||||
|
|
||||||
|
//// <20><><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1>
|
||||||
|
|
||||||
|
//_statusTimer.Interval = delay; // <20><><EFBFBD><EFBFBD><EFBFBD>ӳ<EFBFBD>ʱ<EFBFBD><CAB1>
|
||||||
|
//_statusTimer.Tick += (sender, e) =>
|
||||||
|
//{
|
||||||
|
// _statusTimer.Stop(); // ֹͣ<CDA3><D6B9>ʱ<EFBFBD><CAB1>
|
||||||
|
// lblStatus.Text = string.Empty; // <20><><EFBFBD><EFBFBD>״̬<D7B4><CCAC>Ϣ
|
||||||
|
//};
|
||||||
|
//_statusTimer.Start(); // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1>
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private void Canvas_mouseMoved(PointF pos)
|
||||||
|
{
|
||||||
|
//if (InvokeRequired)
|
||||||
|
//{
|
||||||
|
// Invoke(Canvas_mouseMoved, pos);
|
||||||
|
// return;
|
||||||
|
//}
|
||||||
|
|
||||||
|
//lblStatus.Text = $"X:{pos.X}, Y:{pos.Y}";
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private void Canvas_selectionChanged(List<FlyShape> shapes)
|
||||||
|
{
|
||||||
|
if (shapes.Count != 1)
|
||||||
|
{
|
||||||
|
// panelGuide.Controls.Clear();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
//SwitchGuideForm(shapes[0].ShapeType);
|
||||||
|
Canvas_OnShapeUpdateEvent(shapes[0]);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private void SwitchGuideForm(ShapeTypeEnum shapeType)
|
||||||
|
{
|
||||||
|
//if (_currentGuideCtrl == null)
|
||||||
|
//{
|
||||||
|
// switch (shapeType)
|
||||||
|
// {
|
||||||
|
// case ShapeTypeEnum.Point:
|
||||||
|
// break;
|
||||||
|
// case ShapeTypeEnum.Line:
|
||||||
|
// break;
|
||||||
|
// case ShapeTypeEnum.Rectangle:
|
||||||
|
// break;
|
||||||
|
// case ShapeTypeEnum.Circle:
|
||||||
|
// _currentGuideCtrl = new GuideCircleCtrl();
|
||||||
|
// _currentGuideCtrl.ImageFile = _currentImageFile;
|
||||||
|
// _currentGuideCtrl.OnDrawCircle += this.canvas.DrawCircle;
|
||||||
|
// _currentGuideCtrl.OnClose += () =>
|
||||||
|
// {
|
||||||
|
// panelGuide.Controls.Clear();
|
||||||
|
// StopDrawMode();
|
||||||
|
// };
|
||||||
|
// break;
|
||||||
|
// case ShapeTypeEnum.Polygon:
|
||||||
|
// break;
|
||||||
|
// case ShapeTypeEnum.LineStrip:
|
||||||
|
// break;
|
||||||
|
// default:
|
||||||
|
// break;
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
//_currentGuideCtrl?.AddToPanel(panelGuide);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private void Canvas_OnShapeMoving(List<FlyShape> shapes)
|
||||||
|
{
|
||||||
|
//if (shapes.Count != 1)
|
||||||
|
//{
|
||||||
|
// panelGuide.Controls.Clear();
|
||||||
|
// return;
|
||||||
|
//}
|
||||||
|
|
||||||
|
//_currentGuideCtrl?.UpdateShape(shapes[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private void Canvas_OnShapeUpdateEvent(FlyShape shape)
|
||||||
|
{
|
||||||
|
switch (shape.ShapeType)
|
||||||
|
{
|
||||||
|
case ShapeTypeEnum.Point:
|
||||||
|
break;
|
||||||
|
case ShapeTypeEnum.Line:
|
||||||
|
break;
|
||||||
|
case ShapeTypeEnum.Rectangle:
|
||||||
|
break;
|
||||||
|
case ShapeTypeEnum.Circle:
|
||||||
|
{
|
||||||
|
//_currentGuideCtrl?.UpdateShape(shape);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ShapeTypeEnum.Polygon:
|
||||||
|
break;
|
||||||
|
case ShapeTypeEnum.LineStrip:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private void btnTestOutsideDraw_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
//Random random = new Random((int)DateTime.Now.Ticks);
|
||||||
|
|
||||||
|
//for (int i = 0; i < 10; i++)
|
||||||
|
//{
|
||||||
|
// // this.canvas.DrawCircle(new PointF(500, 500), 100);
|
||||||
|
|
||||||
|
// int x = random.Next() % 500;
|
||||||
|
// int y = random.Next() % 500;
|
||||||
|
// int r = random.Next() % 200;
|
||||||
|
|
||||||
|
// Debug.WriteLine($"X:{x}\tY:{y}\tR:{r}");
|
||||||
|
|
||||||
|
// this.canvas.DrawCircle(new PointF(x, y), r);
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void btnTestClearDraw_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
//this.canvas.ClearDraw();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private async void btnTestCircleMeasure_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
//string dir = Path.Combine(Environment.CurrentDirectory, "hscripts");
|
||||||
|
//string file = "CircleMeasure.hdvp";
|
||||||
|
//string filePath = Path.Combine(dir, file);
|
||||||
|
//if (!File.Exists(filePath))
|
||||||
|
//{
|
||||||
|
// MessageBox.Show($"<22>ļ<EFBFBD> {filePath} <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>");
|
||||||
|
// return;
|
||||||
|
//}
|
||||||
|
|
||||||
|
//HObject? hImage = null;
|
||||||
|
|
||||||
|
//try
|
||||||
|
//{
|
||||||
|
// HDevEngineTool tool = new HDevEngineTool(dir);
|
||||||
|
// tool.LoadProcedure(Path.GetFileNameWithoutExtension(file));
|
||||||
|
|
||||||
|
// // string imageFile = Path.Combine(Environment.CurrentDirectory, "hscripts", "image.png");
|
||||||
|
|
||||||
|
// HOperatorSet.ReadImage(out hImage, _currentImageFile);
|
||||||
|
// tool.InputImageDic["INPUT_Image"] = hImage;
|
||||||
|
// tool.InputTupleDic["XCenter"] = 981.625;
|
||||||
|
// tool.InputTupleDic["YCenter"] = 931.823;
|
||||||
|
// tool.InputTupleDic["Radius"] = 900.141;
|
||||||
|
|
||||||
|
// Stopwatch sw = new Stopwatch();
|
||||||
|
// sw.Start();
|
||||||
|
// if (!tool.RunProcedure(out string error, out _))
|
||||||
|
// {
|
||||||
|
// throw new Exception();
|
||||||
|
// }
|
||||||
|
// sw.Stop();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// var flag = tool.GetResultTuple("OUTPUT_Flag").HTupleToDouble();
|
||||||
|
// List<double> x = tool.GetResultTuple("RXCenter").HTupleToDouble();
|
||||||
|
// var y = tool.GetResultTuple("RYCenter").HTupleToDouble();
|
||||||
|
// var r = tool.GetResultTuple("RRadius").HTupleToDouble();
|
||||||
|
|
||||||
|
// if (flag.Count > 0 && x.Count > 0 && y.Count > 0 && r.Count > 0)
|
||||||
|
// {
|
||||||
|
// this.canvas.DrawCircle(new PointF((float)x[0], (float)y[0]), (float)r[0]);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// //
|
||||||
|
// Debug.WriteLine("");
|
||||||
|
//}
|
||||||
|
//catch (Exception)
|
||||||
|
//{
|
||||||
|
// throw;
|
||||||
|
//}
|
||||||
|
//finally
|
||||||
|
//{
|
||||||
|
// hImage?.Dispose();
|
||||||
|
//}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void btnTest_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
//this.canvas.DrawRectangle(new PointF(300, 300),
|
||||||
|
// new PointF(800, 500), 33f);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void btnRotateTest_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
//if (this.canvas.Shapes.Count == 0)
|
||||||
|
//{
|
||||||
|
// return;
|
||||||
|
//}
|
||||||
|
|
||||||
|
//this.canvas.Shapes[0]._currentRotateAngle += 10;
|
||||||
|
//this.canvas.Invalidate();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void btnMeasureLineline_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
SwitchMeasureMode(guideLineLineCtrl);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void btnMeasureLine_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
SwitchMeasureMode(guideLineCtrl);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
123
CanFly/UI/FrmMain3.resx
Normal file
123
CanFly/UI/FrmMain3.resx
Normal file
@@ -0,0 +1,123 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<root>
|
||||||
|
<!--
|
||||||
|
Microsoft ResX Schema
|
||||||
|
|
||||||
|
Version 2.0
|
||||||
|
|
||||||
|
The primary goals of this format is to allow a simple XML format
|
||||||
|
that is mostly human readable. The generation and parsing of the
|
||||||
|
various data types are done through the TypeConverter classes
|
||||||
|
associated with the data types.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
... ado.net/XML headers & schema ...
|
||||||
|
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||||
|
<resheader name="version">2.0</resheader>
|
||||||
|
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||||
|
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||||
|
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||||
|
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||||
|
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||||
|
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||||
|
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||||
|
<comment>This is a comment</comment>
|
||||||
|
</data>
|
||||||
|
|
||||||
|
There are any number of "resheader" rows that contain simple
|
||||||
|
name/value pairs.
|
||||||
|
|
||||||
|
Each data row contains a name, and value. The row also contains a
|
||||||
|
type or mimetype. Type corresponds to a .NET class that support
|
||||||
|
text/value conversion through the TypeConverter architecture.
|
||||||
|
Classes that don't support this are serialized and stored with the
|
||||||
|
mimetype set.
|
||||||
|
|
||||||
|
The mimetype is used for serialized objects, and tells the
|
||||||
|
ResXResourceReader how to depersist the object. This is currently not
|
||||||
|
extensible. For a given mimetype the value must be set accordingly:
|
||||||
|
|
||||||
|
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||||
|
that the ResXResourceWriter will generate, however the reader can
|
||||||
|
read any of the formats listed below.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.binary.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.soap.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||||
|
value : The object must be serialized into a byte array
|
||||||
|
: using a System.ComponentModel.TypeConverter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
-->
|
||||||
|
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||||
|
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||||
|
<xsd:element name="root" msdata:IsDataSet="true">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:choice maxOccurs="unbounded">
|
||||||
|
<xsd:element name="metadata">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="assembly">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:attribute name="alias" type="xsd:string" />
|
||||||
|
<xsd:attribute name="name" type="xsd:string" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="data">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="resheader">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:choice>
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:schema>
|
||||||
|
<resheader name="resmimetype">
|
||||||
|
<value>text/microsoft-resx</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="version">
|
||||||
|
<value>2.0</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="reader">
|
||||||
|
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="writer">
|
||||||
|
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
<metadata name="statusStrip1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||||
|
<value>17, 17</value>
|
||||||
|
</metadata>
|
||||||
|
</root>
|
||||||
158
CanFly/UI/GuidePanel/BaseGuideControl.cs
Normal file
158
CanFly/UI/GuidePanel/BaseGuideControl.cs
Normal file
@@ -0,0 +1,158 @@
|
|||||||
|
using CanFly.Canvas.Shape;
|
||||||
|
using CanFly.Canvas.UI;
|
||||||
|
using CanFly.Helper;
|
||||||
|
using HalconDotNet;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
namespace CanFly.UI.GuidePanel
|
||||||
|
{
|
||||||
|
|
||||||
|
public class BaseGuideControl : UserControl
|
||||||
|
{
|
||||||
|
public Action? OnControlCloseEvent;
|
||||||
|
|
||||||
|
public event Action<string,string> OnDataPassed;
|
||||||
|
|
||||||
|
|
||||||
|
private string _currentImageFile;
|
||||||
|
|
||||||
|
public string CurrentImageFile;
|
||||||
|
|
||||||
|
|
||||||
|
protected string _hScriptsDir = Path.Combine(Environment.CurrentDirectory, "hscripts");
|
||||||
|
|
||||||
|
protected HObject? hImage = null;
|
||||||
|
|
||||||
|
protected FlyCanvas _canvas;
|
||||||
|
|
||||||
|
private HDevEngineTool? tool = null;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public void DataToTriggerEvent(string input,string output)
|
||||||
|
{
|
||||||
|
|
||||||
|
OnDataPassed?.Invoke(input, output);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected virtual void UpdateShape(FlyShape shape)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected virtual string GetScriptFileName()
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 执行Halcon脚本
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="inputImg">输入图像</param>
|
||||||
|
/// <param name="inputDic">输入参数</param>
|
||||||
|
/// <param name="outputParamKeys">输出参数</param>
|
||||||
|
protected void ExecuteHScript(
|
||||||
|
Dictionary<string, HObject> inputImg,
|
||||||
|
Dictionary<string, HTuple> inputDic,
|
||||||
|
List<string> outputParamKeys,
|
||||||
|
Action<Exception>? exceptionHandler = null)
|
||||||
|
{
|
||||||
|
|
||||||
|
string filePath = Path.Combine(_hScriptsDir, GetScriptFileName());
|
||||||
|
if (!File.Exists(filePath))
|
||||||
|
{
|
||||||
|
MessageBox.Show($"文件 {filePath} 不存在");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (tool == null)
|
||||||
|
{
|
||||||
|
tool = new HDevEngineTool(_hScriptsDir);
|
||||||
|
tool.LoadProcedure(Path.GetFileNameWithoutExtension(GetScriptFileName()));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//tool.InputImageDic["INPUT_Image"] = hImage;
|
||||||
|
//tool.InputTupleDic["XCenter"] = _x;
|
||||||
|
//tool.InputTupleDic["YCenter"] = _y;
|
||||||
|
//tool.InputTupleDic["Radius"] = _r;
|
||||||
|
|
||||||
|
tool.InputImageDic = inputImg;
|
||||||
|
tool.InputTupleDic = inputDic;
|
||||||
|
|
||||||
|
|
||||||
|
Dictionary<string, HTuple> outputParams = new Dictionary<string, HTuple>();
|
||||||
|
|
||||||
|
|
||||||
|
if (!tool.RunProcedure(out string error, out int timeElasped))
|
||||||
|
{
|
||||||
|
OnExecuteHScriptResult(false, outputParams, timeElasped);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < outputParamKeys.Count; i++)
|
||||||
|
{
|
||||||
|
string k = outputParamKeys[i];
|
||||||
|
outputParams[k] = tool.GetResultTuple(k);
|
||||||
|
}
|
||||||
|
|
||||||
|
OnExecuteHScriptResult(true, outputParams, timeElasped);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
exceptionHandler?.Invoke(ex);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
hImage?.Dispose();
|
||||||
|
hImage = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Halcon脚本执行结果回调函数,重写该方法以自行处理算法执行结果
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="success">算法执行是否成功</param>
|
||||||
|
/// <param name="resultDic">算法输出结果</param>
|
||||||
|
/// <param name="timeElasped">算法耗时,单位:ms</param>
|
||||||
|
protected virtual void OnExecuteHScriptResult(bool success, Dictionary<string, HTuple> resultDic, int timeElasped)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
protected void OpenImageFile(Action<Bitmap> callback)
|
||||||
|
{
|
||||||
|
OpenFileDialog ofd = new OpenFileDialog();
|
||||||
|
ofd.Filter = "图像文件|*.jpg;*.jpeg;*.png";
|
||||||
|
ofd.Multiselect = false;
|
||||||
|
if (ofd.ShowDialog() == DialogResult.OK)
|
||||||
|
{
|
||||||
|
CurrentImageFile = ofd.FileName;
|
||||||
|
Bitmap bitmap = (Bitmap)Image.FromFile(CurrentImageFile);
|
||||||
|
callback?.Invoke(bitmap);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
protected void OnControlClose()
|
||||||
|
{
|
||||||
|
OnControlCloseEvent?.Invoke();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
120
CanFly/UI/GuidePanel/BaseGuideControl.resx
Normal file
120
CanFly/UI/GuidePanel/BaseGuideControl.resx
Normal file
@@ -0,0 +1,120 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<root>
|
||||||
|
<!--
|
||||||
|
Microsoft ResX Schema
|
||||||
|
|
||||||
|
Version 2.0
|
||||||
|
|
||||||
|
The primary goals of this format is to allow a simple XML format
|
||||||
|
that is mostly human readable. The generation and parsing of the
|
||||||
|
various data types are done through the TypeConverter classes
|
||||||
|
associated with the data types.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
... ado.net/XML headers & schema ...
|
||||||
|
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||||
|
<resheader name="version">2.0</resheader>
|
||||||
|
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||||
|
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||||
|
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||||
|
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||||
|
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||||
|
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||||
|
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||||
|
<comment>This is a comment</comment>
|
||||||
|
</data>
|
||||||
|
|
||||||
|
There are any number of "resheader" rows that contain simple
|
||||||
|
name/value pairs.
|
||||||
|
|
||||||
|
Each data row contains a name, and value. The row also contains a
|
||||||
|
type or mimetype. Type corresponds to a .NET class that support
|
||||||
|
text/value conversion through the TypeConverter architecture.
|
||||||
|
Classes that don't support this are serialized and stored with the
|
||||||
|
mimetype set.
|
||||||
|
|
||||||
|
The mimetype is used for serialized objects, and tells the
|
||||||
|
ResXResourceReader how to depersist the object. This is currently not
|
||||||
|
extensible. For a given mimetype the value must be set accordingly:
|
||||||
|
|
||||||
|
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||||
|
that the ResXResourceWriter will generate, however the reader can
|
||||||
|
read any of the formats listed below.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.binary.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.soap.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||||
|
value : The object must be serialized into a byte array
|
||||||
|
: using a System.ComponentModel.TypeConverter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
-->
|
||||||
|
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||||
|
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||||
|
<xsd:element name="root" msdata:IsDataSet="true">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:choice maxOccurs="unbounded">
|
||||||
|
<xsd:element name="metadata">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="assembly">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:attribute name="alias" type="xsd:string" />
|
||||||
|
<xsd:attribute name="name" type="xsd:string" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="data">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="resheader">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:choice>
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:schema>
|
||||||
|
<resheader name="resmimetype">
|
||||||
|
<value>text/microsoft-resx</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="version">
|
||||||
|
<value>2.0</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="reader">
|
||||||
|
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="writer">
|
||||||
|
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
</root>
|
||||||
77
CanFly/UI/GuidePanel/CtrlTitleBar.Designer.cs
generated
Normal file
77
CanFly/UI/GuidePanel/CtrlTitleBar.Designer.cs
generated
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
namespace CanFly.UI.GuidePanel
|
||||||
|
{
|
||||||
|
partial class CtrlTitleBar
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 必需的设计器变量。
|
||||||
|
/// </summary>
|
||||||
|
private System.ComponentModel.IContainer components = null;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 清理所有正在使用的资源。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="disposing">如果应释放托管资源,为 true;否则为 false。</param>
|
||||||
|
protected override void Dispose(bool disposing)
|
||||||
|
{
|
||||||
|
if (disposing && (components != null))
|
||||||
|
{
|
||||||
|
components.Dispose();
|
||||||
|
}
|
||||||
|
base.Dispose(disposing);
|
||||||
|
}
|
||||||
|
|
||||||
|
#region 组件设计器生成的代码
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 设计器支持所需的方法 - 不要修改
|
||||||
|
/// 使用代码编辑器修改此方法的内容。
|
||||||
|
/// </summary>
|
||||||
|
private void InitializeComponent()
|
||||||
|
{
|
||||||
|
btnClose = new PictureBox();
|
||||||
|
j = new Label();
|
||||||
|
((System.ComponentModel.ISupportInitialize)btnClose).BeginInit();
|
||||||
|
SuspendLayout();
|
||||||
|
//
|
||||||
|
// btnClose
|
||||||
|
//
|
||||||
|
btnClose.Dock = DockStyle.Right;
|
||||||
|
btnClose.Image = XKRS.CanFly.Properties.Resources.Close;
|
||||||
|
btnClose.Location = new Point(516, 3);
|
||||||
|
btnClose.Name = "btnClose";
|
||||||
|
btnClose.Size = new Size(30, 30);
|
||||||
|
btnClose.SizeMode = PictureBoxSizeMode.StretchImage;
|
||||||
|
btnClose.TabIndex = 1;
|
||||||
|
btnClose.TabStop = false;
|
||||||
|
btnClose.Click += btnClose_Click;
|
||||||
|
//
|
||||||
|
// j
|
||||||
|
//
|
||||||
|
j.Dock = DockStyle.Fill;
|
||||||
|
j.Font = new Font("Microsoft YaHei UI", 12F, FontStyle.Bold, GraphicsUnit.Point);
|
||||||
|
j.Location = new Point(3, 3);
|
||||||
|
j.Name = "j";
|
||||||
|
j.Size = new Size(513, 30);
|
||||||
|
j.TabIndex = 2;
|
||||||
|
j.Text = "标题";
|
||||||
|
j.TextAlign = ContentAlignment.MiddleLeft;
|
||||||
|
//
|
||||||
|
// CtrlTitleBar
|
||||||
|
//
|
||||||
|
AutoScaleDimensions = new SizeF(7F, 17F);
|
||||||
|
AutoScaleMode = AutoScaleMode.Font;
|
||||||
|
Controls.Add(j);
|
||||||
|
Controls.Add(btnClose);
|
||||||
|
MinimumSize = new Size(0, 36);
|
||||||
|
Name = "CtrlTitleBar";
|
||||||
|
Padding = new Padding(3);
|
||||||
|
Size = new Size(549, 36);
|
||||||
|
((System.ComponentModel.ISupportInitialize)btnClose).EndInit();
|
||||||
|
ResumeLayout(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
private PictureBox btnClose;
|
||||||
|
private Label j;
|
||||||
|
}
|
||||||
|
}
|
||||||
38
CanFly/UI/GuidePanel/CtrlTitleBar.cs
Normal file
38
CanFly/UI/GuidePanel/CtrlTitleBar.cs
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.ComponentModel;
|
||||||
|
using System.Data;
|
||||||
|
using System.Drawing;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Windows.Forms;
|
||||||
|
|
||||||
|
namespace CanFly.UI.GuidePanel
|
||||||
|
{
|
||||||
|
public partial class CtrlTitleBar : UserControl
|
||||||
|
{
|
||||||
|
public event Action? OnCloseClicked;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
[DisplayName("Title")]
|
||||||
|
public string Title
|
||||||
|
{
|
||||||
|
get { return this.j.Text; }
|
||||||
|
set { this.j.Text = value; }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public CtrlTitleBar()
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
this.Dock = DockStyle.Top;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void btnClose_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
OnCloseClicked?.Invoke();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
120
CanFly/UI/GuidePanel/CtrlTitleBar.resx
Normal file
120
CanFly/UI/GuidePanel/CtrlTitleBar.resx
Normal file
@@ -0,0 +1,120 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<root>
|
||||||
|
<!--
|
||||||
|
Microsoft ResX Schema
|
||||||
|
|
||||||
|
Version 2.0
|
||||||
|
|
||||||
|
The primary goals of this format is to allow a simple XML format
|
||||||
|
that is mostly human readable. The generation and parsing of the
|
||||||
|
various data types are done through the TypeConverter classes
|
||||||
|
associated with the data types.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
... ado.net/XML headers & schema ...
|
||||||
|
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||||
|
<resheader name="version">2.0</resheader>
|
||||||
|
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||||
|
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||||
|
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||||
|
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||||
|
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||||
|
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||||
|
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||||
|
<comment>This is a comment</comment>
|
||||||
|
</data>
|
||||||
|
|
||||||
|
There are any number of "resheader" rows that contain simple
|
||||||
|
name/value pairs.
|
||||||
|
|
||||||
|
Each data row contains a name, and value. The row also contains a
|
||||||
|
type or mimetype. Type corresponds to a .NET class that support
|
||||||
|
text/value conversion through the TypeConverter architecture.
|
||||||
|
Classes that don't support this are serialized and stored with the
|
||||||
|
mimetype set.
|
||||||
|
|
||||||
|
The mimetype is used for serialized objects, and tells the
|
||||||
|
ResXResourceReader how to depersist the object. This is currently not
|
||||||
|
extensible. For a given mimetype the value must be set accordingly:
|
||||||
|
|
||||||
|
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||||
|
that the ResXResourceWriter will generate, however the reader can
|
||||||
|
read any of the formats listed below.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.binary.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.soap.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||||
|
value : The object must be serialized into a byte array
|
||||||
|
: using a System.ComponentModel.TypeConverter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
-->
|
||||||
|
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||||
|
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||||
|
<xsd:element name="root" msdata:IsDataSet="true">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:choice maxOccurs="unbounded">
|
||||||
|
<xsd:element name="metadata">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="assembly">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:attribute name="alias" type="xsd:string" />
|
||||||
|
<xsd:attribute name="name" type="xsd:string" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="data">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="resheader">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:choice>
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:schema>
|
||||||
|
<resheader name="resmimetype">
|
||||||
|
<value>text/microsoft-resx</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="version">
|
||||||
|
<value>2.0</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="reader">
|
||||||
|
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="writer">
|
||||||
|
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
</root>
|
||||||
364
CanFly/UI/GuidePanel/GuideCircleCtrl.Designer.cs
generated
Normal file
364
CanFly/UI/GuidePanel/GuideCircleCtrl.Designer.cs
generated
Normal file
@@ -0,0 +1,364 @@
|
|||||||
|
namespace CanFly.UI.GuidePanel
|
||||||
|
{
|
||||||
|
partial class GuideCircleCtrl
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 必需的设计器变量。
|
||||||
|
/// </summary>
|
||||||
|
private System.ComponentModel.IContainer components = null;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 清理所有正在使用的资源。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="disposing">如果应释放托管资源,为 true;否则为 false。</param>
|
||||||
|
protected override void Dispose(bool disposing)
|
||||||
|
{
|
||||||
|
if (disposing && (components != null))
|
||||||
|
{
|
||||||
|
components.Dispose();
|
||||||
|
}
|
||||||
|
base.Dispose(disposing);
|
||||||
|
}
|
||||||
|
|
||||||
|
#region 组件设计器生成的代码
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 设计器支持所需的方法 - 不要修改
|
||||||
|
/// 使用代码编辑器修改此方法的内容。
|
||||||
|
/// </summary>
|
||||||
|
private void InitializeComponent()
|
||||||
|
{
|
||||||
|
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(GuideCircleCtrl));
|
||||||
|
splitContainer = new SplitContainer();
|
||||||
|
panel1 = new Panel();
|
||||||
|
canvas = new Canvas.UI.FlyCanvas();
|
||||||
|
statusStrip1 = new StatusStrip();
|
||||||
|
lblStatus = new ToolStripStatusLabel();
|
||||||
|
btnClose = new PictureBox();
|
||||||
|
label4 = new Label();
|
||||||
|
btnExecute = new Button();
|
||||||
|
lblElapsed = new Label();
|
||||||
|
ctrlTitleBar = new CtrlTitleBar();
|
||||||
|
groupBox1 = new GroupBox();
|
||||||
|
label1 = new Label();
|
||||||
|
label2 = new Label();
|
||||||
|
label3 = new Label();
|
||||||
|
tbR = new TextBox();
|
||||||
|
tbY = new TextBox();
|
||||||
|
tbX = new TextBox();
|
||||||
|
btnLoadImage = new Button();
|
||||||
|
btnCreateCircle = new Button();
|
||||||
|
btnSave = new Button();
|
||||||
|
label6 = new Label();
|
||||||
|
lblResult = new Label();
|
||||||
|
panelGuide = new Panel();
|
||||||
|
((System.ComponentModel.ISupportInitialize)splitContainer).BeginInit();
|
||||||
|
splitContainer.Panel1.SuspendLayout();
|
||||||
|
splitContainer.Panel2.SuspendLayout();
|
||||||
|
splitContainer.SuspendLayout();
|
||||||
|
panel1.SuspendLayout();
|
||||||
|
statusStrip1.SuspendLayout();
|
||||||
|
((System.ComponentModel.ISupportInitialize)btnClose).BeginInit();
|
||||||
|
groupBox1.SuspendLayout();
|
||||||
|
panelGuide.SuspendLayout();
|
||||||
|
SuspendLayout();
|
||||||
|
//
|
||||||
|
// splitContainer
|
||||||
|
//
|
||||||
|
splitContainer.Dock = DockStyle.Fill;
|
||||||
|
splitContainer.Location = new Point(0, 0);
|
||||||
|
splitContainer.Name = "splitContainer";
|
||||||
|
//
|
||||||
|
// splitContainer.Panel1
|
||||||
|
//
|
||||||
|
splitContainer.Panel1.Controls.Add(panelGuide);
|
||||||
|
splitContainer.Panel1MinSize = 150;
|
||||||
|
//
|
||||||
|
// splitContainer.Panel2
|
||||||
|
//
|
||||||
|
splitContainer.Panel2.Controls.Add(panel1);
|
||||||
|
splitContainer.Size = new Size(1280, 640);
|
||||||
|
splitContainer.SplitterDistance = 200;
|
||||||
|
splitContainer.TabIndex = 12;
|
||||||
|
//
|
||||||
|
// panel1
|
||||||
|
//
|
||||||
|
panel1.BorderStyle = BorderStyle.FixedSingle;
|
||||||
|
panel1.Controls.Add(canvas);
|
||||||
|
panel1.Controls.Add(statusStrip1);
|
||||||
|
panel1.Dock = DockStyle.Fill;
|
||||||
|
panel1.Location = new Point(0, 0);
|
||||||
|
panel1.Name = "panel1";
|
||||||
|
panel1.Size = new Size(1076, 640);
|
||||||
|
panel1.TabIndex = 1;
|
||||||
|
//
|
||||||
|
// canvas
|
||||||
|
//
|
||||||
|
canvas.AllowMultiSelect = false;
|
||||||
|
canvas.CreateMode = Canvas.Shape.ShapeTypeEnum.Polygon;
|
||||||
|
canvas.Dock = DockStyle.Fill;
|
||||||
|
canvas.Enabled = false;
|
||||||
|
canvas.FillDrawing = false;
|
||||||
|
canvas.Location = new Point(0, 0);
|
||||||
|
canvas.Margin = new Padding(2);
|
||||||
|
canvas.Name = "canvas";
|
||||||
|
canvas.OutsideShapes = (List<Canvas.Shape.FlyShape>)resources.GetObject("canvas.OutsideShapes");
|
||||||
|
canvas.Scale = 1F;
|
||||||
|
canvas.Shapes = (List<Canvas.Shape.FlyShape>)resources.GetObject("canvas.Shapes");
|
||||||
|
canvas.Size = new Size(1074, 616);
|
||||||
|
canvas.TabIndex = 2;
|
||||||
|
//
|
||||||
|
// statusStrip1
|
||||||
|
//
|
||||||
|
statusStrip1.Items.AddRange(new ToolStripItem[] { lblStatus });
|
||||||
|
statusStrip1.Location = new Point(0, 616);
|
||||||
|
statusStrip1.Name = "statusStrip1";
|
||||||
|
statusStrip1.Size = new Size(1074, 22);
|
||||||
|
statusStrip1.TabIndex = 1;
|
||||||
|
statusStrip1.Text = "statusStrip1";
|
||||||
|
//
|
||||||
|
// lblStatus
|
||||||
|
//
|
||||||
|
lblStatus.Name = "lblStatus";
|
||||||
|
lblStatus.Size = new Size(44, 17);
|
||||||
|
lblStatus.Text = " ";
|
||||||
|
//
|
||||||
|
// btnClose
|
||||||
|
//
|
||||||
|
btnClose.Anchor = AnchorStyles.Top | AnchorStyles.Right;
|
||||||
|
btnClose.Image = XKRS.CanFly.Properties.Resources.Close;
|
||||||
|
btnClose.InitialImage = XKRS.CanFly.Properties.Resources.Close;
|
||||||
|
btnClose.Location = new Point(1102, 3);
|
||||||
|
btnClose.Name = "btnClose";
|
||||||
|
btnClose.Size = new Size(33, 33);
|
||||||
|
btnClose.SizeMode = PictureBoxSizeMode.StretchImage;
|
||||||
|
btnClose.TabIndex = 5;
|
||||||
|
btnClose.TabStop = false;
|
||||||
|
btnClose.Click += btnClose_Click;
|
||||||
|
//
|
||||||
|
// label4
|
||||||
|
//
|
||||||
|
label4.AutoSize = true;
|
||||||
|
label4.Location = new Point(6, 307);
|
||||||
|
label4.Name = "label4";
|
||||||
|
label4.Size = new Size(44, 17);
|
||||||
|
label4.TabIndex = 3;
|
||||||
|
label4.Text = "耗时:";
|
||||||
|
//
|
||||||
|
// btnExecute
|
||||||
|
//
|
||||||
|
btnExecute.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
|
||||||
|
btnExecute.Location = new Point(6, 272);
|
||||||
|
btnExecute.Name = "btnExecute";
|
||||||
|
btnExecute.Size = new Size(186, 32);
|
||||||
|
btnExecute.TabIndex = 2;
|
||||||
|
btnExecute.Text = "执行";
|
||||||
|
btnExecute.UseVisualStyleBackColor = true;
|
||||||
|
btnExecute.Click += btnExecute_Click;
|
||||||
|
//
|
||||||
|
// lblElapsed
|
||||||
|
//
|
||||||
|
lblElapsed.AutoSize = true;
|
||||||
|
lblElapsed.Location = new Point(56, 307);
|
||||||
|
lblElapsed.Name = "lblElapsed";
|
||||||
|
lblElapsed.Size = new Size(32, 17);
|
||||||
|
lblElapsed.TabIndex = 4;
|
||||||
|
lblElapsed.Text = "0ms";
|
||||||
|
//
|
||||||
|
// ctrlTitleBar
|
||||||
|
//
|
||||||
|
ctrlTitleBar.Dock = DockStyle.Top;
|
||||||
|
ctrlTitleBar.Location = new Point(0, 0);
|
||||||
|
ctrlTitleBar.MinimumSize = new Size(0, 36);
|
||||||
|
ctrlTitleBar.Name = "ctrlTitleBar";
|
||||||
|
ctrlTitleBar.Padding = new Padding(3);
|
||||||
|
ctrlTitleBar.Size = new Size(198, 36);
|
||||||
|
ctrlTitleBar.TabIndex = 11;
|
||||||
|
ctrlTitleBar.Title = "圆形测量";
|
||||||
|
//
|
||||||
|
// groupBox1
|
||||||
|
//
|
||||||
|
groupBox1.Controls.Add(tbX);
|
||||||
|
groupBox1.Controls.Add(tbY);
|
||||||
|
groupBox1.Controls.Add(tbR);
|
||||||
|
groupBox1.Controls.Add(label3);
|
||||||
|
groupBox1.Controls.Add(label2);
|
||||||
|
groupBox1.Controls.Add(label1);
|
||||||
|
groupBox1.Dock = DockStyle.Top;
|
||||||
|
groupBox1.Location = new Point(0, 36);
|
||||||
|
groupBox1.Name = "groupBox1";
|
||||||
|
groupBox1.Size = new Size(198, 116);
|
||||||
|
groupBox1.TabIndex = 12;
|
||||||
|
groupBox1.TabStop = false;
|
||||||
|
groupBox1.Text = "圆参数";
|
||||||
|
//
|
||||||
|
// label1
|
||||||
|
//
|
||||||
|
label1.AutoSize = true;
|
||||||
|
label1.Location = new Point(6, 25);
|
||||||
|
label1.Name = "label1";
|
||||||
|
label1.Size = new Size(19, 17);
|
||||||
|
label1.TabIndex = 0;
|
||||||
|
label1.Text = "X:";
|
||||||
|
//
|
||||||
|
// label2
|
||||||
|
//
|
||||||
|
label2.AutoSize = true;
|
||||||
|
label2.Location = new Point(6, 54);
|
||||||
|
label2.Name = "label2";
|
||||||
|
label2.Size = new Size(18, 17);
|
||||||
|
label2.TabIndex = 1;
|
||||||
|
label2.Text = "Y:";
|
||||||
|
//
|
||||||
|
// label3
|
||||||
|
//
|
||||||
|
label3.AutoSize = true;
|
||||||
|
label3.Location = new Point(3, 83);
|
||||||
|
label3.Name = "label3";
|
||||||
|
label3.Size = new Size(44, 17);
|
||||||
|
label3.TabIndex = 2;
|
||||||
|
label3.Text = "半径:";
|
||||||
|
//
|
||||||
|
// tbR
|
||||||
|
//
|
||||||
|
tbR.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
|
||||||
|
tbR.Location = new Point(56, 80);
|
||||||
|
tbR.Name = "tbR";
|
||||||
|
tbR.Size = new Size(136, 23);
|
||||||
|
tbR.TabIndex = 3;
|
||||||
|
//
|
||||||
|
// tbY
|
||||||
|
//
|
||||||
|
tbY.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
|
||||||
|
tbY.Location = new Point(56, 51);
|
||||||
|
tbY.Name = "tbY";
|
||||||
|
tbY.Size = new Size(136, 23);
|
||||||
|
tbY.TabIndex = 4;
|
||||||
|
//
|
||||||
|
// tbX
|
||||||
|
//
|
||||||
|
tbX.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
|
||||||
|
tbX.Location = new Point(56, 22);
|
||||||
|
tbX.Name = "tbX";
|
||||||
|
tbX.Size = new Size(136, 23);
|
||||||
|
tbX.TabIndex = 5;
|
||||||
|
//
|
||||||
|
// btnLoadImage
|
||||||
|
//
|
||||||
|
btnLoadImage.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
|
||||||
|
btnLoadImage.Location = new Point(6, 158);
|
||||||
|
btnLoadImage.Name = "btnLoadImage";
|
||||||
|
btnLoadImage.Size = new Size(186, 32);
|
||||||
|
btnLoadImage.TabIndex = 13;
|
||||||
|
btnLoadImage.Text = "打开图片";
|
||||||
|
btnLoadImage.UseVisualStyleBackColor = true;
|
||||||
|
btnLoadImage.Click += btnLoadImage_Click;
|
||||||
|
//
|
||||||
|
// btnCreateCircle
|
||||||
|
//
|
||||||
|
btnCreateCircle.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
|
||||||
|
btnCreateCircle.Location = new Point(6, 196);
|
||||||
|
btnCreateCircle.Name = "btnCreateCircle";
|
||||||
|
btnCreateCircle.Size = new Size(186, 32);
|
||||||
|
btnCreateCircle.TabIndex = 14;
|
||||||
|
btnCreateCircle.Text = "创建圆形";
|
||||||
|
btnCreateCircle.UseVisualStyleBackColor = true;
|
||||||
|
btnCreateCircle.Click += btnCreateCircle_Click;
|
||||||
|
//
|
||||||
|
// btnSave
|
||||||
|
//
|
||||||
|
btnSave.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
|
||||||
|
btnSave.Location = new Point(9, 397);
|
||||||
|
btnSave.Name = "btnSave";
|
||||||
|
btnSave.Size = new Size(186, 32);
|
||||||
|
btnSave.TabIndex = 15;
|
||||||
|
btnSave.Text = "保存数据";
|
||||||
|
btnSave.UseVisualStyleBackColor = true;
|
||||||
|
btnSave.Click += btnSave_Click;
|
||||||
|
//
|
||||||
|
// label6
|
||||||
|
//
|
||||||
|
label6.AutoSize = true;
|
||||||
|
label6.Location = new Point(6, 338);
|
||||||
|
label6.Name = "label6";
|
||||||
|
label6.Size = new Size(44, 17);
|
||||||
|
label6.TabIndex = 16;
|
||||||
|
label6.Text = "结果:";
|
||||||
|
//
|
||||||
|
// lblResult
|
||||||
|
//
|
||||||
|
lblResult.AutoSize = true;
|
||||||
|
lblResult.Location = new Point(56, 338);
|
||||||
|
lblResult.Name = "lblResult";
|
||||||
|
lblResult.Size = new Size(20, 17);
|
||||||
|
lblResult.TabIndex = 17;
|
||||||
|
lblResult.Text = "无";
|
||||||
|
//
|
||||||
|
// panelGuide
|
||||||
|
//
|
||||||
|
panelGuide.BorderStyle = BorderStyle.FixedSingle;
|
||||||
|
panelGuide.Controls.Add(lblResult);
|
||||||
|
panelGuide.Controls.Add(label6);
|
||||||
|
panelGuide.Controls.Add(btnSave);
|
||||||
|
panelGuide.Controls.Add(btnCreateCircle);
|
||||||
|
panelGuide.Controls.Add(btnLoadImage);
|
||||||
|
panelGuide.Controls.Add(groupBox1);
|
||||||
|
panelGuide.Controls.Add(ctrlTitleBar);
|
||||||
|
panelGuide.Controls.Add(lblElapsed);
|
||||||
|
panelGuide.Controls.Add(btnExecute);
|
||||||
|
panelGuide.Controls.Add(label4);
|
||||||
|
panelGuide.Dock = DockStyle.Fill;
|
||||||
|
panelGuide.Location = new Point(0, 0);
|
||||||
|
panelGuide.Name = "panelGuide";
|
||||||
|
panelGuide.Size = new Size(200, 640);
|
||||||
|
panelGuide.TabIndex = 0;
|
||||||
|
//
|
||||||
|
// GuideCircleCtrl
|
||||||
|
//
|
||||||
|
Controls.Add(splitContainer);
|
||||||
|
Controls.Add(btnClose);
|
||||||
|
Name = "GuideCircleCtrl";
|
||||||
|
Size = new Size(1280, 640);
|
||||||
|
splitContainer.Panel1.ResumeLayout(false);
|
||||||
|
splitContainer.Panel2.ResumeLayout(false);
|
||||||
|
((System.ComponentModel.ISupportInitialize)splitContainer).EndInit();
|
||||||
|
splitContainer.ResumeLayout(false);
|
||||||
|
panel1.ResumeLayout(false);
|
||||||
|
panel1.PerformLayout();
|
||||||
|
statusStrip1.ResumeLayout(false);
|
||||||
|
statusStrip1.PerformLayout();
|
||||||
|
((System.ComponentModel.ISupportInitialize)btnClose).EndInit();
|
||||||
|
groupBox1.ResumeLayout(false);
|
||||||
|
groupBox1.PerformLayout();
|
||||||
|
panelGuide.ResumeLayout(false);
|
||||||
|
panelGuide.PerformLayout();
|
||||||
|
ResumeLayout(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
private SplitContainer splitContainer;
|
||||||
|
private Panel panel1;
|
||||||
|
private Canvas.UI.FlyCanvas canvas;
|
||||||
|
private StatusStrip statusStrip1;
|
||||||
|
private ToolStripStatusLabel lblStatus;
|
||||||
|
private PictureBox btnClose;
|
||||||
|
private Panel panelGuide;
|
||||||
|
private Label lblResult;
|
||||||
|
private Label label6;
|
||||||
|
private Button btnSave;
|
||||||
|
private Button btnCreateCircle;
|
||||||
|
private Button btnLoadImage;
|
||||||
|
private GroupBox groupBox1;
|
||||||
|
private TextBox tbX;
|
||||||
|
private TextBox tbY;
|
||||||
|
private TextBox tbR;
|
||||||
|
private Label label3;
|
||||||
|
private Label label2;
|
||||||
|
private Label label1;
|
||||||
|
private CtrlTitleBar ctrlTitleBar;
|
||||||
|
private Label lblElapsed;
|
||||||
|
private Button btnExecute;
|
||||||
|
private Label label4;
|
||||||
|
}
|
||||||
|
}
|
||||||
359
CanFly/UI/GuidePanel/GuideCircleCtrl.cs
Normal file
359
CanFly/UI/GuidePanel/GuideCircleCtrl.cs
Normal file
@@ -0,0 +1,359 @@
|
|||||||
|
using CanFly.Canvas.Shape;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.ComponentModel;
|
||||||
|
using System.Data;
|
||||||
|
using System.Drawing;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Windows.Forms;
|
||||||
|
using CanFly.Canvas.Helper;
|
||||||
|
using CanFly.Helper;
|
||||||
|
using HalconDotNet;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using CanFly.Canvas.UI;
|
||||||
|
|
||||||
|
|
||||||
|
namespace CanFly.UI.GuidePanel
|
||||||
|
{
|
||||||
|
public partial class GuideCircleCtrl : BaseGuideControl
|
||||||
|
{
|
||||||
|
|
||||||
|
private float _x;
|
||||||
|
private float _y;
|
||||||
|
private float _r;
|
||||||
|
private FlyShape? _circle;
|
||||||
|
|
||||||
|
|
||||||
|
protected override string GetScriptFileName() => "CircleMeasure.hdvp";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public GuideCircleCtrl()
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
|
||||||
|
|
||||||
|
this.canvas.mouseMoved += Canvas_mouseMoved;
|
||||||
|
this.canvas.OnShapeUpdateEvent += UpdateShape;
|
||||||
|
this.canvas.selectionChanged += Canvas_selectionChanged;
|
||||||
|
|
||||||
|
this.canvas.OnShapeMoving += Canvas_OnShapeMoving;
|
||||||
|
this.canvas.newShape += Canvas_newShape;
|
||||||
|
|
||||||
|
this.ctrlTitleBar.OnCloseClicked += OnControlClose;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
protected override void UpdateShape(FlyShape shape)
|
||||||
|
{
|
||||||
|
this._circle = shape;
|
||||||
|
|
||||||
|
_x = shape.Points[0].X;
|
||||||
|
_y = shape.Points[0].Y;
|
||||||
|
_r = PointHelper.Distance(shape.Points[0], shape.Points[1]);
|
||||||
|
|
||||||
|
this.tbX.Text = shape.Points[0].X.ToString("F3");
|
||||||
|
this.tbY.Text = shape.Points[0].Y.ToString("F3");
|
||||||
|
this.tbR.Text = _r.ToString("F3");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private void btnExecute_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
if (this.canvas.pixmap == null)
|
||||||
|
{
|
||||||
|
MessageBox.Show("请先打开图片");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(this.tbX.Text.Trim().Length == 0)
|
||||||
|
{
|
||||||
|
MessageBox.Show("请先创建圆形");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
this.canvas.OutsideShapes.Clear();
|
||||||
|
this.canvas.Invalidate();
|
||||||
|
|
||||||
|
flag = new List<double>();
|
||||||
|
x = new List<double>();
|
||||||
|
y = new List<double>();
|
||||||
|
r = new List<double>();
|
||||||
|
Dictionary<string, HObject> inputImg = new Dictionary<string, HObject>();
|
||||||
|
|
||||||
|
if (hImage == null)
|
||||||
|
{
|
||||||
|
HOperatorSet.ReadImage(out hImage, CurrentImageFile);
|
||||||
|
}
|
||||||
|
inputImg["INPUT_Image"] = hImage;
|
||||||
|
|
||||||
|
Dictionary<string, HTuple> inputPara = new Dictionary<string, HTuple>();
|
||||||
|
|
||||||
|
|
||||||
|
inputPara["XCenter"] = _x;
|
||||||
|
inputPara["YCenter"] = _y;
|
||||||
|
inputPara["Radius"] = _r;
|
||||||
|
|
||||||
|
|
||||||
|
List<string> outputKeys = new List<string>()
|
||||||
|
{
|
||||||
|
"OUTPUT_PreTreatedImage",
|
||||||
|
"OUTPUT_Flag",
|
||||||
|
"RXCenter",
|
||||||
|
"RYCenter",
|
||||||
|
"RRadius"
|
||||||
|
};
|
||||||
|
|
||||||
|
ExecuteHScript(
|
||||||
|
inputImg,
|
||||||
|
inputPara,
|
||||||
|
outputKeys);
|
||||||
|
|
||||||
|
}
|
||||||
|
List<double> flag = new List<double>(), x=new List<double>(),y=new List<double>(),r=new List<double>();
|
||||||
|
|
||||||
|
protected override void OnExecuteHScriptResult(
|
||||||
|
bool success,
|
||||||
|
Dictionary<string, HTuple> resultDic,
|
||||||
|
int timeElasped)
|
||||||
|
{
|
||||||
|
if (!success)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
"OUTPUT_Flag",
|
||||||
|
"RXCenter",
|
||||||
|
"RYCenter",
|
||||||
|
"RRadius"
|
||||||
|
*/
|
||||||
|
|
||||||
|
//取图?????
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
flag = resultDic["OUTPUT_Flag"].HTupleToDouble();
|
||||||
|
x = resultDic["RXCenter"].HTupleToDouble();
|
||||||
|
y = resultDic["RYCenter"].HTupleToDouble();
|
||||||
|
r = resultDic["RRadius"].HTupleToDouble();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if (flag.Count > 0)
|
||||||
|
{
|
||||||
|
lblResult.Text = flag[0].ToString();
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
lblResult.Text = "无";
|
||||||
|
}
|
||||||
|
if (flag.Count > 0 && x.Count > 0 && y.Count > 0 && r.Count > 0)
|
||||||
|
{
|
||||||
|
|
||||||
|
//detectResult.VisionImageSet.MLImage = resultDic["RRadius"].GetResultObject("OUTPUT_PreTreatedImage");
|
||||||
|
this.canvas.DrawCircle(new PointF((float)x[0], (float)y[0]), (float)r[0]);
|
||||||
|
lblElapsed.Text = $"{timeElasped} ms";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private void Test()
|
||||||
|
{
|
||||||
|
string filePath = Path.Combine(_hScriptsDir, GetScriptFileName());
|
||||||
|
if (!File.Exists(filePath))
|
||||||
|
{
|
||||||
|
MessageBox.Show($"文件 {filePath} 不存在");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
HDevEngineTool tool = new HDevEngineTool(_hScriptsDir);
|
||||||
|
tool.LoadProcedure(Path.GetFileNameWithoutExtension(GetScriptFileName()));
|
||||||
|
|
||||||
|
|
||||||
|
if (hImage == null)
|
||||||
|
{
|
||||||
|
HOperatorSet.ReadImage(out hImage, CurrentImageFile);
|
||||||
|
}
|
||||||
|
|
||||||
|
tool.InputImageDic["INPUT_Image"] = hImage;
|
||||||
|
tool.InputTupleDic["XCenter"] = _x;
|
||||||
|
tool.InputTupleDic["YCenter"] = _y;
|
||||||
|
tool.InputTupleDic["Radius"] = _r;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if (!tool.RunProcedure(out string error, out int timeElasped))
|
||||||
|
{
|
||||||
|
throw new Exception();
|
||||||
|
}
|
||||||
|
|
||||||
|
HTuple hFlag = tool.GetResultTuple("OUTPUT_Flag");
|
||||||
|
|
||||||
|
var flag = tool.GetResultTuple("OUTPUT_Flag").HTupleToDouble();
|
||||||
|
List<double> x = tool.GetResultTuple("RXCenter").HTupleToDouble();
|
||||||
|
var y = tool.GetResultTuple("RYCenter").HTupleToDouble();
|
||||||
|
var r = tool.GetResultTuple("RRadius").HTupleToDouble();
|
||||||
|
if (flag.Count > 0)
|
||||||
|
{
|
||||||
|
lblResult.Text = flag[0].ToString();
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
lblResult.Text = "无";
|
||||||
|
}
|
||||||
|
if (flag.Count > 0 && x.Count > 0 && y.Count > 0 && r.Count > 0)
|
||||||
|
{
|
||||||
|
this.canvas.DrawCircle(new PointF((float)x[0], (float)y[0]), (float)r[0]);
|
||||||
|
lblElapsed.Text = $"{timeElasped} ms";
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
Debug.WriteLine("");
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
hImage?.Dispose();
|
||||||
|
hImage = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private void btnClose_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
OnControlCloseEvent?.Invoke();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void btnLoadImage_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
OpenImageFile(bitmap =>
|
||||||
|
{
|
||||||
|
this.canvas.LoadPixmap(bitmap);
|
||||||
|
this.canvas.Enabled = true;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private void Canvas_mouseMoved(PointF pos)
|
||||||
|
{
|
||||||
|
if (InvokeRequired)
|
||||||
|
{
|
||||||
|
Invoke(Canvas_mouseMoved, pos);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
lblStatus.Text = $"X:{pos.X}, Y:{pos.Y}";
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private void Canvas_selectionChanged(List<FlyShape> shapes)
|
||||||
|
{
|
||||||
|
//if (shapes.Count != 1)
|
||||||
|
//{
|
||||||
|
// // panelGuide.Controls.Clear();
|
||||||
|
// return;
|
||||||
|
//}
|
||||||
|
//SwitchGuideForm(shapes[0].ShapeType);
|
||||||
|
// Canvas_OnShapeUpdateEvent(shapes[0]);
|
||||||
|
|
||||||
|
if (shapes.Count != 1)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
UpdateShape(shapes[0]);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void Canvas_OnShapeMoving(List<FlyShape> shapes)
|
||||||
|
{
|
||||||
|
if (shapes.Count != 1)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
UpdateShape(shapes[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void btnCreateCircle_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
if (this.canvas.pixmap == null)
|
||||||
|
{
|
||||||
|
MessageBox.Show("请先打开图片");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.tbX.Text = string.Empty;
|
||||||
|
this.tbY.Text = string.Empty;
|
||||||
|
this.tbR.Text = string.Empty;
|
||||||
|
this.canvas.Shapes.Clear();
|
||||||
|
this.canvas.Invalidate();
|
||||||
|
this.canvas.StartDraw(ShapeTypeEnum.Circle);
|
||||||
|
this.canvas.Enabled = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private void Canvas_newShape()
|
||||||
|
{
|
||||||
|
|
||||||
|
this.canvas.StopDraw();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void btnSave_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
if (lblResult.Text.Equals("无"))
|
||||||
|
{
|
||||||
|
MessageBox.Show("请先进行绘制");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(lblResult.Text != "0")
|
||||||
|
{
|
||||||
|
MessageBox.Show("测量计算错误,无法保存");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//List<double> x = tool.GetResultTuple("RXCenter").HTupleToDouble();
|
||||||
|
//var y = tool.GetResultTuple("RYCenter").HTupleToDouble();
|
||||||
|
//var r = tool.GetResultTuple("RRadius").HTupleToDouble();
|
||||||
|
//tool.InputTupleDic["XCenter"] = _x;
|
||||||
|
//tool.InputTupleDic["YCenter"] = _y;
|
||||||
|
//tool.InputTupleDic["Radius"] = _r;
|
||||||
|
string inputput = $"XCenter:{string.Join(";", _x)};YCenter:{string.Join(";", _y)};RRadius:{string.Join(";", _r)}";
|
||||||
|
string output = $"RXCenter:{string.Join(";", x[0])};RYCenter:{string.Join(";", y[0])};RRadius:{string.Join(";", r[0])}";
|
||||||
|
|
||||||
|
DataToTriggerEvent(inputput,output);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
145
CanFly/UI/GuidePanel/GuideCircleCtrl.resx
Normal file
145
CanFly/UI/GuidePanel/GuideCircleCtrl.resx
Normal file
@@ -0,0 +1,145 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<root>
|
||||||
|
<!--
|
||||||
|
Microsoft ResX Schema
|
||||||
|
|
||||||
|
Version 2.0
|
||||||
|
|
||||||
|
The primary goals of this format is to allow a simple XML format
|
||||||
|
that is mostly human readable. The generation and parsing of the
|
||||||
|
various data types are done through the TypeConverter classes
|
||||||
|
associated with the data types.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
... ado.net/XML headers & schema ...
|
||||||
|
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||||
|
<resheader name="version">2.0</resheader>
|
||||||
|
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||||
|
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||||
|
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||||
|
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||||
|
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||||
|
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||||
|
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||||
|
<comment>This is a comment</comment>
|
||||||
|
</data>
|
||||||
|
|
||||||
|
There are any number of "resheader" rows that contain simple
|
||||||
|
name/value pairs.
|
||||||
|
|
||||||
|
Each data row contains a name, and value. The row also contains a
|
||||||
|
type or mimetype. Type corresponds to a .NET class that support
|
||||||
|
text/value conversion through the TypeConverter architecture.
|
||||||
|
Classes that don't support this are serialized and stored with the
|
||||||
|
mimetype set.
|
||||||
|
|
||||||
|
The mimetype is used for serialized objects, and tells the
|
||||||
|
ResXResourceReader how to depersist the object. This is currently not
|
||||||
|
extensible. For a given mimetype the value must be set accordingly:
|
||||||
|
|
||||||
|
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||||
|
that the ResXResourceWriter will generate, however the reader can
|
||||||
|
read any of the formats listed below.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.binary.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.soap.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||||
|
value : The object must be serialized into a byte array
|
||||||
|
: using a System.ComponentModel.TypeConverter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
-->
|
||||||
|
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||||
|
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||||
|
<xsd:element name="root" msdata:IsDataSet="true">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:choice maxOccurs="unbounded">
|
||||||
|
<xsd:element name="metadata">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="assembly">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:attribute name="alias" type="xsd:string" />
|
||||||
|
<xsd:attribute name="name" type="xsd:string" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="data">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="resheader">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:choice>
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:schema>
|
||||||
|
<resheader name="resmimetype">
|
||||||
|
<value>text/microsoft-resx</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="version">
|
||||||
|
<value>2.0</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="reader">
|
||||||
|
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="writer">
|
||||||
|
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
<data name="canvas.OutsideShapes" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||||
|
<value>
|
||||||
|
AAEAAAD/////AQAAAAAAAAAMAgAAAERDYW5GbHkuQ2FudmFzLCBWZXJzaW9uPTEuMC4wLjAsIEN1bHR1
|
||||||
|
cmU9bmV1dHJhbCwgUHVibGljS2V5VG9rZW49bnVsbAQBAAAAdlN5c3RlbS5Db2xsZWN0aW9ucy5HZW5l
|
||||||
|
cmljLkxpc3RgMVtbQ2FuRmx5LkNhbnZhcy5TaGFwZS5GbHlTaGFwZSwgQ2FuRmx5LkNhbnZhcywgQ3Vs
|
||||||
|
dHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1udWxsXV0DAAAABl9pdGVtcwVfc2l6ZQhfdmVyc2lv
|
||||||
|
bgQAAB5DYW5GbHkuQ2FudmFzLlNoYXBlLkZseVNoYXBlW10CAAAACAgJAwAAAAAAAAAAAAAADAQAAAAz
|
||||||
|
Q2FuRmx5LkNhbnZhcywgQ3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1udWxsBwMAAAAAAQAA
|
||||||
|
AAAAAAAEHENhbkZseS5DYW52YXMuU2hhcGUuRmx5U2hhcGUEAAAACw==
|
||||||
|
</value>
|
||||||
|
</data>
|
||||||
|
<data name="canvas.Shapes" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||||
|
<value>
|
||||||
|
AAEAAAD/////AQAAAAAAAAAMAgAAAERDYW5GbHkuQ2FudmFzLCBWZXJzaW9uPTEuMC4wLjAsIEN1bHR1
|
||||||
|
cmU9bmV1dHJhbCwgUHVibGljS2V5VG9rZW49bnVsbAQBAAAAdlN5c3RlbS5Db2xsZWN0aW9ucy5HZW5l
|
||||||
|
cmljLkxpc3RgMVtbQ2FuRmx5LkNhbnZhcy5TaGFwZS5GbHlTaGFwZSwgQ2FuRmx5LkNhbnZhcywgQ3Vs
|
||||||
|
dHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1udWxsXV0DAAAABl9pdGVtcwVfc2l6ZQhfdmVyc2lv
|
||||||
|
bgQAAB5DYW5GbHkuQ2FudmFzLlNoYXBlLkZseVNoYXBlW10CAAAACAgJAwAAAAAAAAAAAAAADAQAAAAz
|
||||||
|
Q2FuRmx5LkNhbnZhcywgQ3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1udWxsBwMAAAAAAQAA
|
||||||
|
AAAAAAAEHENhbkZseS5DYW52YXMuU2hhcGUuRmx5U2hhcGUEAAAACw==
|
||||||
|
</value>
|
||||||
|
</data>
|
||||||
|
<metadata name="statusStrip1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||||
|
<value>17, 17</value>
|
||||||
|
</metadata>
|
||||||
|
</root>
|
||||||
446
CanFly/UI/GuidePanel/GuideHeightCtrl.Designer.cs
generated
Normal file
446
CanFly/UI/GuidePanel/GuideHeightCtrl.Designer.cs
generated
Normal file
@@ -0,0 +1,446 @@
|
|||||||
|
namespace CanFly.UI.GuidePanel
|
||||||
|
{
|
||||||
|
partial class GuideHeightCtrl
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 必需的设计器变量。
|
||||||
|
/// </summary>
|
||||||
|
private System.ComponentModel.IContainer components = null;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 清理所有正在使用的资源。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="disposing">如果应释放托管资源,为 true;否则为 false。</param>
|
||||||
|
protected override void Dispose(bool disposing)
|
||||||
|
{
|
||||||
|
if (disposing && (components != null))
|
||||||
|
{
|
||||||
|
components.Dispose();
|
||||||
|
}
|
||||||
|
base.Dispose(disposing);
|
||||||
|
}
|
||||||
|
|
||||||
|
#region 组件设计器生成的代码
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 设计器支持所需的方法 - 不要修改
|
||||||
|
/// 使用代码编辑器修改此方法的内容。
|
||||||
|
/// </summary>
|
||||||
|
private void InitializeComponent()
|
||||||
|
{
|
||||||
|
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(GuideHeightCtrl));
|
||||||
|
lblElapsed = new Label();
|
||||||
|
label4 = new Label();
|
||||||
|
splitContainer = new SplitContainer();
|
||||||
|
panelGuide = new Panel();
|
||||||
|
btnSave = new Button();
|
||||||
|
lblResult = new Label();
|
||||||
|
label1 = new Label();
|
||||||
|
btnCreateLine = new Button();
|
||||||
|
btnLoadImage = new Button();
|
||||||
|
label9 = new Label();
|
||||||
|
btnExecute = new Button();
|
||||||
|
label10 = new Label();
|
||||||
|
groupBox2 = new GroupBox();
|
||||||
|
tbheight = new TextBox();
|
||||||
|
lbheight = new Label();
|
||||||
|
tbwidth = new TextBox();
|
||||||
|
label2 = new Label();
|
||||||
|
tbLineX2 = new TextBox();
|
||||||
|
label8 = new Label();
|
||||||
|
tbLineY2 = new TextBox();
|
||||||
|
label5 = new Label();
|
||||||
|
tbLineX1 = new TextBox();
|
||||||
|
tbLineY1 = new TextBox();
|
||||||
|
label6 = new Label();
|
||||||
|
label7 = new Label();
|
||||||
|
ctrlTitleBar = new CtrlTitleBar();
|
||||||
|
panel1 = new Panel();
|
||||||
|
canvas = new Canvas.UI.FlyCanvas();
|
||||||
|
statusStrip1 = new StatusStrip();
|
||||||
|
lblStatus = new ToolStripStatusLabel();
|
||||||
|
((System.ComponentModel.ISupportInitialize)splitContainer).BeginInit();
|
||||||
|
splitContainer.Panel1.SuspendLayout();
|
||||||
|
splitContainer.Panel2.SuspendLayout();
|
||||||
|
splitContainer.SuspendLayout();
|
||||||
|
panelGuide.SuspendLayout();
|
||||||
|
groupBox2.SuspendLayout();
|
||||||
|
panel1.SuspendLayout();
|
||||||
|
statusStrip1.SuspendLayout();
|
||||||
|
SuspendLayout();
|
||||||
|
//
|
||||||
|
// lblElapsed
|
||||||
|
//
|
||||||
|
lblElapsed.AutoSize = true;
|
||||||
|
lblElapsed.Location = new Point(50, 328);
|
||||||
|
lblElapsed.Name = "lblElapsed";
|
||||||
|
lblElapsed.Size = new Size(32, 17);
|
||||||
|
lblElapsed.TabIndex = 9;
|
||||||
|
lblElapsed.Text = "0ms";
|
||||||
|
//
|
||||||
|
// label4
|
||||||
|
//
|
||||||
|
label4.AutoSize = true;
|
||||||
|
label4.Location = new Point(0, 328);
|
||||||
|
label4.Name = "label4";
|
||||||
|
label4.Size = new Size(44, 17);
|
||||||
|
label4.TabIndex = 8;
|
||||||
|
label4.Text = "耗时:";
|
||||||
|
//
|
||||||
|
// splitContainer
|
||||||
|
//
|
||||||
|
splitContainer.Dock = DockStyle.Fill;
|
||||||
|
splitContainer.Location = new Point(0, 0);
|
||||||
|
splitContainer.Name = "splitContainer";
|
||||||
|
//
|
||||||
|
// splitContainer.Panel1
|
||||||
|
//
|
||||||
|
splitContainer.Panel1.Controls.Add(panelGuide);
|
||||||
|
splitContainer.Panel1MinSize = 150;
|
||||||
|
//
|
||||||
|
// splitContainer.Panel2
|
||||||
|
//
|
||||||
|
splitContainer.Panel2.Controls.Add(panel1);
|
||||||
|
splitContainer.Size = new Size(1280, 640);
|
||||||
|
splitContainer.SplitterDistance = 200;
|
||||||
|
splitContainer.TabIndex = 11;
|
||||||
|
//
|
||||||
|
// panelGuide
|
||||||
|
//
|
||||||
|
panelGuide.BorderStyle = BorderStyle.FixedSingle;
|
||||||
|
panelGuide.Controls.Add(btnSave);
|
||||||
|
panelGuide.Controls.Add(lblResult);
|
||||||
|
panelGuide.Controls.Add(label1);
|
||||||
|
panelGuide.Controls.Add(btnCreateLine);
|
||||||
|
panelGuide.Controls.Add(btnLoadImage);
|
||||||
|
panelGuide.Controls.Add(label9);
|
||||||
|
panelGuide.Controls.Add(btnExecute);
|
||||||
|
panelGuide.Controls.Add(label10);
|
||||||
|
panelGuide.Controls.Add(groupBox2);
|
||||||
|
panelGuide.Controls.Add(ctrlTitleBar);
|
||||||
|
panelGuide.Dock = DockStyle.Fill;
|
||||||
|
panelGuide.Location = new Point(0, 0);
|
||||||
|
panelGuide.Name = "panelGuide";
|
||||||
|
panelGuide.Size = new Size(200, 640);
|
||||||
|
panelGuide.TabIndex = 0;
|
||||||
|
//
|
||||||
|
// btnSave
|
||||||
|
//
|
||||||
|
btnSave.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
|
||||||
|
btnSave.Location = new Point(2, 419);
|
||||||
|
btnSave.Name = "btnSave";
|
||||||
|
btnSave.Size = new Size(186, 32);
|
||||||
|
btnSave.TabIndex = 23;
|
||||||
|
btnSave.Text = "保存数据";
|
||||||
|
btnSave.UseVisualStyleBackColor = true;
|
||||||
|
btnSave.Click += btnSave_Click;
|
||||||
|
//
|
||||||
|
// lblResult
|
||||||
|
//
|
||||||
|
lblResult.AutoSize = true;
|
||||||
|
lblResult.Location = new Point(59, 354);
|
||||||
|
lblResult.Name = "lblResult";
|
||||||
|
lblResult.Size = new Size(20, 17);
|
||||||
|
lblResult.TabIndex = 22;
|
||||||
|
lblResult.Text = "无";
|
||||||
|
//
|
||||||
|
// label1
|
||||||
|
//
|
||||||
|
label1.AutoSize = true;
|
||||||
|
label1.Location = new Point(9, 354);
|
||||||
|
label1.Name = "label1";
|
||||||
|
label1.Size = new Size(44, 17);
|
||||||
|
label1.TabIndex = 21;
|
||||||
|
label1.Text = "结果:";
|
||||||
|
//
|
||||||
|
// btnCreateLine
|
||||||
|
//
|
||||||
|
btnCreateLine.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
|
||||||
|
btnCreateLine.Location = new Point(9, 252);
|
||||||
|
btnCreateLine.Name = "btnCreateLine";
|
||||||
|
btnCreateLine.Size = new Size(186, 32);
|
||||||
|
btnCreateLine.TabIndex = 20;
|
||||||
|
btnCreateLine.Text = "创建矩形";
|
||||||
|
btnCreateLine.UseVisualStyleBackColor = true;
|
||||||
|
btnCreateLine.Click += btnCreateLine_Click;
|
||||||
|
//
|
||||||
|
// btnLoadImage
|
||||||
|
//
|
||||||
|
btnLoadImage.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
|
||||||
|
btnLoadImage.Location = new Point(6, 214);
|
||||||
|
btnLoadImage.Name = "btnLoadImage";
|
||||||
|
btnLoadImage.Size = new Size(186, 32);
|
||||||
|
btnLoadImage.TabIndex = 18;
|
||||||
|
btnLoadImage.Text = "打开图片";
|
||||||
|
btnLoadImage.UseVisualStyleBackColor = true;
|
||||||
|
btnLoadImage.Click += btnLoadImage_Click;
|
||||||
|
//
|
||||||
|
// label9
|
||||||
|
//
|
||||||
|
label9.AutoSize = true;
|
||||||
|
label9.Location = new Point(59, 325);
|
||||||
|
label9.Name = "label9";
|
||||||
|
label9.Size = new Size(32, 17);
|
||||||
|
label9.TabIndex = 17;
|
||||||
|
label9.Text = "0ms";
|
||||||
|
//
|
||||||
|
// btnExecute
|
||||||
|
//
|
||||||
|
btnExecute.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
|
||||||
|
btnExecute.Location = new Point(9, 290);
|
||||||
|
btnExecute.Name = "btnExecute";
|
||||||
|
btnExecute.Size = new Size(186, 32);
|
||||||
|
btnExecute.TabIndex = 15;
|
||||||
|
btnExecute.Text = "执行";
|
||||||
|
btnExecute.UseVisualStyleBackColor = true;
|
||||||
|
btnExecute.Click += btnExecute_Click;
|
||||||
|
//
|
||||||
|
// label10
|
||||||
|
//
|
||||||
|
label10.AutoSize = true;
|
||||||
|
label10.Location = new Point(9, 325);
|
||||||
|
label10.Name = "label10";
|
||||||
|
label10.Size = new Size(44, 17);
|
||||||
|
label10.TabIndex = 16;
|
||||||
|
label10.Text = "耗时:";
|
||||||
|
//
|
||||||
|
// groupBox2
|
||||||
|
//
|
||||||
|
groupBox2.Controls.Add(tbheight);
|
||||||
|
groupBox2.Controls.Add(lbheight);
|
||||||
|
groupBox2.Controls.Add(tbwidth);
|
||||||
|
groupBox2.Controls.Add(label2);
|
||||||
|
groupBox2.Controls.Add(tbLineX2);
|
||||||
|
groupBox2.Controls.Add(label8);
|
||||||
|
groupBox2.Controls.Add(tbLineY2);
|
||||||
|
groupBox2.Controls.Add(label5);
|
||||||
|
groupBox2.Controls.Add(tbLineX1);
|
||||||
|
groupBox2.Controls.Add(tbLineY1);
|
||||||
|
groupBox2.Controls.Add(label6);
|
||||||
|
groupBox2.Controls.Add(label7);
|
||||||
|
groupBox2.Dock = DockStyle.Top;
|
||||||
|
groupBox2.Location = new Point(0, 36);
|
||||||
|
groupBox2.Name = "groupBox2";
|
||||||
|
groupBox2.Size = new Size(198, 172);
|
||||||
|
groupBox2.TabIndex = 13;
|
||||||
|
groupBox2.TabStop = false;
|
||||||
|
groupBox2.Text = "线参数";
|
||||||
|
//
|
||||||
|
// tbheight
|
||||||
|
//
|
||||||
|
tbheight.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
|
||||||
|
tbheight.Location = new Point(126, 140);
|
||||||
|
tbheight.Name = "tbheight";
|
||||||
|
tbheight.Size = new Size(66, 23);
|
||||||
|
tbheight.TabIndex = 13;
|
||||||
|
//
|
||||||
|
// lbheight
|
||||||
|
//
|
||||||
|
lbheight.AutoSize = true;
|
||||||
|
lbheight.Location = new Point(97, 143);
|
||||||
|
lbheight.Name = "lbheight";
|
||||||
|
lbheight.Size = new Size(23, 17);
|
||||||
|
lbheight.TabIndex = 12;
|
||||||
|
lbheight.Text = "高:";
|
||||||
|
//
|
||||||
|
// tbwidth
|
||||||
|
//
|
||||||
|
tbwidth.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
|
||||||
|
tbwidth.Location = new Point(27, 140);
|
||||||
|
tbwidth.Name = "tbwidth";
|
||||||
|
tbwidth.Size = new Size(64, 23);
|
||||||
|
tbwidth.TabIndex = 11;
|
||||||
|
//
|
||||||
|
// label2
|
||||||
|
//
|
||||||
|
label2.AutoSize = true;
|
||||||
|
label2.Location = new Point(6, 143);
|
||||||
|
label2.Name = "label2";
|
||||||
|
label2.Size = new Size(23, 17);
|
||||||
|
label2.TabIndex = 10;
|
||||||
|
label2.Text = "宽:";
|
||||||
|
//
|
||||||
|
// tbLineX2
|
||||||
|
//
|
||||||
|
tbLineX2.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
|
||||||
|
tbLineX2.Location = new Point(56, 80);
|
||||||
|
tbLineX2.Name = "tbLineX2";
|
||||||
|
tbLineX2.Size = new Size(136, 23);
|
||||||
|
tbLineX2.TabIndex = 9;
|
||||||
|
//
|
||||||
|
// label8
|
||||||
|
//
|
||||||
|
label8.AutoSize = true;
|
||||||
|
label8.Location = new Point(6, 83);
|
||||||
|
label8.Name = "label8";
|
||||||
|
label8.Size = new Size(26, 17);
|
||||||
|
label8.TabIndex = 8;
|
||||||
|
label8.Text = "X2:";
|
||||||
|
//
|
||||||
|
// tbLineY2
|
||||||
|
//
|
||||||
|
tbLineY2.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
|
||||||
|
tbLineY2.Location = new Point(56, 109);
|
||||||
|
tbLineY2.Name = "tbLineY2";
|
||||||
|
tbLineY2.Size = new Size(136, 23);
|
||||||
|
tbLineY2.TabIndex = 7;
|
||||||
|
//
|
||||||
|
// label5
|
||||||
|
//
|
||||||
|
label5.AutoSize = true;
|
||||||
|
label5.Location = new Point(6, 112);
|
||||||
|
label5.Name = "label5";
|
||||||
|
label5.Size = new Size(25, 17);
|
||||||
|
label5.TabIndex = 6;
|
||||||
|
label5.Text = "Y2:";
|
||||||
|
//
|
||||||
|
// tbLineX1
|
||||||
|
//
|
||||||
|
tbLineX1.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
|
||||||
|
tbLineX1.Location = new Point(56, 22);
|
||||||
|
tbLineX1.Name = "tbLineX1";
|
||||||
|
tbLineX1.Size = new Size(136, 23);
|
||||||
|
tbLineX1.TabIndex = 5;
|
||||||
|
tbLineX1.TextChanged += tbLineX1_TextChanged;
|
||||||
|
//
|
||||||
|
// tbLineY1
|
||||||
|
//
|
||||||
|
tbLineY1.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
|
||||||
|
tbLineY1.Location = new Point(56, 51);
|
||||||
|
tbLineY1.Name = "tbLineY1";
|
||||||
|
tbLineY1.Size = new Size(136, 23);
|
||||||
|
tbLineY1.TabIndex = 4;
|
||||||
|
//
|
||||||
|
// label6
|
||||||
|
//
|
||||||
|
label6.AutoSize = true;
|
||||||
|
label6.Location = new Point(6, 54);
|
||||||
|
label6.Name = "label6";
|
||||||
|
label6.Size = new Size(25, 17);
|
||||||
|
label6.TabIndex = 1;
|
||||||
|
label6.Text = "Y1:";
|
||||||
|
//
|
||||||
|
// label7
|
||||||
|
//
|
||||||
|
label7.AutoSize = true;
|
||||||
|
label7.Location = new Point(6, 25);
|
||||||
|
label7.Name = "label7";
|
||||||
|
label7.Size = new Size(26, 17);
|
||||||
|
label7.TabIndex = 0;
|
||||||
|
label7.Text = "X1:";
|
||||||
|
//
|
||||||
|
// ctrlTitleBar
|
||||||
|
//
|
||||||
|
ctrlTitleBar.Dock = DockStyle.Top;
|
||||||
|
ctrlTitleBar.Location = new Point(0, 0);
|
||||||
|
ctrlTitleBar.MinimumSize = new Size(0, 36);
|
||||||
|
ctrlTitleBar.Name = "ctrlTitleBar";
|
||||||
|
ctrlTitleBar.Padding = new Padding(3);
|
||||||
|
ctrlTitleBar.Size = new Size(198, 36);
|
||||||
|
ctrlTitleBar.TabIndex = 11;
|
||||||
|
ctrlTitleBar.Title = "高度测量";
|
||||||
|
//
|
||||||
|
// panel1
|
||||||
|
//
|
||||||
|
panel1.BorderStyle = BorderStyle.FixedSingle;
|
||||||
|
panel1.Controls.Add(canvas);
|
||||||
|
panel1.Controls.Add(statusStrip1);
|
||||||
|
panel1.Dock = DockStyle.Fill;
|
||||||
|
panel1.Location = new Point(0, 0);
|
||||||
|
panel1.Name = "panel1";
|
||||||
|
panel1.Size = new Size(1076, 640);
|
||||||
|
panel1.TabIndex = 1;
|
||||||
|
//
|
||||||
|
// canvas
|
||||||
|
//
|
||||||
|
canvas.AllowMultiSelect = false;
|
||||||
|
canvas.CreateMode = Canvas.Shape.ShapeTypeEnum.Polygon;
|
||||||
|
canvas.Dock = DockStyle.Fill;
|
||||||
|
canvas.Enabled = false;
|
||||||
|
canvas.FillDrawing = false;
|
||||||
|
canvas.Location = new Point(0, 0);
|
||||||
|
canvas.Margin = new Padding(2);
|
||||||
|
canvas.Name = "canvas";
|
||||||
|
canvas.OutsideShapes = (List<Canvas.Shape.FlyShape>)resources.GetObject("canvas.OutsideShapes");
|
||||||
|
canvas.Scale = 1F;
|
||||||
|
canvas.Shapes = (List<Canvas.Shape.FlyShape>)resources.GetObject("canvas.Shapes");
|
||||||
|
canvas.Size = new Size(1074, 616);
|
||||||
|
canvas.TabIndex = 2;
|
||||||
|
//
|
||||||
|
// statusStrip1
|
||||||
|
//
|
||||||
|
statusStrip1.Items.AddRange(new ToolStripItem[] { lblStatus });
|
||||||
|
statusStrip1.Location = new Point(0, 616);
|
||||||
|
statusStrip1.Name = "statusStrip1";
|
||||||
|
statusStrip1.Size = new Size(1074, 22);
|
||||||
|
statusStrip1.TabIndex = 1;
|
||||||
|
statusStrip1.Text = "statusStrip1";
|
||||||
|
//
|
||||||
|
// lblStatus
|
||||||
|
//
|
||||||
|
lblStatus.Name = "lblStatus";
|
||||||
|
lblStatus.Size = new Size(44, 17);
|
||||||
|
lblStatus.Text = " ";
|
||||||
|
//
|
||||||
|
// GuideHeightCtrl
|
||||||
|
//
|
||||||
|
AutoScaleDimensions = new SizeF(7F, 17F);
|
||||||
|
AutoScaleMode = AutoScaleMode.Font;
|
||||||
|
Controls.Add(splitContainer);
|
||||||
|
Controls.Add(lblElapsed);
|
||||||
|
Controls.Add(label4);
|
||||||
|
Name = "GuideHeightCtrl";
|
||||||
|
Size = new Size(1280, 640);
|
||||||
|
Load += GuideLineCircleCtrl_Load;
|
||||||
|
splitContainer.Panel1.ResumeLayout(false);
|
||||||
|
splitContainer.Panel2.ResumeLayout(false);
|
||||||
|
((System.ComponentModel.ISupportInitialize)splitContainer).EndInit();
|
||||||
|
splitContainer.ResumeLayout(false);
|
||||||
|
panelGuide.ResumeLayout(false);
|
||||||
|
panelGuide.PerformLayout();
|
||||||
|
groupBox2.ResumeLayout(false);
|
||||||
|
groupBox2.PerformLayout();
|
||||||
|
panel1.ResumeLayout(false);
|
||||||
|
panel1.PerformLayout();
|
||||||
|
statusStrip1.ResumeLayout(false);
|
||||||
|
statusStrip1.PerformLayout();
|
||||||
|
ResumeLayout(false);
|
||||||
|
PerformLayout();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
private Label lblElapsed;
|
||||||
|
private Label label4;
|
||||||
|
|
||||||
|
private SplitContainer splitContainer;
|
||||||
|
private Panel panelGuide;
|
||||||
|
private Panel panel1;
|
||||||
|
private Canvas.UI.FlyCanvas canvas;
|
||||||
|
private StatusStrip statusStrip1;
|
||||||
|
private ToolStripStatusLabel lblStatus;
|
||||||
|
private GroupBox groupBox2;
|
||||||
|
private TextBox tbLineX2;
|
||||||
|
private Label label8;
|
||||||
|
private TextBox tbLineY2;
|
||||||
|
private Label label5;
|
||||||
|
private TextBox tbLineX1;
|
||||||
|
private TextBox tbLineY1;
|
||||||
|
private Label label6;
|
||||||
|
private Label label7;
|
||||||
|
private CtrlTitleBar ctrlTitleBar;
|
||||||
|
private Button btnLoadImage;
|
||||||
|
private Label label9;
|
||||||
|
private Button btnExecute;
|
||||||
|
private Label label10;
|
||||||
|
private Button btnCreateLine;
|
||||||
|
private TextBox tbRectWidth1;
|
||||||
|
private Label lblResult;
|
||||||
|
private Label label1;
|
||||||
|
private Button btnSave;
|
||||||
|
private TextBox tbheight;
|
||||||
|
private Label lbheight;
|
||||||
|
private TextBox tbwidth;
|
||||||
|
private Label label2;
|
||||||
|
}
|
||||||
|
}
|
||||||
346
CanFly/UI/GuidePanel/GuideHeightCtrl.cs
Normal file
346
CanFly/UI/GuidePanel/GuideHeightCtrl.cs
Normal file
@@ -0,0 +1,346 @@
|
|||||||
|
using CanFly.Canvas.Helper;
|
||||||
|
using CanFly.Canvas.Shape;
|
||||||
|
using CanFly.Canvas.UI;
|
||||||
|
using CanFly.Helper;
|
||||||
|
using HalconDotNet;
|
||||||
|
using OpenCvSharp;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.ComponentModel;
|
||||||
|
using System.Data;
|
||||||
|
using System.Drawing;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Windows.Forms;
|
||||||
|
|
||||||
|
namespace CanFly.UI.GuidePanel
|
||||||
|
{
|
||||||
|
public partial class GuideHeightCtrl : BaseGuideControl
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private FlyShape? _line;
|
||||||
|
|
||||||
|
|
||||||
|
private float _lineX1;
|
||||||
|
private float _lineY1;
|
||||||
|
private float _lineX2;
|
||||||
|
private float _lineY2;
|
||||||
|
float width, height;
|
||||||
|
private float _lineWidth;
|
||||||
|
private PointF[] _rectPoints = new PointF[4];
|
||||||
|
//private float _LineLX=new float();
|
||||||
|
//private float _LineLY =new float();
|
||||||
|
//private float _LineRX =new float();
|
||||||
|
//private float _LineRY =new float();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
protected override string GetScriptFileName() => "HeightMeasure.hdvp";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public GuideHeightCtrl()
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
|
||||||
|
this.canvas.mouseMoved += Canvas_mouseMoved;
|
||||||
|
this.canvas.OnShapeUpdateEvent += UpdateShape;
|
||||||
|
this.canvas.selectionChanged += Canvas_selectionChanged;
|
||||||
|
|
||||||
|
this.canvas.OnShapeMoving += Canvas_OnShapeMoving;
|
||||||
|
this.canvas.newShape += Canvas_newShape;
|
||||||
|
|
||||||
|
this.ctrlTitleBar.OnCloseClicked += OnControlClose;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
protected override void UpdateShape(FlyShape shape)
|
||||||
|
{
|
||||||
|
switch (shape.ShapeType)
|
||||||
|
{
|
||||||
|
case ShapeTypeEnum.Rectangle:
|
||||||
|
this._line = shape;
|
||||||
|
|
||||||
|
var pts = this._line.Points;
|
||||||
|
|
||||||
|
_lineX1 = pts[0].X;
|
||||||
|
_lineY1 = pts[0].Y;
|
||||||
|
_lineX2 = pts[1].X;
|
||||||
|
_lineY2 = pts[1].Y;
|
||||||
|
_lineWidth = shape.LineVirtualRectWidth;
|
||||||
|
_rectPoints = shape.LineVirtualRectPoints;
|
||||||
|
//_LineLX = (shape.LineVirtualRectPoints[0].X + shape.LineVirtualRectPoints[3].X) / 2;
|
||||||
|
//_LineLY = (shape.LineVirtualRectPoints[0].Y + shape.LineVirtualRectPoints[3].Y) / 2;
|
||||||
|
//_LineRX = (shape.LineVirtualRectPoints[1].X + shape.LineVirtualRectPoints[2].X) / 2;
|
||||||
|
//_LineRY = (shape.LineVirtualRectPoints[1].Y + shape.LineVirtualRectPoints[2].Y) / 2;
|
||||||
|
|
||||||
|
width = Math.Abs(_lineX2 - _lineX1);
|
||||||
|
height = Math.Abs(_lineY2 - _lineY1);
|
||||||
|
|
||||||
|
|
||||||
|
tbLineX1.Text = _lineX1.ToString("F3");
|
||||||
|
tbLineY1.Text = _lineY1.ToString("F3");
|
||||||
|
tbLineX2.Text = _lineX2.ToString("F3");
|
||||||
|
tbLineY2.Text = _lineY2.ToString("F3");
|
||||||
|
tbwidth.Text = width.ToString();
|
||||||
|
tbheight.Text = height.ToString();
|
||||||
|
// NumRectWidth1.Value = (decimal)_lineWidth;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private void GuideLineCircleCtrl_Load(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private void Canvas_mouseMoved(PointF pos)
|
||||||
|
{
|
||||||
|
if (InvokeRequired)
|
||||||
|
{
|
||||||
|
Invoke(Canvas_mouseMoved, pos);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
lblStatus.Text = $"X:{pos.X}, Y:{pos.Y}";
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private void Canvas_selectionChanged(List<FlyShape> shapes)
|
||||||
|
{
|
||||||
|
//if (shapes.Count != 1)
|
||||||
|
//{
|
||||||
|
// // panelGuide.Controls.Clear();
|
||||||
|
// return;
|
||||||
|
//}
|
||||||
|
//SwitchGuideForm(shapes[0].ShapeType);
|
||||||
|
// Canvas_OnShapeUpdateEvent(shapes[0]);
|
||||||
|
|
||||||
|
if (shapes.Count != 1)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
UpdateShape(shapes[0]);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private void Canvas_OnShapeMoving(List<FlyShape> shapes)
|
||||||
|
{
|
||||||
|
if (shapes.Count != 1)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
UpdateShape(shapes[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private void btnCreateLine_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
if (this.canvas.pixmap == null)
|
||||||
|
{
|
||||||
|
MessageBox.Show("请先打开图片");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
tbLineX1.Text = string.Empty;
|
||||||
|
tbLineY1.Text = string.Empty;
|
||||||
|
tbLineX2.Text = string.Empty;
|
||||||
|
tbLineY2.Text = string.Empty; ;
|
||||||
|
tbwidth.Text = string.Empty; ;
|
||||||
|
tbheight.Text = string.Empty; ;
|
||||||
|
this.canvas.Shapes.RemoveAll(shp => shp.ShapeType == ShapeTypeEnum.Rectangle);
|
||||||
|
this.canvas.Invalidate();
|
||||||
|
this.canvas.StartDraw(ShapeTypeEnum.Rectangle);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private void btnLoadImage_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
OpenImageFile(bitmap =>
|
||||||
|
{
|
||||||
|
this.canvas.LoadPixmap(bitmap);
|
||||||
|
this.canvas.Enabled = true;
|
||||||
|
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void Canvas_newShape()
|
||||||
|
{
|
||||||
|
this.canvas.StopDraw();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void btnExecute_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
if (this.canvas.pixmap == null)
|
||||||
|
{
|
||||||
|
MessageBox.Show("请先打开图片");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (this.tbLineX1.Text.Trim().Length == 0)
|
||||||
|
{
|
||||||
|
MessageBox.Show("请先创建矩形");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.canvas.OutsideShapes.Clear();
|
||||||
|
this.canvas.Invalidate();
|
||||||
|
|
||||||
|
|
||||||
|
flag = new List<double>();
|
||||||
|
|
||||||
|
Line1Para = new List<double>();
|
||||||
|
Line2Para = new List<double>();
|
||||||
|
iHeight = new List<double>();
|
||||||
|
Dictionary<string, HObject> inputImg = new Dictionary<string, HObject>();
|
||||||
|
|
||||||
|
if (hImage == null)
|
||||||
|
{
|
||||||
|
HOperatorSet.ReadImage(out hImage, CurrentImageFile);
|
||||||
|
}
|
||||||
|
inputImg["INPUT_Image"] = hImage;
|
||||||
|
|
||||||
|
|
||||||
|
Dictionary<string, HTuple> inputPara = new Dictionary<string, HTuple>();
|
||||||
|
|
||||||
|
|
||||||
|
inputPara["row"] = _lineY1;
|
||||||
|
inputPara["column"] = _lineX1;
|
||||||
|
inputPara["Width"] = width;
|
||||||
|
inputPara["Height"] = height;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
List<string> outputKeys = new List<string>()
|
||||||
|
{
|
||||||
|
"OUTPUT_PreTreatedImage",
|
||||||
|
"OUTPUT_Flag",
|
||||||
|
|
||||||
|
"Line1Para",
|
||||||
|
"Line2Para",
|
||||||
|
"iHeight"
|
||||||
|
};
|
||||||
|
|
||||||
|
ExecuteHScript(
|
||||||
|
inputImg,
|
||||||
|
inputPara,
|
||||||
|
outputKeys);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
List<double> flag = new List<double>();
|
||||||
|
List<double> Line1Para = new List<double>();
|
||||||
|
List<double> Line2Para = new List<double>();
|
||||||
|
|
||||||
|
List<double> iHeight = new List<double>();
|
||||||
|
|
||||||
|
|
||||||
|
protected override void OnExecuteHScriptResult(
|
||||||
|
bool success,
|
||||||
|
Dictionary<string, HTuple> resultDic,
|
||||||
|
int timeElasped)
|
||||||
|
{
|
||||||
|
if (!success)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
"OUTPUT_Flag",
|
||||||
|
"RXCenter",
|
||||||
|
"RYCenter",
|
||||||
|
"RRadius"
|
||||||
|
*/
|
||||||
|
|
||||||
|
flag = resultDic["OUTPUT_Flag"].HTupleToDouble();
|
||||||
|
|
||||||
|
Line1Para = resultDic["Line1Para"].HTupleToDouble();
|
||||||
|
Line2Para = resultDic["Line2Para"].HTupleToDouble();
|
||||||
|
// EndRow = resultDic["EndRow"].HTupleToDouble();
|
||||||
|
//EndCloumn = resultDic["EndColumn"].HTupleToDouble();
|
||||||
|
iHeight = resultDic["iHeight"].HTupleToDouble();
|
||||||
|
|
||||||
|
if (flag.Count > 0)
|
||||||
|
{
|
||||||
|
lblResult.Text = flag[0].ToString();
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
lblResult.Text = "无";
|
||||||
|
}
|
||||||
|
if (flag.Count > 0 && Line1Para.Count == 4 && Line2Para.Count == 4 && iHeight.Count > 0)
|
||||||
|
{
|
||||||
|
float width = 0;
|
||||||
|
this.canvas.DrawLine(new PointF((float)Line1Para[1], (float)Line1Para[0]), new PointF((float)Line1Para[3], (float)Line1Para[2]), 0);
|
||||||
|
this.canvas.DrawLine(new PointF((float)Line2Para[1], (float)Line2Para[0]), new PointF((float)Line2Para[3], (float)Line2Para[2]), 0);
|
||||||
|
this.canvas.Invalidate();
|
||||||
|
lblElapsed.Text = $"{timeElasped} ms";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private void btnSave_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
if (lblResult.Text.Equals("无"))
|
||||||
|
{
|
||||||
|
MessageBox.Show("请先进行绘制");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (lblResult.Text != "0")
|
||||||
|
{
|
||||||
|
MessageBox.Show("测量计算错误,无法保存");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
string input = $"row:{string.Join(";", _lineY1)};column:{string.Join(";", _lineX1)};" +
|
||||||
|
$"Width:{string.Join(";", width)};Height:{string.Join(";", height)}";
|
||||||
|
|
||||||
|
string output = $"iHeight:{string.Join(";", iHeight[0])}";
|
||||||
|
DataToTriggerEvent(input, output);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void tbLineX1_TextChanged(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
145
CanFly/UI/GuidePanel/GuideHeightCtrl.resx
Normal file
145
CanFly/UI/GuidePanel/GuideHeightCtrl.resx
Normal file
@@ -0,0 +1,145 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<root>
|
||||||
|
<!--
|
||||||
|
Microsoft ResX Schema
|
||||||
|
|
||||||
|
Version 2.0
|
||||||
|
|
||||||
|
The primary goals of this format is to allow a simple XML format
|
||||||
|
that is mostly human readable. The generation and parsing of the
|
||||||
|
various data types are done through the TypeConverter classes
|
||||||
|
associated with the data types.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
... ado.net/XML headers & schema ...
|
||||||
|
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||||
|
<resheader name="version">2.0</resheader>
|
||||||
|
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||||
|
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||||
|
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||||
|
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||||
|
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||||
|
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||||
|
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||||
|
<comment>This is a comment</comment>
|
||||||
|
</data>
|
||||||
|
|
||||||
|
There are any number of "resheader" rows that contain simple
|
||||||
|
name/value pairs.
|
||||||
|
|
||||||
|
Each data row contains a name, and value. The row also contains a
|
||||||
|
type or mimetype. Type corresponds to a .NET class that support
|
||||||
|
text/value conversion through the TypeConverter architecture.
|
||||||
|
Classes that don't support this are serialized and stored with the
|
||||||
|
mimetype set.
|
||||||
|
|
||||||
|
The mimetype is used for serialized objects, and tells the
|
||||||
|
ResXResourceReader how to depersist the object. This is currently not
|
||||||
|
extensible. For a given mimetype the value must be set accordingly:
|
||||||
|
|
||||||
|
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||||
|
that the ResXResourceWriter will generate, however the reader can
|
||||||
|
read any of the formats listed below.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.binary.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.soap.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||||
|
value : The object must be serialized into a byte array
|
||||||
|
: using a System.ComponentModel.TypeConverter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
-->
|
||||||
|
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||||
|
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||||
|
<xsd:element name="root" msdata:IsDataSet="true">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:choice maxOccurs="unbounded">
|
||||||
|
<xsd:element name="metadata">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="assembly">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:attribute name="alias" type="xsd:string" />
|
||||||
|
<xsd:attribute name="name" type="xsd:string" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="data">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="resheader">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:choice>
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:schema>
|
||||||
|
<resheader name="resmimetype">
|
||||||
|
<value>text/microsoft-resx</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="version">
|
||||||
|
<value>2.0</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="reader">
|
||||||
|
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="writer">
|
||||||
|
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
<data name="canvas.OutsideShapes" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||||
|
<value>
|
||||||
|
AAEAAAD/////AQAAAAAAAAAMAgAAAERDYW5GbHkuQ2FudmFzLCBWZXJzaW9uPTEuMC4wLjAsIEN1bHR1
|
||||||
|
cmU9bmV1dHJhbCwgUHVibGljS2V5VG9rZW49bnVsbAQBAAAAdlN5c3RlbS5Db2xsZWN0aW9ucy5HZW5l
|
||||||
|
cmljLkxpc3RgMVtbQ2FuRmx5LkNhbnZhcy5TaGFwZS5GbHlTaGFwZSwgQ2FuRmx5LkNhbnZhcywgQ3Vs
|
||||||
|
dHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1udWxsXV0DAAAABl9pdGVtcwVfc2l6ZQhfdmVyc2lv
|
||||||
|
bgQAAB5DYW5GbHkuQ2FudmFzLlNoYXBlLkZseVNoYXBlW10CAAAACAgJAwAAAAAAAAAAAAAADAQAAAAz
|
||||||
|
Q2FuRmx5LkNhbnZhcywgQ3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1udWxsBwMAAAAAAQAA
|
||||||
|
AAAAAAAEHENhbkZseS5DYW52YXMuU2hhcGUuRmx5U2hhcGUEAAAACw==
|
||||||
|
</value>
|
||||||
|
</data>
|
||||||
|
<data name="canvas.Shapes" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||||
|
<value>
|
||||||
|
AAEAAAD/////AQAAAAAAAAAMAgAAAERDYW5GbHkuQ2FudmFzLCBWZXJzaW9uPTEuMC4wLjAsIEN1bHR1
|
||||||
|
cmU9bmV1dHJhbCwgUHVibGljS2V5VG9rZW49bnVsbAQBAAAAdlN5c3RlbS5Db2xsZWN0aW9ucy5HZW5l
|
||||||
|
cmljLkxpc3RgMVtbQ2FuRmx5LkNhbnZhcy5TaGFwZS5GbHlTaGFwZSwgQ2FuRmx5LkNhbnZhcywgQ3Vs
|
||||||
|
dHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1udWxsXV0DAAAABl9pdGVtcwVfc2l6ZQhfdmVyc2lv
|
||||||
|
bgQAAB5DYW5GbHkuQ2FudmFzLlNoYXBlLkZseVNoYXBlW10CAAAACAgJAwAAAAAAAAAAAAAADAQAAAAz
|
||||||
|
Q2FuRmx5LkNhbnZhcywgQ3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1udWxsBwMAAAAAAQAA
|
||||||
|
AAAAAAAEHENhbkZseS5DYW52YXMuU2hhcGUuRmx5U2hhcGUEAAAACw==
|
||||||
|
</value>
|
||||||
|
</data>
|
||||||
|
<metadata name="statusStrip1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||||
|
<value>17, 17</value>
|
||||||
|
</metadata>
|
||||||
|
</root>
|
||||||
550
CanFly/UI/GuidePanel/GuideLineCircleCtrl.Designer.cs
generated
Normal file
550
CanFly/UI/GuidePanel/GuideLineCircleCtrl.Designer.cs
generated
Normal file
@@ -0,0 +1,550 @@
|
|||||||
|
namespace CanFly.UI.GuidePanel
|
||||||
|
{
|
||||||
|
partial class GuideLineCircleCtrl
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 必需的设计器变量。
|
||||||
|
/// </summary>
|
||||||
|
private System.ComponentModel.IContainer components = null;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 清理所有正在使用的资源。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="disposing">如果应释放托管资源,为 true;否则为 false。</param>
|
||||||
|
protected override void Dispose(bool disposing)
|
||||||
|
{
|
||||||
|
if (disposing && (components != null))
|
||||||
|
{
|
||||||
|
components.Dispose();
|
||||||
|
}
|
||||||
|
base.Dispose(disposing);
|
||||||
|
}
|
||||||
|
|
||||||
|
#region 组件设计器生成的代码
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 设计器支持所需的方法 - 不要修改
|
||||||
|
/// 使用代码编辑器修改此方法的内容。
|
||||||
|
/// </summary>
|
||||||
|
private void InitializeComponent()
|
||||||
|
{
|
||||||
|
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(GuideLineCircleCtrl));
|
||||||
|
lblElapsed = new Label();
|
||||||
|
label4 = new Label();
|
||||||
|
splitContainer = new SplitContainer();
|
||||||
|
panelGuide = new Panel();
|
||||||
|
lblDistance = new Label();
|
||||||
|
label17 = new Label();
|
||||||
|
lblResult = new Label();
|
||||||
|
label15 = new Label();
|
||||||
|
btnCreateLine = new Button();
|
||||||
|
btnCreateCircle = new Button();
|
||||||
|
btnLoadImage = new Button();
|
||||||
|
label9 = new Label();
|
||||||
|
btnExecute = new Button();
|
||||||
|
label10 = new Label();
|
||||||
|
groupBox2 = new GroupBox();
|
||||||
|
NumRectWidth1 = new NumericUpDown();
|
||||||
|
label11 = new Label();
|
||||||
|
tbLineX2 = new TextBox();
|
||||||
|
label8 = new Label();
|
||||||
|
tbLineY2 = new TextBox();
|
||||||
|
label5 = new Label();
|
||||||
|
tbLineX1 = new TextBox();
|
||||||
|
tbLineY1 = new TextBox();
|
||||||
|
label6 = new Label();
|
||||||
|
label7 = new Label();
|
||||||
|
groupBox1 = new GroupBox();
|
||||||
|
tbCircleX = new TextBox();
|
||||||
|
tbCircleY = new TextBox();
|
||||||
|
tbCircleR = new TextBox();
|
||||||
|
label3 = new Label();
|
||||||
|
label2 = new Label();
|
||||||
|
label1 = new Label();
|
||||||
|
ctrlTitleBar = new CtrlTitleBar();
|
||||||
|
panel1 = new Panel();
|
||||||
|
canvas = new Canvas.UI.FlyCanvas();
|
||||||
|
statusStrip1 = new StatusStrip();
|
||||||
|
lblStatus = new ToolStripStatusLabel();
|
||||||
|
btnSave = new Button();
|
||||||
|
((System.ComponentModel.ISupportInitialize)splitContainer).BeginInit();
|
||||||
|
splitContainer.Panel1.SuspendLayout();
|
||||||
|
splitContainer.Panel2.SuspendLayout();
|
||||||
|
splitContainer.SuspendLayout();
|
||||||
|
panelGuide.SuspendLayout();
|
||||||
|
groupBox2.SuspendLayout();
|
||||||
|
((System.ComponentModel.ISupportInitialize)NumRectWidth1).BeginInit();
|
||||||
|
groupBox1.SuspendLayout();
|
||||||
|
panel1.SuspendLayout();
|
||||||
|
statusStrip1.SuspendLayout();
|
||||||
|
SuspendLayout();
|
||||||
|
//
|
||||||
|
// lblElapsed
|
||||||
|
//
|
||||||
|
lblElapsed.AutoSize = true;
|
||||||
|
lblElapsed.Location = new Point(50, 328);
|
||||||
|
lblElapsed.Name = "lblElapsed";
|
||||||
|
lblElapsed.Size = new Size(32, 17);
|
||||||
|
lblElapsed.TabIndex = 9;
|
||||||
|
lblElapsed.Text = "0ms";
|
||||||
|
//
|
||||||
|
// label4
|
||||||
|
//
|
||||||
|
label4.AutoSize = true;
|
||||||
|
label4.Location = new Point(0, 328);
|
||||||
|
label4.Name = "label4";
|
||||||
|
label4.Size = new Size(44, 17);
|
||||||
|
label4.TabIndex = 8;
|
||||||
|
label4.Text = "耗时:";
|
||||||
|
//
|
||||||
|
// splitContainer
|
||||||
|
//
|
||||||
|
splitContainer.Dock = DockStyle.Fill;
|
||||||
|
splitContainer.Location = new Point(0, 0);
|
||||||
|
splitContainer.Name = "splitContainer";
|
||||||
|
//
|
||||||
|
// splitContainer.Panel1
|
||||||
|
//
|
||||||
|
splitContainer.Panel1.Controls.Add(panelGuide);
|
||||||
|
splitContainer.Panel1MinSize = 150;
|
||||||
|
//
|
||||||
|
// splitContainer.Panel2
|
||||||
|
//
|
||||||
|
splitContainer.Panel2.Controls.Add(panel1);
|
||||||
|
splitContainer.Size = new Size(1280, 640);
|
||||||
|
splitContainer.SplitterDistance = 200;
|
||||||
|
splitContainer.TabIndex = 11;
|
||||||
|
//
|
||||||
|
// panelGuide
|
||||||
|
//
|
||||||
|
panelGuide.BorderStyle = BorderStyle.FixedSingle;
|
||||||
|
panelGuide.Controls.Add(btnSave);
|
||||||
|
panelGuide.Controls.Add(lblDistance);
|
||||||
|
panelGuide.Controls.Add(label17);
|
||||||
|
panelGuide.Controls.Add(lblResult);
|
||||||
|
panelGuide.Controls.Add(label15);
|
||||||
|
panelGuide.Controls.Add(btnCreateLine);
|
||||||
|
panelGuide.Controls.Add(btnCreateCircle);
|
||||||
|
panelGuide.Controls.Add(btnLoadImage);
|
||||||
|
panelGuide.Controls.Add(label9);
|
||||||
|
panelGuide.Controls.Add(btnExecute);
|
||||||
|
panelGuide.Controls.Add(label10);
|
||||||
|
panelGuide.Controls.Add(groupBox2);
|
||||||
|
panelGuide.Controls.Add(groupBox1);
|
||||||
|
panelGuide.Controls.Add(ctrlTitleBar);
|
||||||
|
panelGuide.Dock = DockStyle.Fill;
|
||||||
|
panelGuide.Location = new Point(0, 0);
|
||||||
|
panelGuide.Name = "panelGuide";
|
||||||
|
panelGuide.Size = new Size(200, 640);
|
||||||
|
panelGuide.TabIndex = 0;
|
||||||
|
//
|
||||||
|
// lblDistance
|
||||||
|
//
|
||||||
|
lblDistance.AutoSize = true;
|
||||||
|
lblDistance.Location = new Point(54, 505);
|
||||||
|
lblDistance.Name = "lblDistance";
|
||||||
|
lblDistance.Size = new Size(15, 17);
|
||||||
|
lblDistance.TabIndex = 29;
|
||||||
|
lblDistance.Text = "0";
|
||||||
|
//
|
||||||
|
// label17
|
||||||
|
//
|
||||||
|
label17.AutoSize = true;
|
||||||
|
label17.Location = new Point(6, 505);
|
||||||
|
label17.Name = "label17";
|
||||||
|
label17.Size = new Size(44, 17);
|
||||||
|
label17.TabIndex = 28;
|
||||||
|
label17.Text = "距离:";
|
||||||
|
//
|
||||||
|
// lblResult
|
||||||
|
//
|
||||||
|
lblResult.AutoSize = true;
|
||||||
|
lblResult.Location = new Point(54, 479);
|
||||||
|
lblResult.Name = "lblResult";
|
||||||
|
lblResult.Size = new Size(20, 17);
|
||||||
|
lblResult.TabIndex = 27;
|
||||||
|
lblResult.Text = "无";
|
||||||
|
//
|
||||||
|
// label15
|
||||||
|
//
|
||||||
|
label15.AutoSize = true;
|
||||||
|
label15.Location = new Point(6, 479);
|
||||||
|
label15.Name = "label15";
|
||||||
|
label15.Size = new Size(44, 17);
|
||||||
|
label15.TabIndex = 26;
|
||||||
|
label15.Text = "结果:";
|
||||||
|
//
|
||||||
|
// btnCreateLine
|
||||||
|
//
|
||||||
|
btnCreateLine.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
|
||||||
|
btnCreateLine.Location = new Point(6, 406);
|
||||||
|
btnCreateLine.Name = "btnCreateLine";
|
||||||
|
btnCreateLine.Size = new Size(186, 32);
|
||||||
|
btnCreateLine.TabIndex = 20;
|
||||||
|
btnCreateLine.Text = "创建直线";
|
||||||
|
btnCreateLine.UseVisualStyleBackColor = true;
|
||||||
|
btnCreateLine.Click += btnCreateLine_Click;
|
||||||
|
//
|
||||||
|
// btnCreateCircle
|
||||||
|
//
|
||||||
|
btnCreateCircle.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
|
||||||
|
btnCreateCircle.Location = new Point(6, 368);
|
||||||
|
btnCreateCircle.Name = "btnCreateCircle";
|
||||||
|
btnCreateCircle.Size = new Size(186, 32);
|
||||||
|
btnCreateCircle.TabIndex = 19;
|
||||||
|
btnCreateCircle.Text = "创建圆形";
|
||||||
|
btnCreateCircle.UseVisualStyleBackColor = true;
|
||||||
|
btnCreateCircle.Click += btnCreateCircle_Click;
|
||||||
|
//
|
||||||
|
// btnLoadImage
|
||||||
|
//
|
||||||
|
btnLoadImage.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
|
||||||
|
btnLoadImage.Location = new Point(6, 330);
|
||||||
|
btnLoadImage.Name = "btnLoadImage";
|
||||||
|
btnLoadImage.Size = new Size(186, 32);
|
||||||
|
btnLoadImage.TabIndex = 18;
|
||||||
|
btnLoadImage.Text = "打开图片";
|
||||||
|
btnLoadImage.UseVisualStyleBackColor = true;
|
||||||
|
btnLoadImage.Click += btnLoadImage_Click;
|
||||||
|
//
|
||||||
|
// label9
|
||||||
|
//
|
||||||
|
label9.AutoSize = true;
|
||||||
|
label9.Location = new Point(56, 525);
|
||||||
|
label9.Name = "label9";
|
||||||
|
label9.Size = new Size(32, 17);
|
||||||
|
label9.TabIndex = 17;
|
||||||
|
label9.Text = "0ms";
|
||||||
|
//
|
||||||
|
// btnExecute
|
||||||
|
//
|
||||||
|
btnExecute.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
|
||||||
|
btnExecute.Location = new Point(6, 444);
|
||||||
|
btnExecute.Name = "btnExecute";
|
||||||
|
btnExecute.Size = new Size(186, 32);
|
||||||
|
btnExecute.TabIndex = 15;
|
||||||
|
btnExecute.Text = "执行";
|
||||||
|
btnExecute.UseVisualStyleBackColor = true;
|
||||||
|
btnExecute.Click += btnExecute_Click;
|
||||||
|
//
|
||||||
|
// label10
|
||||||
|
//
|
||||||
|
label10.AutoSize = true;
|
||||||
|
label10.Location = new Point(6, 525);
|
||||||
|
label10.Name = "label10";
|
||||||
|
label10.Size = new Size(44, 17);
|
||||||
|
label10.TabIndex = 16;
|
||||||
|
label10.Text = "耗时:";
|
||||||
|
//
|
||||||
|
// groupBox2
|
||||||
|
//
|
||||||
|
groupBox2.Controls.Add(NumRectWidth1);
|
||||||
|
groupBox2.Controls.Add(label11);
|
||||||
|
groupBox2.Controls.Add(tbLineX2);
|
||||||
|
groupBox2.Controls.Add(label8);
|
||||||
|
groupBox2.Controls.Add(tbLineY2);
|
||||||
|
groupBox2.Controls.Add(label5);
|
||||||
|
groupBox2.Controls.Add(tbLineX1);
|
||||||
|
groupBox2.Controls.Add(tbLineY1);
|
||||||
|
groupBox2.Controls.Add(label6);
|
||||||
|
groupBox2.Controls.Add(label7);
|
||||||
|
groupBox2.Dock = DockStyle.Top;
|
||||||
|
groupBox2.Location = new Point(0, 152);
|
||||||
|
groupBox2.Name = "groupBox2";
|
||||||
|
groupBox2.Size = new Size(198, 172);
|
||||||
|
groupBox2.TabIndex = 13;
|
||||||
|
groupBox2.TabStop = false;
|
||||||
|
groupBox2.Text = "线参数";
|
||||||
|
//
|
||||||
|
// NumRectWidth1
|
||||||
|
//
|
||||||
|
NumRectWidth1.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
|
||||||
|
NumRectWidth1.Location = new Point(56, 138);
|
||||||
|
NumRectWidth1.Maximum = new decimal(new int[] { 9000, 0, 0, 0 });
|
||||||
|
NumRectWidth1.Minimum = new decimal(new int[] { 1, 0, 0, 0 });
|
||||||
|
NumRectWidth1.Name = "NumRectWidth1";
|
||||||
|
NumRectWidth1.Size = new Size(136, 23);
|
||||||
|
NumRectWidth1.TabIndex = 13;
|
||||||
|
NumRectWidth1.Value = new decimal(new int[] { 1, 0, 0, 0 });
|
||||||
|
//
|
||||||
|
// label11
|
||||||
|
//
|
||||||
|
label11.AutoSize = true;
|
||||||
|
label11.Location = new Point(6, 140);
|
||||||
|
label11.Name = "label11";
|
||||||
|
label11.Size = new Size(35, 17);
|
||||||
|
label11.TabIndex = 12;
|
||||||
|
label11.Text = "宽度:";
|
||||||
|
//
|
||||||
|
// tbLineX2
|
||||||
|
//
|
||||||
|
tbLineX2.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
|
||||||
|
tbLineX2.Location = new Point(56, 80);
|
||||||
|
tbLineX2.Name = "tbLineX2";
|
||||||
|
tbLineX2.Size = new Size(136, 23);
|
||||||
|
tbLineX2.TabIndex = 9;
|
||||||
|
//
|
||||||
|
// label8
|
||||||
|
//
|
||||||
|
label8.AutoSize = true;
|
||||||
|
label8.Location = new Point(6, 83);
|
||||||
|
label8.Name = "label8";
|
||||||
|
label8.Size = new Size(26, 17);
|
||||||
|
label8.TabIndex = 8;
|
||||||
|
label8.Text = "X2:";
|
||||||
|
//
|
||||||
|
// tbLineY2
|
||||||
|
//
|
||||||
|
tbLineY2.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
|
||||||
|
tbLineY2.Location = new Point(56, 109);
|
||||||
|
tbLineY2.Name = "tbLineY2";
|
||||||
|
tbLineY2.Size = new Size(136, 23);
|
||||||
|
tbLineY2.TabIndex = 7;
|
||||||
|
//
|
||||||
|
// label5
|
||||||
|
//
|
||||||
|
label5.AutoSize = true;
|
||||||
|
label5.Location = new Point(6, 112);
|
||||||
|
label5.Name = "label5";
|
||||||
|
label5.Size = new Size(25, 17);
|
||||||
|
label5.TabIndex = 6;
|
||||||
|
label5.Text = "Y2:";
|
||||||
|
//
|
||||||
|
// tbLineX1
|
||||||
|
//
|
||||||
|
tbLineX1.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
|
||||||
|
tbLineX1.Location = new Point(56, 22);
|
||||||
|
tbLineX1.Name = "tbLineX1";
|
||||||
|
tbLineX1.Size = new Size(136, 23);
|
||||||
|
tbLineX1.TabIndex = 5;
|
||||||
|
//
|
||||||
|
// tbLineY1
|
||||||
|
//
|
||||||
|
tbLineY1.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
|
||||||
|
tbLineY1.Location = new Point(56, 51);
|
||||||
|
tbLineY1.Name = "tbLineY1";
|
||||||
|
tbLineY1.Size = new Size(136, 23);
|
||||||
|
tbLineY1.TabIndex = 4;
|
||||||
|
//
|
||||||
|
// label6
|
||||||
|
//
|
||||||
|
label6.AutoSize = true;
|
||||||
|
label6.Location = new Point(6, 54);
|
||||||
|
label6.Name = "label6";
|
||||||
|
label6.Size = new Size(25, 17);
|
||||||
|
label6.TabIndex = 1;
|
||||||
|
label6.Text = "Y1:";
|
||||||
|
//
|
||||||
|
// label7
|
||||||
|
//
|
||||||
|
label7.AutoSize = true;
|
||||||
|
label7.Location = new Point(6, 25);
|
||||||
|
label7.Name = "label7";
|
||||||
|
label7.Size = new Size(26, 17);
|
||||||
|
label7.TabIndex = 0;
|
||||||
|
label7.Text = "X1:";
|
||||||
|
//
|
||||||
|
// groupBox1
|
||||||
|
//
|
||||||
|
groupBox1.Controls.Add(tbCircleX);
|
||||||
|
groupBox1.Controls.Add(tbCircleY);
|
||||||
|
groupBox1.Controls.Add(tbCircleR);
|
||||||
|
groupBox1.Controls.Add(label3);
|
||||||
|
groupBox1.Controls.Add(label2);
|
||||||
|
groupBox1.Controls.Add(label1);
|
||||||
|
groupBox1.Dock = DockStyle.Top;
|
||||||
|
groupBox1.Location = new Point(0, 36);
|
||||||
|
groupBox1.Name = "groupBox1";
|
||||||
|
groupBox1.Size = new Size(198, 116);
|
||||||
|
groupBox1.TabIndex = 12;
|
||||||
|
groupBox1.TabStop = false;
|
||||||
|
groupBox1.Text = "圆参数";
|
||||||
|
//
|
||||||
|
// tbCircleX
|
||||||
|
//
|
||||||
|
tbCircleX.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
|
||||||
|
tbCircleX.Location = new Point(56, 22);
|
||||||
|
tbCircleX.Name = "tbCircleX";
|
||||||
|
tbCircleX.Size = new Size(136, 23);
|
||||||
|
tbCircleX.TabIndex = 5;
|
||||||
|
//
|
||||||
|
// tbCircleY
|
||||||
|
//
|
||||||
|
tbCircleY.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
|
||||||
|
tbCircleY.Location = new Point(56, 51);
|
||||||
|
tbCircleY.Name = "tbCircleY";
|
||||||
|
tbCircleY.Size = new Size(136, 23);
|
||||||
|
tbCircleY.TabIndex = 4;
|
||||||
|
//
|
||||||
|
// tbCircleR
|
||||||
|
//
|
||||||
|
tbCircleR.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
|
||||||
|
tbCircleR.Location = new Point(56, 80);
|
||||||
|
tbCircleR.Name = "tbCircleR";
|
||||||
|
tbCircleR.Size = new Size(136, 23);
|
||||||
|
tbCircleR.TabIndex = 3;
|
||||||
|
//
|
||||||
|
// label3
|
||||||
|
//
|
||||||
|
label3.AutoSize = true;
|
||||||
|
label3.Location = new Point(3, 83);
|
||||||
|
label3.Name = "label3";
|
||||||
|
label3.Size = new Size(44, 17);
|
||||||
|
label3.TabIndex = 2;
|
||||||
|
label3.Text = "半径:";
|
||||||
|
//
|
||||||
|
// label2
|
||||||
|
//
|
||||||
|
label2.AutoSize = true;
|
||||||
|
label2.Location = new Point(6, 54);
|
||||||
|
label2.Name = "label2";
|
||||||
|
label2.Size = new Size(18, 17);
|
||||||
|
label2.TabIndex = 1;
|
||||||
|
label2.Text = "Y:";
|
||||||
|
//
|
||||||
|
// label1
|
||||||
|
//
|
||||||
|
label1.AutoSize = true;
|
||||||
|
label1.Location = new Point(6, 25);
|
||||||
|
label1.Name = "label1";
|
||||||
|
label1.Size = new Size(19, 17);
|
||||||
|
label1.TabIndex = 0;
|
||||||
|
label1.Text = "X:";
|
||||||
|
//
|
||||||
|
// ctrlTitleBar
|
||||||
|
//
|
||||||
|
ctrlTitleBar.Dock = DockStyle.Top;
|
||||||
|
ctrlTitleBar.Location = new Point(0, 0);
|
||||||
|
ctrlTitleBar.MinimumSize = new Size(0, 36);
|
||||||
|
ctrlTitleBar.Name = "ctrlTitleBar";
|
||||||
|
ctrlTitleBar.Padding = new Padding(3);
|
||||||
|
ctrlTitleBar.Size = new Size(198, 36);
|
||||||
|
ctrlTitleBar.TabIndex = 11;
|
||||||
|
ctrlTitleBar.Title = "线圆测量";
|
||||||
|
//
|
||||||
|
// panel1
|
||||||
|
//
|
||||||
|
panel1.BorderStyle = BorderStyle.FixedSingle;
|
||||||
|
panel1.Controls.Add(canvas);
|
||||||
|
panel1.Controls.Add(statusStrip1);
|
||||||
|
panel1.Dock = DockStyle.Fill;
|
||||||
|
panel1.Location = new Point(0, 0);
|
||||||
|
panel1.Name = "panel1";
|
||||||
|
panel1.Size = new Size(1076, 640);
|
||||||
|
panel1.TabIndex = 1;
|
||||||
|
//
|
||||||
|
// canvas
|
||||||
|
//
|
||||||
|
canvas.AllowMultiSelect = false;
|
||||||
|
canvas.CreateMode = Canvas.Shape.ShapeTypeEnum.Polygon;
|
||||||
|
canvas.Dock = DockStyle.Fill;
|
||||||
|
canvas.Enabled = false;
|
||||||
|
canvas.FillDrawing = false;
|
||||||
|
canvas.Location = new Point(0, 0);
|
||||||
|
canvas.Margin = new Padding(2);
|
||||||
|
canvas.Name = "canvas";
|
||||||
|
canvas.OutsideShapes = (List<Canvas.Shape.FlyShape>)resources.GetObject("canvas.OutsideShapes");
|
||||||
|
canvas.Scale = 1F;
|
||||||
|
canvas.Shapes = (List<Canvas.Shape.FlyShape>)resources.GetObject("canvas.Shapes");
|
||||||
|
canvas.Size = new Size(1074, 616);
|
||||||
|
canvas.TabIndex = 2;
|
||||||
|
//
|
||||||
|
// statusStrip1
|
||||||
|
//
|
||||||
|
statusStrip1.Items.AddRange(new ToolStripItem[] { lblStatus });
|
||||||
|
statusStrip1.Location = new Point(0, 616);
|
||||||
|
statusStrip1.Name = "statusStrip1";
|
||||||
|
statusStrip1.Size = new Size(1074, 22);
|
||||||
|
statusStrip1.TabIndex = 1;
|
||||||
|
statusStrip1.Text = "statusStrip1";
|
||||||
|
//
|
||||||
|
// lblStatus
|
||||||
|
//
|
||||||
|
lblStatus.Name = "lblStatus";
|
||||||
|
lblStatus.Size = new Size(44, 17);
|
||||||
|
lblStatus.Text = " ";
|
||||||
|
//
|
||||||
|
// btnSave
|
||||||
|
//
|
||||||
|
btnSave.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
|
||||||
|
btnSave.Location = new Point(6, 545);
|
||||||
|
btnSave.Name = "btnSave";
|
||||||
|
btnSave.Size = new Size(186, 32);
|
||||||
|
btnSave.TabIndex = 30;
|
||||||
|
btnSave.Text = "保存数据";
|
||||||
|
btnSave.UseVisualStyleBackColor = true;
|
||||||
|
btnSave.Click += btnSave_Click;
|
||||||
|
//
|
||||||
|
// GuideLineCircleCtrl
|
||||||
|
//
|
||||||
|
AutoScaleDimensions = new SizeF(7F, 17F);
|
||||||
|
AutoScaleMode = AutoScaleMode.Font;
|
||||||
|
Controls.Add(splitContainer);
|
||||||
|
Controls.Add(lblElapsed);
|
||||||
|
Controls.Add(label4);
|
||||||
|
Name = "GuideLineCircleCtrl";
|
||||||
|
Size = new Size(1280, 640);
|
||||||
|
Load += GuideLineCircleCtrl_Load;
|
||||||
|
splitContainer.Panel1.ResumeLayout(false);
|
||||||
|
splitContainer.Panel2.ResumeLayout(false);
|
||||||
|
((System.ComponentModel.ISupportInitialize)splitContainer).EndInit();
|
||||||
|
splitContainer.ResumeLayout(false);
|
||||||
|
panelGuide.ResumeLayout(false);
|
||||||
|
panelGuide.PerformLayout();
|
||||||
|
groupBox2.ResumeLayout(false);
|
||||||
|
groupBox2.PerformLayout();
|
||||||
|
((System.ComponentModel.ISupportInitialize)NumRectWidth1).EndInit();
|
||||||
|
groupBox1.ResumeLayout(false);
|
||||||
|
groupBox1.PerformLayout();
|
||||||
|
panel1.ResumeLayout(false);
|
||||||
|
panel1.PerformLayout();
|
||||||
|
statusStrip1.ResumeLayout(false);
|
||||||
|
statusStrip1.PerformLayout();
|
||||||
|
ResumeLayout(false);
|
||||||
|
PerformLayout();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
private Label lblElapsed;
|
||||||
|
private Label label4;
|
||||||
|
|
||||||
|
private SplitContainer splitContainer;
|
||||||
|
private Panel panelGuide;
|
||||||
|
private Panel panel1;
|
||||||
|
private Canvas.UI.FlyCanvas canvas;
|
||||||
|
private StatusStrip statusStrip1;
|
||||||
|
private ToolStripStatusLabel lblStatus;
|
||||||
|
private GroupBox groupBox2;
|
||||||
|
private TextBox tbLineX2;
|
||||||
|
private Label label8;
|
||||||
|
private TextBox tbLineY2;
|
||||||
|
private Label label5;
|
||||||
|
private TextBox tbLineX1;
|
||||||
|
private TextBox tbLineY1;
|
||||||
|
private Label label6;
|
||||||
|
private Label label7;
|
||||||
|
private GroupBox groupBox1;
|
||||||
|
private TextBox tbCircleX;
|
||||||
|
private TextBox tbCircleY;
|
||||||
|
private TextBox tbCircleR;
|
||||||
|
private Label label3;
|
||||||
|
private Label label2;
|
||||||
|
private Label label1;
|
||||||
|
private CtrlTitleBar ctrlTitleBar;
|
||||||
|
private Button btnCreateCircle;
|
||||||
|
private Button btnLoadImage;
|
||||||
|
private Label label9;
|
||||||
|
private Button btnExecute;
|
||||||
|
private Label label10;
|
||||||
|
private Button btnCreateLine;
|
||||||
|
private TextBox tbRectWidth1;
|
||||||
|
private Label label11;
|
||||||
|
private NumericUpDown NumRectWidth1;
|
||||||
|
private Label lblDistance;
|
||||||
|
private Label label17;
|
||||||
|
private Label lblResult;
|
||||||
|
private Label label15;
|
||||||
|
private Button btnSave;
|
||||||
|
}
|
||||||
|
}
|
||||||
449
CanFly/UI/GuidePanel/GuideLineCircleCtrl.cs
Normal file
449
CanFly/UI/GuidePanel/GuideLineCircleCtrl.cs
Normal file
@@ -0,0 +1,449 @@
|
|||||||
|
using CanFly.Canvas.Helper;
|
||||||
|
using CanFly.Canvas.Shape;
|
||||||
|
using CanFly.Canvas.UI;
|
||||||
|
using CanFly.Helper;
|
||||||
|
using HalconDotNet;
|
||||||
|
using OpenCvSharp;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.ComponentModel;
|
||||||
|
using System.Data;
|
||||||
|
using System.Drawing;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Windows.Forms;
|
||||||
|
|
||||||
|
|
||||||
|
namespace CanFly.UI.GuidePanel
|
||||||
|
{
|
||||||
|
public partial class GuideLineCircleCtrl : BaseGuideControl
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
private FlyShape? _circle;
|
||||||
|
private FlyShape? _line;
|
||||||
|
|
||||||
|
|
||||||
|
private float _lineX1;
|
||||||
|
private float _lineY1;
|
||||||
|
private float _lineX2;
|
||||||
|
private float _lineY2;
|
||||||
|
private float _lineWidth;
|
||||||
|
|
||||||
|
|
||||||
|
private float _circleX;
|
||||||
|
private float _circleY;
|
||||||
|
private float _circleR;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
protected override string GetScriptFileName() => "LineToCircle.hdvp";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public GuideLineCircleCtrl()
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
|
||||||
|
this.canvas.mouseMoved += Canvas_mouseMoved;
|
||||||
|
this.canvas.OnShapeUpdateEvent += UpdateShape;
|
||||||
|
this.canvas.selectionChanged += Canvas_selectionChanged;
|
||||||
|
|
||||||
|
this.canvas.OnShapeMoving += Canvas_OnShapeMoving;
|
||||||
|
this.canvas.newShape += Canvas_newShape;
|
||||||
|
|
||||||
|
this.ctrlTitleBar.OnCloseClicked += OnControlClose;
|
||||||
|
|
||||||
|
NumRectWidth1.ValueChanged -= NumRectWidth1_ValueChanged;
|
||||||
|
NumRectWidth1.Value = 40;
|
||||||
|
NumRectWidth1.ValueChanged += NumRectWidth1_ValueChanged;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
protected override void UpdateShape(FlyShape shape)
|
||||||
|
{
|
||||||
|
switch (shape.ShapeType)
|
||||||
|
{
|
||||||
|
case ShapeTypeEnum.Line:
|
||||||
|
this._line = shape;
|
||||||
|
_line.IsDrawLineVirtualRect = true;
|
||||||
|
var pts = this._line.Points;
|
||||||
|
|
||||||
|
_lineX1 = pts[0].X;
|
||||||
|
_lineY1 = pts[0].Y;
|
||||||
|
_lineX2 = pts[1].X;
|
||||||
|
_lineY2 = pts[1].Y;
|
||||||
|
_lineWidth = shape.LineVirtualRectWidth;
|
||||||
|
|
||||||
|
tbLineX1.Text = _lineX1.ToString("F3");
|
||||||
|
tbLineY1.Text = _lineY1.ToString("F3");
|
||||||
|
tbLineX2.Text = _lineX2.ToString("F3");
|
||||||
|
tbLineY2.Text = _lineY2.ToString("F3");
|
||||||
|
// NumRectWidth1.Value = (decimal)_lineWidth;
|
||||||
|
break;
|
||||||
|
case ShapeTypeEnum.Circle:
|
||||||
|
this._circle = shape;
|
||||||
|
|
||||||
|
_circleX = shape.Points[0].X;
|
||||||
|
_circleY = shape.Points[0].Y;
|
||||||
|
_circleR = PointHelper.Distance(shape.Points[0], shape.Points[1]);
|
||||||
|
|
||||||
|
this.tbCircleX.Text = _circleX.ToString("F3");
|
||||||
|
this.tbCircleY.Text = _circleY.ToString("F3");
|
||||||
|
this.tbCircleR.Text = _circleR.ToString("F3");
|
||||||
|
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private void GuideLineCircleCtrl_Load(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private void Canvas_mouseMoved(PointF pos)
|
||||||
|
{
|
||||||
|
if (InvokeRequired)
|
||||||
|
{
|
||||||
|
Invoke(Canvas_mouseMoved, pos);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
lblStatus.Text = $"X:{pos.X}, Y:{pos.Y}";
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private void Canvas_selectionChanged(List<FlyShape> shapes)
|
||||||
|
{
|
||||||
|
//if (shapes.Count != 1)
|
||||||
|
//{
|
||||||
|
// // panelGuide.Controls.Clear();
|
||||||
|
// return;
|
||||||
|
//}
|
||||||
|
//SwitchGuideForm(shapes[0].ShapeType);
|
||||||
|
// Canvas_OnShapeUpdateEvent(shapes[0]);
|
||||||
|
|
||||||
|
if (shapes.Count != 1)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
UpdateShape(shapes[0]);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private void Canvas_OnShapeMoving(List<FlyShape> shapes)
|
||||||
|
{
|
||||||
|
if (shapes.Count != 1)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
UpdateShape(shapes[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private void btnCreateCircle_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
if (this.canvas.pixmap == null)
|
||||||
|
{
|
||||||
|
MessageBox.Show("请先打开图片");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.tbCircleX.Text = string.Empty;
|
||||||
|
this.tbCircleY.Text = string.Empty;
|
||||||
|
this.tbCircleR.Text = string.Empty;
|
||||||
|
this.canvas.Shapes.RemoveAll(shp => shp.ShapeType == ShapeTypeEnum.Circle);
|
||||||
|
|
||||||
|
this.canvas.Invalidate();
|
||||||
|
this.canvas.StartDraw(ShapeTypeEnum.Circle);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private void btnCreateLine_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
if (this.canvas.pixmap == null)
|
||||||
|
{
|
||||||
|
MessageBox.Show("请先打开图片");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
tbLineX1.Text = string.Empty;
|
||||||
|
tbLineY1.Text = string.Empty;
|
||||||
|
tbLineX2.Text = string.Empty;
|
||||||
|
tbLineY2.Text = string.Empty;
|
||||||
|
|
||||||
|
this.canvas.Shapes.RemoveAll(shp => shp.ShapeType == ShapeTypeEnum.Line);
|
||||||
|
this.canvas.Invalidate();
|
||||||
|
this.canvas.StartDraw(ShapeTypeEnum.Line);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private void btnLoadImage_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
OpenImageFile(bitmap =>
|
||||||
|
{
|
||||||
|
this.canvas.LoadPixmap(bitmap);
|
||||||
|
this.canvas.Enabled = true;
|
||||||
|
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void Canvas_newShape()
|
||||||
|
{
|
||||||
|
this.canvas.StopDraw();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
string strarrayX=string.Empty;
|
||||||
|
string strarrayY=string.Empty;
|
||||||
|
private void btnExecute_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (this.canvas.pixmap == null)
|
||||||
|
{
|
||||||
|
MessageBox.Show("请先打开图片");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (this.tbLineX1.Text.Trim().Length == 0)
|
||||||
|
{
|
||||||
|
MessageBox.Show("请先创建直线");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (this.tbLineX1.Text.Trim().Length == 0)
|
||||||
|
{
|
||||||
|
MessageBox.Show("请先创建圆形");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.canvas.OutsideShapes.Clear();
|
||||||
|
this.canvas.Invalidate();
|
||||||
|
|
||||||
|
flag = new List<double>();
|
||||||
|
Distance = new List<double>();
|
||||||
|
fRowCenter = new List<double>();
|
||||||
|
fColCenter = new List<double>();
|
||||||
|
fRadius = new List<double>();
|
||||||
|
RowBegin = new List<double>();
|
||||||
|
ColBegin = new List<double>();
|
||||||
|
RowEnd = new List<double>();
|
||||||
|
ColEnd = new List<double>();
|
||||||
|
Dictionary<string, HObject> inputImg = new Dictionary<string, HObject>();
|
||||||
|
|
||||||
|
if (hImage == null)
|
||||||
|
{
|
||||||
|
HOperatorSet.ReadImage(out hImage, CurrentImageFile);
|
||||||
|
}
|
||||||
|
inputImg["INPUT_Image"] = hImage;
|
||||||
|
|
||||||
|
Dictionary<string, HTuple> inputPara = new Dictionary<string, HTuple>();
|
||||||
|
|
||||||
|
PointF[] Points = this._line.LineVirtualRectPoints;
|
||||||
|
PointF Point1 = Points[0];
|
||||||
|
PointF Point2 = Points[1];
|
||||||
|
PointF Point3 = Points[2];
|
||||||
|
PointF Point4 = Points[3];
|
||||||
|
PointF Point5 = Points[0];
|
||||||
|
|
||||||
|
float x1 = Point1.X;
|
||||||
|
float y1 = Point1.Y;
|
||||||
|
|
||||||
|
float x2 = Point2.X;
|
||||||
|
float y2 = Point2.Y;
|
||||||
|
|
||||||
|
float x3 = Point3.X;
|
||||||
|
float y3 = Point3.Y;
|
||||||
|
|
||||||
|
float x4 = Point4.X;
|
||||||
|
float y4 = Point4.Y;
|
||||||
|
|
||||||
|
float x5 = Point5.X;
|
||||||
|
float y5 = Point5.Y;
|
||||||
|
|
||||||
|
|
||||||
|
float[] arrayX = new float[] { x1, x2, x3, x4, x5 };
|
||||||
|
HTuple hTupleArrayX = new HTuple(arrayX);
|
||||||
|
|
||||||
|
float[] arrayY = new float[] { y1, y2, y3, y4, y5 };
|
||||||
|
HTuple hTupleArrayY = new HTuple(arrayY);
|
||||||
|
|
||||||
|
strarrayX=string.Join(",", arrayX);
|
||||||
|
strarrayY=string.Join(",", arrayY);
|
||||||
|
|
||||||
|
inputPara["LX"] = _lineX1;
|
||||||
|
inputPara["LY"] = _lineY1;
|
||||||
|
inputPara["RX"] = _lineX2;
|
||||||
|
inputPara["RY"] = _lineY2;
|
||||||
|
inputPara["XCenter"] = _circleX;
|
||||||
|
inputPara["YCenter"] = _circleY;
|
||||||
|
inputPara["Radius"] = _circleR;
|
||||||
|
inputPara["Line_XRect"] = hTupleArrayX;
|
||||||
|
inputPara["Line_YRect"] = hTupleArrayY;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
List<string> outputKeys = new List<string>()
|
||||||
|
{
|
||||||
|
"OUTPUT_Flag",
|
||||||
|
"distance",
|
||||||
|
"fRowCenter",
|
||||||
|
"fColCenter",
|
||||||
|
"fRadius",
|
||||||
|
"RowBegin",
|
||||||
|
"ColBegin",
|
||||||
|
"RowEnd",
|
||||||
|
"ColEnd"
|
||||||
|
};
|
||||||
|
|
||||||
|
ExecuteHScript(
|
||||||
|
inputImg,
|
||||||
|
inputPara,
|
||||||
|
outputKeys);
|
||||||
|
|
||||||
|
}
|
||||||
|
List<double> flag = new List<double>();
|
||||||
|
List<double> Distance = new List<double>();
|
||||||
|
List<double> fRowCenter = new List<double>();
|
||||||
|
List<double> fColCenter = new List<double>();
|
||||||
|
List<double> fRadius = new List<double>();
|
||||||
|
List<double> RowBegin = new List<double>();
|
||||||
|
List<double> ColBegin = new List<double>();
|
||||||
|
List<double> RowEnd = new List<double>();
|
||||||
|
List<double> ColEnd = new List<double>();
|
||||||
|
protected override void OnExecuteHScriptResult(
|
||||||
|
bool success,
|
||||||
|
Dictionary<string, HTuple> resultDic,
|
||||||
|
int timeElasped)
|
||||||
|
{
|
||||||
|
if (!success)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//"OUTPUT_Flag",
|
||||||
|
// "distance",
|
||||||
|
// "fRowCenter",
|
||||||
|
// "fColCenter",
|
||||||
|
// "fRadius",
|
||||||
|
// "RowBegin",
|
||||||
|
// "ColBegin",
|
||||||
|
// "RowEnd",
|
||||||
|
// "ColEnd"
|
||||||
|
|
||||||
|
flag = resultDic["OUTPUT_Flag"].HTupleToDouble();
|
||||||
|
Distance = resultDic["distance"].HTupleToDouble();
|
||||||
|
fRowCenter = resultDic["fRowCenter"].HTupleToDouble();
|
||||||
|
fColCenter = resultDic["fColCenter"].HTupleToDouble();
|
||||||
|
fRadius = resultDic["fRadius"].HTupleToDouble();
|
||||||
|
RowBegin = resultDic["RowBegin"].HTupleToDouble();
|
||||||
|
ColBegin = resultDic["ColBegin"].HTupleToDouble();
|
||||||
|
RowEnd = resultDic["RowEnd"].HTupleToDouble();
|
||||||
|
ColEnd = resultDic["ColEnd"].HTupleToDouble();
|
||||||
|
|
||||||
|
|
||||||
|
if (flag.Count > 0)
|
||||||
|
{
|
||||||
|
lblResult.Text = flag[0].ToString();
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
lblResult.Text = "无";
|
||||||
|
}
|
||||||
|
if (Distance.Count > 0)
|
||||||
|
{
|
||||||
|
lblDistance.Text = Distance[0].ToString();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
lblDistance.Text = "0";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (flag.Count > 0 && Distance.Count > 0 && fRowCenter.Count > 0 && fColCenter.Count > 0 && fRadius.Count > 0 && RowBegin.Count > 0 && ColBegin.Count > 0 && RowEnd.Count > 0 && ColEnd.Count > 0)
|
||||||
|
{
|
||||||
|
float width = 0;
|
||||||
|
this.canvas.DrawLine(new PointF((float)ColBegin[0], (float)RowBegin[0]), new PointF((float)ColEnd[0], (float)RowEnd[0]), width);
|
||||||
|
this.canvas.DrawCircle(new PointF((float)fColCenter[0], (float)fRowCenter[0]), (float)fRadius[0]);
|
||||||
|
|
||||||
|
this.canvas.Invalidate();
|
||||||
|
lblElapsed.Text = $"{timeElasped} ms";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private void NumRectWidth1_ValueChanged(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
if (_line != null)
|
||||||
|
{
|
||||||
|
//_line1.IsDrawLineVirtualRect = true;
|
||||||
|
_line.LineVirtualRectWidth = (float)NumRectWidth1.Value;
|
||||||
|
UpdateShape(_line);
|
||||||
|
this.canvas.Invalidate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void btnSave_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
if (lblResult.Text.Equals("无"))
|
||||||
|
{
|
||||||
|
MessageBox.Show("请先进行绘制");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (lblResult.Text != "0")
|
||||||
|
{
|
||||||
|
MessageBox.Show("测量计算错误,无法保存");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
string input = $"LX:{_lineX1};" +
|
||||||
|
$"LY:{_lineY1};" +
|
||||||
|
$"RX:{_lineX2};" +
|
||||||
|
$"RY:{_lineY2};" +
|
||||||
|
$"XCenter:{_circleX};" +
|
||||||
|
$"YCenter:{_circleY};" +
|
||||||
|
$"Radius:{_circleR};" +
|
||||||
|
$"Line_XRect:{strarrayX};"+
|
||||||
|
$"Line_YRect:{strarrayY}";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
string result = $"distance:{Distance[0]};";
|
||||||
|
DataToTriggerEvent(input, result);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
145
CanFly/UI/GuidePanel/GuideLineCircleCtrl.resx
Normal file
145
CanFly/UI/GuidePanel/GuideLineCircleCtrl.resx
Normal file
@@ -0,0 +1,145 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<root>
|
||||||
|
<!--
|
||||||
|
Microsoft ResX Schema
|
||||||
|
|
||||||
|
Version 2.0
|
||||||
|
|
||||||
|
The primary goals of this format is to allow a simple XML format
|
||||||
|
that is mostly human readable. The generation and parsing of the
|
||||||
|
various data types are done through the TypeConverter classes
|
||||||
|
associated with the data types.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
... ado.net/XML headers & schema ...
|
||||||
|
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||||
|
<resheader name="version">2.0</resheader>
|
||||||
|
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||||
|
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||||
|
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||||
|
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||||
|
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||||
|
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||||
|
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||||
|
<comment>This is a comment</comment>
|
||||||
|
</data>
|
||||||
|
|
||||||
|
There are any number of "resheader" rows that contain simple
|
||||||
|
name/value pairs.
|
||||||
|
|
||||||
|
Each data row contains a name, and value. The row also contains a
|
||||||
|
type or mimetype. Type corresponds to a .NET class that support
|
||||||
|
text/value conversion through the TypeConverter architecture.
|
||||||
|
Classes that don't support this are serialized and stored with the
|
||||||
|
mimetype set.
|
||||||
|
|
||||||
|
The mimetype is used for serialized objects, and tells the
|
||||||
|
ResXResourceReader how to depersist the object. This is currently not
|
||||||
|
extensible. For a given mimetype the value must be set accordingly:
|
||||||
|
|
||||||
|
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||||
|
that the ResXResourceWriter will generate, however the reader can
|
||||||
|
read any of the formats listed below.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.binary.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.soap.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||||
|
value : The object must be serialized into a byte array
|
||||||
|
: using a System.ComponentModel.TypeConverter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
-->
|
||||||
|
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||||
|
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||||
|
<xsd:element name="root" msdata:IsDataSet="true">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:choice maxOccurs="unbounded">
|
||||||
|
<xsd:element name="metadata">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="assembly">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:attribute name="alias" type="xsd:string" />
|
||||||
|
<xsd:attribute name="name" type="xsd:string" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="data">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="resheader">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:choice>
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:schema>
|
||||||
|
<resheader name="resmimetype">
|
||||||
|
<value>text/microsoft-resx</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="version">
|
||||||
|
<value>2.0</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="reader">
|
||||||
|
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="writer">
|
||||||
|
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
<data name="canvas.OutsideShapes" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||||
|
<value>
|
||||||
|
AAEAAAD/////AQAAAAAAAAAMAgAAAERDYW5GbHkuQ2FudmFzLCBWZXJzaW9uPTEuMC4wLjAsIEN1bHR1
|
||||||
|
cmU9bmV1dHJhbCwgUHVibGljS2V5VG9rZW49bnVsbAQBAAAAdlN5c3RlbS5Db2xsZWN0aW9ucy5HZW5l
|
||||||
|
cmljLkxpc3RgMVtbQ2FuRmx5LkNhbnZhcy5TaGFwZS5GbHlTaGFwZSwgQ2FuRmx5LkNhbnZhcywgQ3Vs
|
||||||
|
dHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1udWxsXV0DAAAABl9pdGVtcwVfc2l6ZQhfdmVyc2lv
|
||||||
|
bgQAAB5DYW5GbHkuQ2FudmFzLlNoYXBlLkZseVNoYXBlW10CAAAACAgJAwAAAAAAAAAAAAAADAQAAAAz
|
||||||
|
Q2FuRmx5LkNhbnZhcywgQ3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1udWxsBwMAAAAAAQAA
|
||||||
|
AAAAAAAEHENhbkZseS5DYW52YXMuU2hhcGUuRmx5U2hhcGUEAAAACw==
|
||||||
|
</value>
|
||||||
|
</data>
|
||||||
|
<data name="canvas.Shapes" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||||
|
<value>
|
||||||
|
AAEAAAD/////AQAAAAAAAAAMAgAAAERDYW5GbHkuQ2FudmFzLCBWZXJzaW9uPTEuMC4wLjAsIEN1bHR1
|
||||||
|
cmU9bmV1dHJhbCwgUHVibGljS2V5VG9rZW49bnVsbAQBAAAAdlN5c3RlbS5Db2xsZWN0aW9ucy5HZW5l
|
||||||
|
cmljLkxpc3RgMVtbQ2FuRmx5LkNhbnZhcy5TaGFwZS5GbHlTaGFwZSwgQ2FuRmx5LkNhbnZhcywgQ3Vs
|
||||||
|
dHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1udWxsXV0DAAAABl9pdGVtcwVfc2l6ZQhfdmVyc2lv
|
||||||
|
bgQAAB5DYW5GbHkuQ2FudmFzLlNoYXBlLkZseVNoYXBlW10CAAAACAgJAwAAAAAAAAAAAAAADAQAAAAz
|
||||||
|
Q2FuRmx5LkNhbnZhcywgQ3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1udWxsBwMAAAAAAQAA
|
||||||
|
AAAAAAAEHENhbkZseS5DYW52YXMuU2hhcGUuRmx5U2hhcGUEAAAACw==
|
||||||
|
</value>
|
||||||
|
</data>
|
||||||
|
<metadata name="statusStrip1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||||
|
<value>17, 17</value>
|
||||||
|
</metadata>
|
||||||
|
</root>
|
||||||
427
CanFly/UI/GuidePanel/GuideLineCtrl.Designer.cs
generated
Normal file
427
CanFly/UI/GuidePanel/GuideLineCtrl.Designer.cs
generated
Normal file
@@ -0,0 +1,427 @@
|
|||||||
|
namespace CanFly.UI.GuidePanel
|
||||||
|
{
|
||||||
|
partial class GuideLineCtrl
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 必需的设计器变量。
|
||||||
|
/// </summary>
|
||||||
|
private System.ComponentModel.IContainer components = null;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 清理所有正在使用的资源。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="disposing">如果应释放托管资源,为 true;否则为 false。</param>
|
||||||
|
protected override void Dispose(bool disposing)
|
||||||
|
{
|
||||||
|
if (disposing && (components != null))
|
||||||
|
{
|
||||||
|
components.Dispose();
|
||||||
|
}
|
||||||
|
base.Dispose(disposing);
|
||||||
|
}
|
||||||
|
|
||||||
|
#region 组件设计器生成的代码
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 设计器支持所需的方法 - 不要修改
|
||||||
|
/// 使用代码编辑器修改此方法的内容。
|
||||||
|
/// </summary>
|
||||||
|
private void InitializeComponent()
|
||||||
|
{
|
||||||
|
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(GuideLineCtrl));
|
||||||
|
lblElapsed = new Label();
|
||||||
|
label4 = new Label();
|
||||||
|
splitContainer = new SplitContainer();
|
||||||
|
panelGuide = new Panel();
|
||||||
|
btnSave = new Button();
|
||||||
|
lblResult = new Label();
|
||||||
|
label1 = new Label();
|
||||||
|
btnCreateLine = new Button();
|
||||||
|
btnLoadImage = new Button();
|
||||||
|
label9 = new Label();
|
||||||
|
btnExecute = new Button();
|
||||||
|
label10 = new Label();
|
||||||
|
groupBox2 = new GroupBox();
|
||||||
|
NumRectWidth1 = new NumericUpDown();
|
||||||
|
label11 = new Label();
|
||||||
|
tbLineX2 = new TextBox();
|
||||||
|
label8 = new Label();
|
||||||
|
tbLineY2 = new TextBox();
|
||||||
|
label5 = new Label();
|
||||||
|
tbLineX1 = new TextBox();
|
||||||
|
tbLineY1 = new TextBox();
|
||||||
|
label6 = new Label();
|
||||||
|
label7 = new Label();
|
||||||
|
ctrlTitleBar = new CtrlTitleBar();
|
||||||
|
panel1 = new Panel();
|
||||||
|
canvas = new Canvas.UI.FlyCanvas();
|
||||||
|
statusStrip1 = new StatusStrip();
|
||||||
|
lblStatus = new ToolStripStatusLabel();
|
||||||
|
((System.ComponentModel.ISupportInitialize)splitContainer).BeginInit();
|
||||||
|
splitContainer.Panel1.SuspendLayout();
|
||||||
|
splitContainer.Panel2.SuspendLayout();
|
||||||
|
splitContainer.SuspendLayout();
|
||||||
|
panelGuide.SuspendLayout();
|
||||||
|
groupBox2.SuspendLayout();
|
||||||
|
((System.ComponentModel.ISupportInitialize)NumRectWidth1).BeginInit();
|
||||||
|
panel1.SuspendLayout();
|
||||||
|
statusStrip1.SuspendLayout();
|
||||||
|
SuspendLayout();
|
||||||
|
//
|
||||||
|
// lblElapsed
|
||||||
|
//
|
||||||
|
lblElapsed.AutoSize = true;
|
||||||
|
lblElapsed.Location = new Point(50, 328);
|
||||||
|
lblElapsed.Name = "lblElapsed";
|
||||||
|
lblElapsed.Size = new Size(32, 17);
|
||||||
|
lblElapsed.TabIndex = 9;
|
||||||
|
lblElapsed.Text = "0ms";
|
||||||
|
//
|
||||||
|
// label4
|
||||||
|
//
|
||||||
|
label4.AutoSize = true;
|
||||||
|
label4.Location = new Point(0, 328);
|
||||||
|
label4.Name = "label4";
|
||||||
|
label4.Size = new Size(44, 17);
|
||||||
|
label4.TabIndex = 8;
|
||||||
|
label4.Text = "耗时:";
|
||||||
|
//
|
||||||
|
// splitContainer
|
||||||
|
//
|
||||||
|
splitContainer.Dock = DockStyle.Fill;
|
||||||
|
splitContainer.Location = new Point(0, 0);
|
||||||
|
splitContainer.Name = "splitContainer";
|
||||||
|
//
|
||||||
|
// splitContainer.Panel1
|
||||||
|
//
|
||||||
|
splitContainer.Panel1.Controls.Add(panelGuide);
|
||||||
|
splitContainer.Panel1MinSize = 150;
|
||||||
|
//
|
||||||
|
// splitContainer.Panel2
|
||||||
|
//
|
||||||
|
splitContainer.Panel2.Controls.Add(panel1);
|
||||||
|
splitContainer.Size = new Size(1280, 640);
|
||||||
|
splitContainer.SplitterDistance = 200;
|
||||||
|
splitContainer.TabIndex = 11;
|
||||||
|
//
|
||||||
|
// panelGuide
|
||||||
|
//
|
||||||
|
panelGuide.BorderStyle = BorderStyle.FixedSingle;
|
||||||
|
panelGuide.Controls.Add(btnSave);
|
||||||
|
panelGuide.Controls.Add(lblResult);
|
||||||
|
panelGuide.Controls.Add(label1);
|
||||||
|
panelGuide.Controls.Add(btnCreateLine);
|
||||||
|
panelGuide.Controls.Add(btnLoadImage);
|
||||||
|
panelGuide.Controls.Add(label9);
|
||||||
|
panelGuide.Controls.Add(btnExecute);
|
||||||
|
panelGuide.Controls.Add(label10);
|
||||||
|
panelGuide.Controls.Add(groupBox2);
|
||||||
|
panelGuide.Controls.Add(ctrlTitleBar);
|
||||||
|
panelGuide.Dock = DockStyle.Fill;
|
||||||
|
panelGuide.Location = new Point(0, 0);
|
||||||
|
panelGuide.Name = "panelGuide";
|
||||||
|
panelGuide.Size = new Size(200, 640);
|
||||||
|
panelGuide.TabIndex = 0;
|
||||||
|
//
|
||||||
|
// btnSave
|
||||||
|
//
|
||||||
|
btnSave.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
|
||||||
|
btnSave.Location = new Point(6, 390);
|
||||||
|
btnSave.Name = "btnSave";
|
||||||
|
btnSave.Size = new Size(186, 32);
|
||||||
|
btnSave.TabIndex = 23;
|
||||||
|
btnSave.Text = "保存数据";
|
||||||
|
btnSave.UseVisualStyleBackColor = true;
|
||||||
|
btnSave.Click += btnSave_Click;
|
||||||
|
//
|
||||||
|
// lblResult
|
||||||
|
//
|
||||||
|
lblResult.AutoSize = true;
|
||||||
|
lblResult.Location = new Point(59, 354);
|
||||||
|
lblResult.Name = "lblResult";
|
||||||
|
lblResult.Size = new Size(20, 17);
|
||||||
|
lblResult.TabIndex = 22;
|
||||||
|
lblResult.Text = "无";
|
||||||
|
//
|
||||||
|
// label1
|
||||||
|
//
|
||||||
|
label1.AutoSize = true;
|
||||||
|
label1.Location = new Point(9, 354);
|
||||||
|
label1.Name = "label1";
|
||||||
|
label1.Size = new Size(44, 17);
|
||||||
|
label1.TabIndex = 21;
|
||||||
|
label1.Text = "结果:";
|
||||||
|
//
|
||||||
|
// btnCreateLine
|
||||||
|
//
|
||||||
|
btnCreateLine.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
|
||||||
|
btnCreateLine.Location = new Point(9, 252);
|
||||||
|
btnCreateLine.Name = "btnCreateLine";
|
||||||
|
btnCreateLine.Size = new Size(186, 32);
|
||||||
|
btnCreateLine.TabIndex = 20;
|
||||||
|
btnCreateLine.Text = "创建直线";
|
||||||
|
btnCreateLine.UseVisualStyleBackColor = true;
|
||||||
|
btnCreateLine.Click += btnCreateLine_Click;
|
||||||
|
//
|
||||||
|
// btnLoadImage
|
||||||
|
//
|
||||||
|
btnLoadImage.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
|
||||||
|
btnLoadImage.Location = new Point(6, 214);
|
||||||
|
btnLoadImage.Name = "btnLoadImage";
|
||||||
|
btnLoadImage.Size = new Size(186, 32);
|
||||||
|
btnLoadImage.TabIndex = 18;
|
||||||
|
btnLoadImage.Text = "打开图片";
|
||||||
|
btnLoadImage.UseVisualStyleBackColor = true;
|
||||||
|
btnLoadImage.Click += btnLoadImage_Click;
|
||||||
|
//
|
||||||
|
// label9
|
||||||
|
//
|
||||||
|
label9.AutoSize = true;
|
||||||
|
label9.Location = new Point(59, 325);
|
||||||
|
label9.Name = "label9";
|
||||||
|
label9.Size = new Size(32, 17);
|
||||||
|
label9.TabIndex = 17;
|
||||||
|
label9.Text = "0ms";
|
||||||
|
//
|
||||||
|
// btnExecute
|
||||||
|
//
|
||||||
|
btnExecute.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
|
||||||
|
btnExecute.Location = new Point(9, 290);
|
||||||
|
btnExecute.Name = "btnExecute";
|
||||||
|
btnExecute.Size = new Size(186, 32);
|
||||||
|
btnExecute.TabIndex = 15;
|
||||||
|
btnExecute.Text = "执行";
|
||||||
|
btnExecute.UseVisualStyleBackColor = true;
|
||||||
|
btnExecute.Click += btnExecute_Click;
|
||||||
|
//
|
||||||
|
// label10
|
||||||
|
//
|
||||||
|
label10.AutoSize = true;
|
||||||
|
label10.Location = new Point(9, 325);
|
||||||
|
label10.Name = "label10";
|
||||||
|
label10.Size = new Size(44, 17);
|
||||||
|
label10.TabIndex = 16;
|
||||||
|
label10.Text = "耗时:";
|
||||||
|
//
|
||||||
|
// groupBox2
|
||||||
|
//
|
||||||
|
groupBox2.Controls.Add(NumRectWidth1);
|
||||||
|
groupBox2.Controls.Add(label11);
|
||||||
|
groupBox2.Controls.Add(tbLineX2);
|
||||||
|
groupBox2.Controls.Add(label8);
|
||||||
|
groupBox2.Controls.Add(tbLineY2);
|
||||||
|
groupBox2.Controls.Add(label5);
|
||||||
|
groupBox2.Controls.Add(tbLineX1);
|
||||||
|
groupBox2.Controls.Add(tbLineY1);
|
||||||
|
groupBox2.Controls.Add(label6);
|
||||||
|
groupBox2.Controls.Add(label7);
|
||||||
|
groupBox2.Dock = DockStyle.Top;
|
||||||
|
groupBox2.Location = new Point(0, 36);
|
||||||
|
groupBox2.Name = "groupBox2";
|
||||||
|
groupBox2.Size = new Size(198, 172);
|
||||||
|
groupBox2.TabIndex = 13;
|
||||||
|
groupBox2.TabStop = false;
|
||||||
|
groupBox2.Text = "线参数";
|
||||||
|
//
|
||||||
|
// NumRectWidth1
|
||||||
|
//
|
||||||
|
NumRectWidth1.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
|
||||||
|
NumRectWidth1.Location = new Point(56, 138);
|
||||||
|
NumRectWidth1.Maximum = new decimal(new int[] { 9000, 0, 0, 0 });
|
||||||
|
NumRectWidth1.Minimum = new decimal(new int[] { 1, 0, 0, 0 });
|
||||||
|
NumRectWidth1.Name = "NumRectWidth1";
|
||||||
|
NumRectWidth1.Size = new Size(136, 23);
|
||||||
|
NumRectWidth1.TabIndex = 13;
|
||||||
|
NumRectWidth1.Value = new decimal(new int[] { 1, 0, 0, 0 });
|
||||||
|
//
|
||||||
|
// label11
|
||||||
|
//
|
||||||
|
label11.AutoSize = true;
|
||||||
|
label11.Location = new Point(6, 140);
|
||||||
|
label11.Name = "label11";
|
||||||
|
label11.Size = new Size(35, 17);
|
||||||
|
label11.TabIndex = 12;
|
||||||
|
label11.Text = "宽度:";
|
||||||
|
//
|
||||||
|
// tbLineX2
|
||||||
|
//
|
||||||
|
tbLineX2.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
|
||||||
|
tbLineX2.Location = new Point(56, 80);
|
||||||
|
tbLineX2.Name = "tbLineX2";
|
||||||
|
tbLineX2.Size = new Size(136, 23);
|
||||||
|
tbLineX2.TabIndex = 9;
|
||||||
|
//
|
||||||
|
// label8
|
||||||
|
//
|
||||||
|
label8.AutoSize = true;
|
||||||
|
label8.Location = new Point(6, 83);
|
||||||
|
label8.Name = "label8";
|
||||||
|
label8.Size = new Size(26, 17);
|
||||||
|
label8.TabIndex = 8;
|
||||||
|
label8.Text = "X2:";
|
||||||
|
//
|
||||||
|
// tbLineY2
|
||||||
|
//
|
||||||
|
tbLineY2.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
|
||||||
|
tbLineY2.Location = new Point(56, 109);
|
||||||
|
tbLineY2.Name = "tbLineY2";
|
||||||
|
tbLineY2.Size = new Size(136, 23);
|
||||||
|
tbLineY2.TabIndex = 7;
|
||||||
|
//
|
||||||
|
// label5
|
||||||
|
//
|
||||||
|
label5.AutoSize = true;
|
||||||
|
label5.Location = new Point(6, 112);
|
||||||
|
label5.Name = "label5";
|
||||||
|
label5.Size = new Size(25, 17);
|
||||||
|
label5.TabIndex = 6;
|
||||||
|
label5.Text = "Y2:";
|
||||||
|
//
|
||||||
|
// tbLineX1
|
||||||
|
//
|
||||||
|
tbLineX1.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
|
||||||
|
tbLineX1.Location = new Point(56, 22);
|
||||||
|
tbLineX1.Name = "tbLineX1";
|
||||||
|
tbLineX1.Size = new Size(136, 23);
|
||||||
|
tbLineX1.TabIndex = 5;
|
||||||
|
//
|
||||||
|
// tbLineY1
|
||||||
|
//
|
||||||
|
tbLineY1.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
|
||||||
|
tbLineY1.Location = new Point(56, 51);
|
||||||
|
tbLineY1.Name = "tbLineY1";
|
||||||
|
tbLineY1.Size = new Size(136, 23);
|
||||||
|
tbLineY1.TabIndex = 4;
|
||||||
|
//
|
||||||
|
// label6
|
||||||
|
//
|
||||||
|
label6.AutoSize = true;
|
||||||
|
label6.Location = new Point(6, 54);
|
||||||
|
label6.Name = "label6";
|
||||||
|
label6.Size = new Size(25, 17);
|
||||||
|
label6.TabIndex = 1;
|
||||||
|
label6.Text = "Y1:";
|
||||||
|
//
|
||||||
|
// label7
|
||||||
|
//
|
||||||
|
label7.AutoSize = true;
|
||||||
|
label7.Location = new Point(6, 25);
|
||||||
|
label7.Name = "label7";
|
||||||
|
label7.Size = new Size(26, 17);
|
||||||
|
label7.TabIndex = 0;
|
||||||
|
label7.Text = "X1:";
|
||||||
|
//
|
||||||
|
// ctrlTitleBar
|
||||||
|
//
|
||||||
|
ctrlTitleBar.Dock = DockStyle.Top;
|
||||||
|
ctrlTitleBar.Location = new Point(0, 0);
|
||||||
|
ctrlTitleBar.MinimumSize = new Size(0, 36);
|
||||||
|
ctrlTitleBar.Name = "ctrlTitleBar";
|
||||||
|
ctrlTitleBar.Padding = new Padding(3);
|
||||||
|
ctrlTitleBar.Size = new Size(198, 36);
|
||||||
|
ctrlTitleBar.TabIndex = 11;
|
||||||
|
ctrlTitleBar.Title = "直线测量";
|
||||||
|
//
|
||||||
|
// panel1
|
||||||
|
//
|
||||||
|
panel1.BorderStyle = BorderStyle.FixedSingle;
|
||||||
|
panel1.Controls.Add(canvas);
|
||||||
|
panel1.Controls.Add(statusStrip1);
|
||||||
|
panel1.Dock = DockStyle.Fill;
|
||||||
|
panel1.Location = new Point(0, 0);
|
||||||
|
panel1.Name = "panel1";
|
||||||
|
panel1.Size = new Size(1076, 640);
|
||||||
|
panel1.TabIndex = 1;
|
||||||
|
//
|
||||||
|
// canvas
|
||||||
|
//
|
||||||
|
canvas.AllowMultiSelect = false;
|
||||||
|
canvas.CreateMode = Canvas.Shape.ShapeTypeEnum.Polygon;
|
||||||
|
canvas.Dock = DockStyle.Fill;
|
||||||
|
canvas.Enabled = false;
|
||||||
|
canvas.FillDrawing = false;
|
||||||
|
canvas.Location = new Point(0, 0);
|
||||||
|
canvas.Margin = new Padding(2);
|
||||||
|
canvas.Name = "canvas";
|
||||||
|
canvas.OutsideShapes = (List<Canvas.Shape.FlyShape>)resources.GetObject("canvas.OutsideShapes");
|
||||||
|
canvas.Scale = 1F;
|
||||||
|
canvas.Shapes = (List<Canvas.Shape.FlyShape>)resources.GetObject("canvas.Shapes");
|
||||||
|
canvas.Size = new Size(1074, 616);
|
||||||
|
canvas.TabIndex = 2;
|
||||||
|
//
|
||||||
|
// statusStrip1
|
||||||
|
//
|
||||||
|
statusStrip1.Items.AddRange(new ToolStripItem[] { lblStatus });
|
||||||
|
statusStrip1.Location = new Point(0, 616);
|
||||||
|
statusStrip1.Name = "statusStrip1";
|
||||||
|
statusStrip1.Size = new Size(1074, 22);
|
||||||
|
statusStrip1.TabIndex = 1;
|
||||||
|
statusStrip1.Text = "statusStrip1";
|
||||||
|
//
|
||||||
|
// lblStatus
|
||||||
|
//
|
||||||
|
lblStatus.Name = "lblStatus";
|
||||||
|
lblStatus.Size = new Size(44, 17);
|
||||||
|
lblStatus.Text = " ";
|
||||||
|
//
|
||||||
|
// GuideLineCtrl
|
||||||
|
//
|
||||||
|
AutoScaleDimensions = new SizeF(7F, 17F);
|
||||||
|
AutoScaleMode = AutoScaleMode.Font;
|
||||||
|
Controls.Add(splitContainer);
|
||||||
|
Controls.Add(lblElapsed);
|
||||||
|
Controls.Add(label4);
|
||||||
|
Name = "GuideLineCtrl";
|
||||||
|
Size = new Size(1280, 640);
|
||||||
|
Load += GuideLineCircleCtrl_Load;
|
||||||
|
splitContainer.Panel1.ResumeLayout(false);
|
||||||
|
splitContainer.Panel2.ResumeLayout(false);
|
||||||
|
((System.ComponentModel.ISupportInitialize)splitContainer).EndInit();
|
||||||
|
splitContainer.ResumeLayout(false);
|
||||||
|
panelGuide.ResumeLayout(false);
|
||||||
|
panelGuide.PerformLayout();
|
||||||
|
groupBox2.ResumeLayout(false);
|
||||||
|
groupBox2.PerformLayout();
|
||||||
|
((System.ComponentModel.ISupportInitialize)NumRectWidth1).EndInit();
|
||||||
|
panel1.ResumeLayout(false);
|
||||||
|
panel1.PerformLayout();
|
||||||
|
statusStrip1.ResumeLayout(false);
|
||||||
|
statusStrip1.PerformLayout();
|
||||||
|
ResumeLayout(false);
|
||||||
|
PerformLayout();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
private Label lblElapsed;
|
||||||
|
private Label label4;
|
||||||
|
|
||||||
|
private SplitContainer splitContainer;
|
||||||
|
private Panel panelGuide;
|
||||||
|
private Panel panel1;
|
||||||
|
private Canvas.UI.FlyCanvas canvas;
|
||||||
|
private StatusStrip statusStrip1;
|
||||||
|
private ToolStripStatusLabel lblStatus;
|
||||||
|
private GroupBox groupBox2;
|
||||||
|
private TextBox tbLineX2;
|
||||||
|
private Label label8;
|
||||||
|
private TextBox tbLineY2;
|
||||||
|
private Label label5;
|
||||||
|
private TextBox tbLineX1;
|
||||||
|
private TextBox tbLineY1;
|
||||||
|
private Label label6;
|
||||||
|
private Label label7;
|
||||||
|
private CtrlTitleBar ctrlTitleBar;
|
||||||
|
private Button btnLoadImage;
|
||||||
|
private Label label9;
|
||||||
|
private Button btnExecute;
|
||||||
|
private Label label10;
|
||||||
|
private Button btnCreateLine;
|
||||||
|
private TextBox tbRectWidth1;
|
||||||
|
private Label label11;
|
||||||
|
private NumericUpDown NumRectWidth1;
|
||||||
|
private Label lblResult;
|
||||||
|
private Label label1;
|
||||||
|
private Button btnSave;
|
||||||
|
}
|
||||||
|
}
|
||||||
387
CanFly/UI/GuidePanel/GuideLineCtrl.cs
Normal file
387
CanFly/UI/GuidePanel/GuideLineCtrl.cs
Normal file
@@ -0,0 +1,387 @@
|
|||||||
|
using CanFly.Canvas.Helper;
|
||||||
|
using CanFly.Canvas.Shape;
|
||||||
|
using CanFly.Canvas.UI;
|
||||||
|
using CanFly.Helper;
|
||||||
|
using HalconDotNet;
|
||||||
|
using OpenCvSharp;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.ComponentModel;
|
||||||
|
using System.Data;
|
||||||
|
using System.Drawing;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Windows.Forms;
|
||||||
|
|
||||||
|
namespace CanFly.UI.GuidePanel
|
||||||
|
{
|
||||||
|
public partial class GuideLineCtrl : BaseGuideControl
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private FlyShape? _line;
|
||||||
|
|
||||||
|
|
||||||
|
private float _lineX1;
|
||||||
|
private float _lineY1;
|
||||||
|
private float _lineX2;
|
||||||
|
private float _lineY2;
|
||||||
|
private float _lineWidth;
|
||||||
|
private PointF[] _rectPoints = new PointF[4];
|
||||||
|
//private float _LineLX=new float();
|
||||||
|
//private float _LineLY =new float();
|
||||||
|
//private float _LineRX =new float();
|
||||||
|
//private float _LineRY =new float();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
protected override string GetScriptFileName() => "Line_detect.hdvp";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public GuideLineCtrl()
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
|
||||||
|
this.canvas.mouseMoved += Canvas_mouseMoved;
|
||||||
|
this.canvas.OnShapeUpdateEvent += UpdateShape;
|
||||||
|
this.canvas.selectionChanged += Canvas_selectionChanged;
|
||||||
|
|
||||||
|
this.canvas.OnShapeMoving += Canvas_OnShapeMoving;
|
||||||
|
this.canvas.newShape += Canvas_newShape;
|
||||||
|
|
||||||
|
this.ctrlTitleBar.OnCloseClicked += OnControlClose;
|
||||||
|
|
||||||
|
NumRectWidth1.ValueChanged -= NumRectWidth1_ValueChanged;
|
||||||
|
NumRectWidth1.Value = 40;
|
||||||
|
NumRectWidth1.ValueChanged += NumRectWidth1_ValueChanged;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
protected override void UpdateShape(FlyShape shape)
|
||||||
|
{
|
||||||
|
switch (shape.ShapeType)
|
||||||
|
{
|
||||||
|
case ShapeTypeEnum.Line:
|
||||||
|
this._line = shape;
|
||||||
|
_line.IsDrawLineVirtualRect = true;
|
||||||
|
var pts = this._line.Points;
|
||||||
|
|
||||||
|
_lineX1 = pts[0].X;
|
||||||
|
_lineY1 = pts[0].Y;
|
||||||
|
_lineX2 = pts[1].X;
|
||||||
|
_lineY2 = pts[1].Y;
|
||||||
|
_lineWidth = shape.LineVirtualRectWidth;
|
||||||
|
_rectPoints = shape.LineVirtualRectPoints;
|
||||||
|
//_LineLX = (shape.LineVirtualRectPoints[0].X + shape.LineVirtualRectPoints[3].X) / 2;
|
||||||
|
//_LineLY = (shape.LineVirtualRectPoints[0].Y + shape.LineVirtualRectPoints[3].Y) / 2;
|
||||||
|
//_LineRX = (shape.LineVirtualRectPoints[1].X + shape.LineVirtualRectPoints[2].X) / 2;
|
||||||
|
//_LineRY = (shape.LineVirtualRectPoints[1].Y + shape.LineVirtualRectPoints[2].Y) / 2;
|
||||||
|
|
||||||
|
tbLineX1.Text = _lineX1.ToString("F3");
|
||||||
|
tbLineY1.Text = _lineY1.ToString("F3");
|
||||||
|
tbLineX2.Text = _lineX2.ToString("F3");
|
||||||
|
tbLineY2.Text = _lineY2.ToString("F3");
|
||||||
|
// NumRectWidth1.Value = (decimal)_lineWidth;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private void GuideLineCircleCtrl_Load(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private void Canvas_mouseMoved(PointF pos)
|
||||||
|
{
|
||||||
|
if (InvokeRequired)
|
||||||
|
{
|
||||||
|
Invoke(Canvas_mouseMoved, pos);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
lblStatus.Text = $"X:{pos.X}, Y:{pos.Y}";
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private void Canvas_selectionChanged(List<FlyShape> shapes)
|
||||||
|
{
|
||||||
|
//if (shapes.Count != 1)
|
||||||
|
//{
|
||||||
|
// // panelGuide.Controls.Clear();
|
||||||
|
// return;
|
||||||
|
//}
|
||||||
|
//SwitchGuideForm(shapes[0].ShapeType);
|
||||||
|
// Canvas_OnShapeUpdateEvent(shapes[0]);
|
||||||
|
|
||||||
|
if (shapes.Count != 1)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
UpdateShape(shapes[0]);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private void Canvas_OnShapeMoving(List<FlyShape> shapes)
|
||||||
|
{
|
||||||
|
if (shapes.Count != 1)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
UpdateShape(shapes[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private void btnCreateLine_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
if (this.canvas.pixmap == null)
|
||||||
|
{
|
||||||
|
MessageBox.Show("请先打开图片");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
tbLineX1.Text = string.Empty;
|
||||||
|
tbLineY1.Text = string.Empty;
|
||||||
|
tbLineX2.Text = string.Empty;
|
||||||
|
tbLineY2.Text = string.Empty;
|
||||||
|
|
||||||
|
|
||||||
|
this.canvas.Shapes.RemoveAll(shp => shp.ShapeType == ShapeTypeEnum.Line);
|
||||||
|
this.canvas.Invalidate();
|
||||||
|
this.canvas.StartDraw(ShapeTypeEnum.Line);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private void btnLoadImage_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
OpenImageFile(bitmap =>
|
||||||
|
{
|
||||||
|
this.canvas.LoadPixmap(bitmap);
|
||||||
|
this.canvas.Enabled = true;
|
||||||
|
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void Canvas_newShape()
|
||||||
|
{
|
||||||
|
this.canvas.StopDraw();
|
||||||
|
}
|
||||||
|
string strarrayX = string.Empty;
|
||||||
|
string strarrayY = string.Empty;
|
||||||
|
private void btnExecute_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
if (this.canvas.pixmap == null)
|
||||||
|
{
|
||||||
|
MessageBox.Show("请先打开图片");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (this.tbLineX1.Text.Trim().Length == 0)
|
||||||
|
{
|
||||||
|
MessageBox.Show("请先创建直线");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.canvas.OutsideShapes.Clear();
|
||||||
|
this.canvas.Invalidate();
|
||||||
|
|
||||||
|
|
||||||
|
flag = new List<double>();
|
||||||
|
RowBegin = new List<double>();
|
||||||
|
ColBegin = new List<double>();
|
||||||
|
RowEnd = new List<double>();
|
||||||
|
ColEnd = new List<double>();
|
||||||
|
Dictionary<string, HObject> inputImg = new Dictionary<string, HObject>();
|
||||||
|
|
||||||
|
if (hImage == null)
|
||||||
|
{
|
||||||
|
HOperatorSet.ReadImage(out hImage, CurrentImageFile);
|
||||||
|
}
|
||||||
|
inputImg["INPUT_Image"] = hImage;
|
||||||
|
// 创建一维数组
|
||||||
|
|
||||||
|
Dictionary<string, HTuple> inputPara = new Dictionary<string, HTuple>();
|
||||||
|
|
||||||
|
// 获取矩形的 4 个点
|
||||||
|
PointF[] Points = this._line.LineVirtualRectPoints;
|
||||||
|
PointF Point1 = Points[0];
|
||||||
|
PointF Point2 = Points[1];
|
||||||
|
PointF Point3 = Points[2];
|
||||||
|
PointF Point4 = Points[3];
|
||||||
|
PointF Point5 = Points[0];
|
||||||
|
|
||||||
|
float x1 = Point1.X;
|
||||||
|
float y1 = Point1.Y;
|
||||||
|
|
||||||
|
float x2 = Point2.X;
|
||||||
|
float y2 = Point2.Y;
|
||||||
|
|
||||||
|
float x3 = Point3.X;
|
||||||
|
float y3 = Point3.Y;
|
||||||
|
|
||||||
|
float x4 = Point4.X;
|
||||||
|
float y4 = Point4.Y;
|
||||||
|
|
||||||
|
float x5 = Point5.X;
|
||||||
|
float y5 = Point5.Y;
|
||||||
|
|
||||||
|
|
||||||
|
float[] arrayX = new float[] { x1, x2, x3, x4, x5 };
|
||||||
|
HTuple hTupleArrayX = new HTuple(arrayX);
|
||||||
|
|
||||||
|
float[] arrayY = new float[] { y1, y2, y3, y4, y5 };
|
||||||
|
HTuple hTupleArrayY = new HTuple(arrayY);
|
||||||
|
|
||||||
|
strarrayX = string.Join(",", arrayX);
|
||||||
|
strarrayY = string.Join(",", arrayY);
|
||||||
|
|
||||||
|
inputPara["LX"] = _lineX1;
|
||||||
|
inputPara["LY"] = _lineY1;
|
||||||
|
inputPara["RX"] = _lineX2;
|
||||||
|
inputPara["RY"] = _lineY2;
|
||||||
|
inputPara["XRect"] = hTupleArrayX;
|
||||||
|
inputPara["YRect"] = hTupleArrayY;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
List<string> outputKeys = new List<string>()
|
||||||
|
{
|
||||||
|
"OUTPUT_Flag",
|
||||||
|
"RowBegin",
|
||||||
|
"ColBegin",
|
||||||
|
"RowEnd",
|
||||||
|
"ColEnd"
|
||||||
|
};
|
||||||
|
|
||||||
|
ExecuteHScript(
|
||||||
|
inputImg,
|
||||||
|
inputPara,
|
||||||
|
outputKeys);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
List<double> flag = new List<double>();
|
||||||
|
List<double> RowBegin = new List<double>();
|
||||||
|
List<double> ColBegin = new List<double>();
|
||||||
|
List<double> RowEnd = new List<double>();
|
||||||
|
List<double> ColEnd = new List<double>();
|
||||||
|
|
||||||
|
|
||||||
|
protected override void OnExecuteHScriptResult(
|
||||||
|
bool success,
|
||||||
|
Dictionary<string, HTuple> resultDic,
|
||||||
|
int timeElasped)
|
||||||
|
{
|
||||||
|
if (!success)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
"OUTPUT_Flag",
|
||||||
|
"RXCenter",
|
||||||
|
"RYCenter",
|
||||||
|
"RRadius"
|
||||||
|
*/
|
||||||
|
|
||||||
|
flag = resultDic["OUTPUT_Flag"].HTupleToDouble();
|
||||||
|
RowBegin = resultDic["RowBegin"].HTupleToDouble();
|
||||||
|
ColBegin = resultDic["ColBegin"].HTupleToDouble();
|
||||||
|
RowEnd = resultDic["RowEnd"].HTupleToDouble();
|
||||||
|
ColEnd = resultDic["ColEnd"].HTupleToDouble();
|
||||||
|
if (flag.Count > 0)
|
||||||
|
{
|
||||||
|
lblResult.Text = flag[0].ToString();
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
lblResult.Text = "无";
|
||||||
|
}
|
||||||
|
if (flag.Count > 0 && RowBegin.Count > 0 && ColBegin.Count > 0 && RowEnd.Count > 0 && ColEnd.Count > 0)
|
||||||
|
{
|
||||||
|
float width = 0;
|
||||||
|
this.canvas.DrawLine(new PointF((float)ColBegin[0], (float)RowBegin[0]), new PointF((float)ColEnd[0], (float)RowEnd[0]), width);
|
||||||
|
this.canvas.Invalidate();
|
||||||
|
lblElapsed.Text = $"{timeElasped} ms";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void NumRectWidth1_ValueChanged(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
if (_line != null)
|
||||||
|
{
|
||||||
|
//_line1.IsDrawLineVirtualRect = true;
|
||||||
|
_line.LineVirtualRectWidth = (float)NumRectWidth1.Value;
|
||||||
|
UpdateShape(_line);
|
||||||
|
this.canvas.Invalidate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void btnSave_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
if (lblResult.Text.Equals("无"))
|
||||||
|
{
|
||||||
|
MessageBox.Show("请先进行绘制");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (lblResult.Text != "0")
|
||||||
|
{
|
||||||
|
MessageBox.Show("测量计算错误,无法保存");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
//flag = resultDic["OUTPUT_Flag"].HTupleToDouble();
|
||||||
|
//RowBegin = resultDic["RowBegin"].HTupleToDouble();
|
||||||
|
//ColBegin = resultDic["ColBegin"].HTupleToDouble();
|
||||||
|
//RowEnd = resultDic["RowEnd"].HTupleToDouble();
|
||||||
|
//ColEnd = resultDic["ColEnd"].HTupleToDouble();
|
||||||
|
|
||||||
|
|
||||||
|
string input = $"LX:{_lineX1};" +
|
||||||
|
$"LY:{_lineY1};" +
|
||||||
|
$"RX:{_lineX2};" +
|
||||||
|
$"RY:{_lineY2};" +
|
||||||
|
$"Line_XRect:{strarrayX};" +
|
||||||
|
$"Line_YRect:{strarrayY}";
|
||||||
|
|
||||||
|
|
||||||
|
string result = $"RowBegin:{string.Join(";", RowBegin[0])};ColBegin:{string.Join(";", ColBegin[0])};RowEnd:{string.Join(";", RowEnd[0])};ColEnd:{string.Join(";", ColEnd[0])}";
|
||||||
|
|
||||||
|
DataToTriggerEvent(input, result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
145
CanFly/UI/GuidePanel/GuideLineCtrl.resx
Normal file
145
CanFly/UI/GuidePanel/GuideLineCtrl.resx
Normal file
@@ -0,0 +1,145 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<root>
|
||||||
|
<!--
|
||||||
|
Microsoft ResX Schema
|
||||||
|
|
||||||
|
Version 2.0
|
||||||
|
|
||||||
|
The primary goals of this format is to allow a simple XML format
|
||||||
|
that is mostly human readable. The generation and parsing of the
|
||||||
|
various data types are done through the TypeConverter classes
|
||||||
|
associated with the data types.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
... ado.net/XML headers & schema ...
|
||||||
|
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||||
|
<resheader name="version">2.0</resheader>
|
||||||
|
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||||
|
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||||
|
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||||
|
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||||
|
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||||
|
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||||
|
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||||
|
<comment>This is a comment</comment>
|
||||||
|
</data>
|
||||||
|
|
||||||
|
There are any number of "resheader" rows that contain simple
|
||||||
|
name/value pairs.
|
||||||
|
|
||||||
|
Each data row contains a name, and value. The row also contains a
|
||||||
|
type or mimetype. Type corresponds to a .NET class that support
|
||||||
|
text/value conversion through the TypeConverter architecture.
|
||||||
|
Classes that don't support this are serialized and stored with the
|
||||||
|
mimetype set.
|
||||||
|
|
||||||
|
The mimetype is used for serialized objects, and tells the
|
||||||
|
ResXResourceReader how to depersist the object. This is currently not
|
||||||
|
extensible. For a given mimetype the value must be set accordingly:
|
||||||
|
|
||||||
|
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||||
|
that the ResXResourceWriter will generate, however the reader can
|
||||||
|
read any of the formats listed below.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.binary.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.soap.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||||
|
value : The object must be serialized into a byte array
|
||||||
|
: using a System.ComponentModel.TypeConverter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
-->
|
||||||
|
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||||
|
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||||
|
<xsd:element name="root" msdata:IsDataSet="true">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:choice maxOccurs="unbounded">
|
||||||
|
<xsd:element name="metadata">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="assembly">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:attribute name="alias" type="xsd:string" />
|
||||||
|
<xsd:attribute name="name" type="xsd:string" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="data">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="resheader">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:choice>
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:schema>
|
||||||
|
<resheader name="resmimetype">
|
||||||
|
<value>text/microsoft-resx</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="version">
|
||||||
|
<value>2.0</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="reader">
|
||||||
|
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="writer">
|
||||||
|
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
<data name="canvas.OutsideShapes" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||||
|
<value>
|
||||||
|
AAEAAAD/////AQAAAAAAAAAMAgAAAERDYW5GbHkuQ2FudmFzLCBWZXJzaW9uPTEuMC4wLjAsIEN1bHR1
|
||||||
|
cmU9bmV1dHJhbCwgUHVibGljS2V5VG9rZW49bnVsbAQBAAAAdlN5c3RlbS5Db2xsZWN0aW9ucy5HZW5l
|
||||||
|
cmljLkxpc3RgMVtbQ2FuRmx5LkNhbnZhcy5TaGFwZS5GbHlTaGFwZSwgQ2FuRmx5LkNhbnZhcywgQ3Vs
|
||||||
|
dHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1udWxsXV0DAAAABl9pdGVtcwVfc2l6ZQhfdmVyc2lv
|
||||||
|
bgQAAB5DYW5GbHkuQ2FudmFzLlNoYXBlLkZseVNoYXBlW10CAAAACAgJAwAAAAAAAAAAAAAADAQAAAAz
|
||||||
|
Q2FuRmx5LkNhbnZhcywgQ3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1udWxsBwMAAAAAAQAA
|
||||||
|
AAAAAAAEHENhbkZseS5DYW52YXMuU2hhcGUuRmx5U2hhcGUEAAAACw==
|
||||||
|
</value>
|
||||||
|
</data>
|
||||||
|
<data name="canvas.Shapes" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||||
|
<value>
|
||||||
|
AAEAAAD/////AQAAAAAAAAAMAgAAAERDYW5GbHkuQ2FudmFzLCBWZXJzaW9uPTEuMC4wLjAsIEN1bHR1
|
||||||
|
cmU9bmV1dHJhbCwgUHVibGljS2V5VG9rZW49bnVsbAQBAAAAdlN5c3RlbS5Db2xsZWN0aW9ucy5HZW5l
|
||||||
|
cmljLkxpc3RgMVtbQ2FuRmx5LkNhbnZhcy5TaGFwZS5GbHlTaGFwZSwgQ2FuRmx5LkNhbnZhcywgQ3Vs
|
||||||
|
dHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1udWxsXV0DAAAABl9pdGVtcwVfc2l6ZQhfdmVyc2lv
|
||||||
|
bgQAAB5DYW5GbHkuQ2FudmFzLlNoYXBlLkZseVNoYXBlW10CAAAACAgJAwAAAAAAAAAAAAAADAQAAAAz
|
||||||
|
Q2FuRmx5LkNhbnZhcywgQ3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1udWxsBwMAAAAAAQAA
|
||||||
|
AAAAAAAEHENhbkZseS5DYW52YXMuU2hhcGUuRmx5U2hhcGUEAAAACw==
|
||||||
|
</value>
|
||||||
|
</data>
|
||||||
|
<metadata name="statusStrip1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||||
|
<value>17, 17</value>
|
||||||
|
</metadata>
|
||||||
|
</root>
|
||||||
570
CanFly/UI/GuidePanel/GuideLineLineCtrl.Designer.cs
generated
Normal file
570
CanFly/UI/GuidePanel/GuideLineLineCtrl.Designer.cs
generated
Normal file
@@ -0,0 +1,570 @@
|
|||||||
|
namespace CanFly.UI.GuidePanel
|
||||||
|
{
|
||||||
|
partial class GuideLineLineCtrl
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Required designer variable.
|
||||||
|
/// </summary>
|
||||||
|
private System.ComponentModel.IContainer components = null;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Clean up any resources being used.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||||
|
protected override void Dispose(bool disposing)
|
||||||
|
{
|
||||||
|
if (disposing && (components != null))
|
||||||
|
{
|
||||||
|
components.Dispose();
|
||||||
|
}
|
||||||
|
base.Dispose(disposing);
|
||||||
|
}
|
||||||
|
|
||||||
|
#region Windows Form Designer generated code
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Required method for Designer support - do not modify
|
||||||
|
/// the contents of this method with the code editor.
|
||||||
|
/// </summary>
|
||||||
|
private void InitializeComponent()
|
||||||
|
{
|
||||||
|
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(GuideLineLineCtrl));
|
||||||
|
lblStatus = new ToolStripStatusLabel();
|
||||||
|
panel1 = new Panel();
|
||||||
|
canvas = new Canvas.UI.FlyCanvas();
|
||||||
|
statusStrip1 = new StatusStrip();
|
||||||
|
ctrlTitleBar = new CtrlTitleBar();
|
||||||
|
tbLine1X2 = new TextBox();
|
||||||
|
label8 = new Label();
|
||||||
|
tbLine1Y2 = new TextBox();
|
||||||
|
label5 = new Label();
|
||||||
|
label10 = new Label();
|
||||||
|
tbLine1X1 = new TextBox();
|
||||||
|
tbLine1Y1 = new TextBox();
|
||||||
|
label6 = new Label();
|
||||||
|
label7 = new Label();
|
||||||
|
btnLoadImage = new Button();
|
||||||
|
label9 = new Label();
|
||||||
|
btnExecute = new Button();
|
||||||
|
panelGuide = new Panel();
|
||||||
|
lblDistance = new Label();
|
||||||
|
label17 = new Label();
|
||||||
|
lblResult = new Label();
|
||||||
|
label15 = new Label();
|
||||||
|
groupBox3 = new GroupBox();
|
||||||
|
NumRectWidth2 = new NumericUpDown();
|
||||||
|
label2 = new Label();
|
||||||
|
tbLine2X2 = new TextBox();
|
||||||
|
label11 = new Label();
|
||||||
|
tbLine2Y2 = new TextBox();
|
||||||
|
label12 = new Label();
|
||||||
|
tbLine2X1 = new TextBox();
|
||||||
|
tbLine2Y1 = new TextBox();
|
||||||
|
label13 = new Label();
|
||||||
|
label14 = new Label();
|
||||||
|
groupBox2 = new GroupBox();
|
||||||
|
NumRectWidth1 = new NumericUpDown();
|
||||||
|
label1 = new Label();
|
||||||
|
splitContainer = new SplitContainer();
|
||||||
|
lblElapsed = new Label();
|
||||||
|
label4 = new Label();
|
||||||
|
btnSave = new Button();
|
||||||
|
panel1.SuspendLayout();
|
||||||
|
statusStrip1.SuspendLayout();
|
||||||
|
panelGuide.SuspendLayout();
|
||||||
|
groupBox3.SuspendLayout();
|
||||||
|
((System.ComponentModel.ISupportInitialize)NumRectWidth2).BeginInit();
|
||||||
|
groupBox2.SuspendLayout();
|
||||||
|
((System.ComponentModel.ISupportInitialize)NumRectWidth1).BeginInit();
|
||||||
|
((System.ComponentModel.ISupportInitialize)splitContainer).BeginInit();
|
||||||
|
splitContainer.Panel1.SuspendLayout();
|
||||||
|
splitContainer.Panel2.SuspendLayout();
|
||||||
|
splitContainer.SuspendLayout();
|
||||||
|
SuspendLayout();
|
||||||
|
//
|
||||||
|
// lblStatus
|
||||||
|
//
|
||||||
|
lblStatus.Name = "lblStatus";
|
||||||
|
lblStatus.Size = new Size(44, 17);
|
||||||
|
lblStatus.Text = " ";
|
||||||
|
//
|
||||||
|
// panel1
|
||||||
|
//
|
||||||
|
panel1.BorderStyle = BorderStyle.FixedSingle;
|
||||||
|
panel1.Controls.Add(canvas);
|
||||||
|
panel1.Controls.Add(statusStrip1);
|
||||||
|
panel1.Dock = DockStyle.Fill;
|
||||||
|
panel1.Location = new Point(0, 0);
|
||||||
|
panel1.Name = "panel1";
|
||||||
|
panel1.Size = new Size(1076, 640);
|
||||||
|
panel1.TabIndex = 1;
|
||||||
|
//
|
||||||
|
// canvas
|
||||||
|
//
|
||||||
|
canvas.AllowMultiSelect = false;
|
||||||
|
canvas.CreateMode = Canvas.Shape.ShapeTypeEnum.Polygon;
|
||||||
|
canvas.Dock = DockStyle.Fill;
|
||||||
|
canvas.Enabled = false;
|
||||||
|
canvas.FillDrawing = false;
|
||||||
|
canvas.Location = new Point(0, 0);
|
||||||
|
canvas.Margin = new Padding(2);
|
||||||
|
canvas.Name = "canvas";
|
||||||
|
canvas.OutsideShapes = (List<Canvas.Shape.FlyShape>)resources.GetObject("canvas.OutsideShapes");
|
||||||
|
canvas.Scale = 1F;
|
||||||
|
canvas.Shapes = (List<Canvas.Shape.FlyShape>)resources.GetObject("canvas.Shapes");
|
||||||
|
canvas.Size = new Size(1074, 616);
|
||||||
|
canvas.TabIndex = 2;
|
||||||
|
//
|
||||||
|
// statusStrip1
|
||||||
|
//
|
||||||
|
statusStrip1.Items.AddRange(new ToolStripItem[] { lblStatus });
|
||||||
|
statusStrip1.Location = new Point(0, 616);
|
||||||
|
statusStrip1.Name = "statusStrip1";
|
||||||
|
statusStrip1.Size = new Size(1074, 22);
|
||||||
|
statusStrip1.TabIndex = 1;
|
||||||
|
statusStrip1.Text = "statusStrip1";
|
||||||
|
//
|
||||||
|
// ctrlTitleBar
|
||||||
|
//
|
||||||
|
ctrlTitleBar.Dock = DockStyle.Top;
|
||||||
|
ctrlTitleBar.Location = new Point(0, 0);
|
||||||
|
ctrlTitleBar.MinimumSize = new Size(0, 36);
|
||||||
|
ctrlTitleBar.Name = "ctrlTitleBar";
|
||||||
|
ctrlTitleBar.Padding = new Padding(3);
|
||||||
|
ctrlTitleBar.Size = new Size(198, 36);
|
||||||
|
ctrlTitleBar.TabIndex = 11;
|
||||||
|
ctrlTitleBar.Title = "线线测量";
|
||||||
|
//
|
||||||
|
// tbLine1X2
|
||||||
|
//
|
||||||
|
tbLine1X2.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
|
||||||
|
tbLine1X2.Location = new Point(56, 80);
|
||||||
|
tbLine1X2.Name = "tbLine1X2";
|
||||||
|
tbLine1X2.Size = new Size(134, 23);
|
||||||
|
tbLine1X2.TabIndex = 9;
|
||||||
|
//
|
||||||
|
// label8
|
||||||
|
//
|
||||||
|
label8.AutoSize = true;
|
||||||
|
label8.Location = new Point(6, 83);
|
||||||
|
label8.Name = "label8";
|
||||||
|
label8.Size = new Size(26, 17);
|
||||||
|
label8.TabIndex = 8;
|
||||||
|
label8.Text = "X2:";
|
||||||
|
//
|
||||||
|
// tbLine1Y2
|
||||||
|
//
|
||||||
|
tbLine1Y2.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
|
||||||
|
tbLine1Y2.Location = new Point(56, 109);
|
||||||
|
tbLine1Y2.Name = "tbLine1Y2";
|
||||||
|
tbLine1Y2.Size = new Size(134, 23);
|
||||||
|
tbLine1Y2.TabIndex = 7;
|
||||||
|
//
|
||||||
|
// label5
|
||||||
|
//
|
||||||
|
label5.AutoSize = true;
|
||||||
|
label5.Location = new Point(6, 112);
|
||||||
|
label5.Name = "label5";
|
||||||
|
label5.Size = new Size(25, 17);
|
||||||
|
label5.TabIndex = 6;
|
||||||
|
label5.Text = "Y2:";
|
||||||
|
//
|
||||||
|
// label10
|
||||||
|
//
|
||||||
|
label10.AutoSize = true;
|
||||||
|
label10.Location = new Point(6, 521);
|
||||||
|
label10.Name = "label10";
|
||||||
|
label10.Size = new Size(44, 17);
|
||||||
|
label10.TabIndex = 16;
|
||||||
|
label10.Text = "耗时:";
|
||||||
|
//
|
||||||
|
// tbLine1X1
|
||||||
|
//
|
||||||
|
tbLine1X1.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
|
||||||
|
tbLine1X1.Location = new Point(56, 22);
|
||||||
|
tbLine1X1.Name = "tbLine1X1";
|
||||||
|
tbLine1X1.Size = new Size(134, 23);
|
||||||
|
tbLine1X1.TabIndex = 5;
|
||||||
|
//
|
||||||
|
// tbLine1Y1
|
||||||
|
//
|
||||||
|
tbLine1Y1.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
|
||||||
|
tbLine1Y1.Location = new Point(56, 51);
|
||||||
|
tbLine1Y1.Name = "tbLine1Y1";
|
||||||
|
tbLine1Y1.Size = new Size(134, 23);
|
||||||
|
tbLine1Y1.TabIndex = 4;
|
||||||
|
//
|
||||||
|
// label6
|
||||||
|
//
|
||||||
|
label6.AutoSize = true;
|
||||||
|
label6.Location = new Point(6, 54);
|
||||||
|
label6.Name = "label6";
|
||||||
|
label6.Size = new Size(25, 17);
|
||||||
|
label6.TabIndex = 1;
|
||||||
|
label6.Text = "Y1:";
|
||||||
|
//
|
||||||
|
// label7
|
||||||
|
//
|
||||||
|
label7.AutoSize = true;
|
||||||
|
label7.Location = new Point(6, 25);
|
||||||
|
label7.Name = "label7";
|
||||||
|
label7.Size = new Size(26, 17);
|
||||||
|
label7.TabIndex = 0;
|
||||||
|
label7.Text = "X1:";
|
||||||
|
//
|
||||||
|
// btnLoadImage
|
||||||
|
//
|
||||||
|
btnLoadImage.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
|
||||||
|
btnLoadImage.Location = new Point(6, 394);
|
||||||
|
btnLoadImage.Name = "btnLoadImage";
|
||||||
|
btnLoadImage.Size = new Size(184, 32);
|
||||||
|
btnLoadImage.TabIndex = 18;
|
||||||
|
btnLoadImage.Text = "打开图片";
|
||||||
|
btnLoadImage.UseVisualStyleBackColor = true;
|
||||||
|
btnLoadImage.Click += btnLoadImage_Click;
|
||||||
|
//
|
||||||
|
// label9
|
||||||
|
//
|
||||||
|
label9.AutoSize = true;
|
||||||
|
label9.Location = new Point(54, 521);
|
||||||
|
label9.Name = "label9";
|
||||||
|
label9.Size = new Size(32, 17);
|
||||||
|
label9.TabIndex = 17;
|
||||||
|
label9.Text = "0ms";
|
||||||
|
//
|
||||||
|
// btnExecute
|
||||||
|
//
|
||||||
|
btnExecute.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
|
||||||
|
btnExecute.Location = new Point(5, 432);
|
||||||
|
btnExecute.Name = "btnExecute";
|
||||||
|
btnExecute.Size = new Size(184, 32);
|
||||||
|
btnExecute.TabIndex = 15;
|
||||||
|
btnExecute.Text = "执行";
|
||||||
|
btnExecute.UseVisualStyleBackColor = true;
|
||||||
|
btnExecute.Click += btnExecute_Click;
|
||||||
|
//
|
||||||
|
// panelGuide
|
||||||
|
//
|
||||||
|
panelGuide.BorderStyle = BorderStyle.FixedSingle;
|
||||||
|
panelGuide.Controls.Add(btnSave);
|
||||||
|
panelGuide.Controls.Add(lblDistance);
|
||||||
|
panelGuide.Controls.Add(label17);
|
||||||
|
panelGuide.Controls.Add(lblResult);
|
||||||
|
panelGuide.Controls.Add(label15);
|
||||||
|
panelGuide.Controls.Add(groupBox3);
|
||||||
|
panelGuide.Controls.Add(btnLoadImage);
|
||||||
|
panelGuide.Controls.Add(label9);
|
||||||
|
panelGuide.Controls.Add(btnExecute);
|
||||||
|
panelGuide.Controls.Add(label10);
|
||||||
|
panelGuide.Controls.Add(groupBox2);
|
||||||
|
panelGuide.Controls.Add(ctrlTitleBar);
|
||||||
|
panelGuide.Dock = DockStyle.Fill;
|
||||||
|
panelGuide.Location = new Point(0, 0);
|
||||||
|
panelGuide.Name = "panelGuide";
|
||||||
|
panelGuide.Size = new Size(200, 640);
|
||||||
|
panelGuide.TabIndex = 0;
|
||||||
|
//
|
||||||
|
// lblDistance
|
||||||
|
//
|
||||||
|
lblDistance.AutoSize = true;
|
||||||
|
lblDistance.Location = new Point(54, 493);
|
||||||
|
lblDistance.Name = "lblDistance";
|
||||||
|
lblDistance.Size = new Size(15, 17);
|
||||||
|
lblDistance.TabIndex = 25;
|
||||||
|
lblDistance.Text = "0";
|
||||||
|
//
|
||||||
|
// label17
|
||||||
|
//
|
||||||
|
label17.AutoSize = true;
|
||||||
|
label17.Location = new Point(6, 493);
|
||||||
|
label17.Name = "label17";
|
||||||
|
label17.Size = new Size(44, 17);
|
||||||
|
label17.TabIndex = 24;
|
||||||
|
label17.Text = "距离:";
|
||||||
|
//
|
||||||
|
// lblResult
|
||||||
|
//
|
||||||
|
lblResult.AutoSize = true;
|
||||||
|
lblResult.Location = new Point(54, 467);
|
||||||
|
lblResult.Name = "lblResult";
|
||||||
|
lblResult.Size = new Size(20, 17);
|
||||||
|
lblResult.TabIndex = 23;
|
||||||
|
lblResult.Text = "无";
|
||||||
|
//
|
||||||
|
// label15
|
||||||
|
//
|
||||||
|
label15.AutoSize = true;
|
||||||
|
label15.Location = new Point(6, 467);
|
||||||
|
label15.Name = "label15";
|
||||||
|
label15.Size = new Size(44, 17);
|
||||||
|
label15.TabIndex = 22;
|
||||||
|
label15.Text = "结果:";
|
||||||
|
//
|
||||||
|
// groupBox3
|
||||||
|
//
|
||||||
|
groupBox3.Controls.Add(NumRectWidth2);
|
||||||
|
groupBox3.Controls.Add(label2);
|
||||||
|
groupBox3.Controls.Add(tbLine2X2);
|
||||||
|
groupBox3.Controls.Add(label11);
|
||||||
|
groupBox3.Controls.Add(tbLine2Y2);
|
||||||
|
groupBox3.Controls.Add(label12);
|
||||||
|
groupBox3.Controls.Add(tbLine2X1);
|
||||||
|
groupBox3.Controls.Add(tbLine2Y1);
|
||||||
|
groupBox3.Controls.Add(label13);
|
||||||
|
groupBox3.Controls.Add(label14);
|
||||||
|
groupBox3.Dock = DockStyle.Top;
|
||||||
|
groupBox3.Location = new Point(0, 216);
|
||||||
|
groupBox3.Name = "groupBox3";
|
||||||
|
groupBox3.Size = new Size(198, 172);
|
||||||
|
groupBox3.TabIndex = 21;
|
||||||
|
groupBox3.TabStop = false;
|
||||||
|
groupBox3.Text = "线2参数";
|
||||||
|
//
|
||||||
|
// NumRectWidth2
|
||||||
|
//
|
||||||
|
NumRectWidth2.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
|
||||||
|
NumRectWidth2.Location = new Point(53, 138);
|
||||||
|
NumRectWidth2.Maximum = new decimal(new int[] { 9000, 0, 0, 0 });
|
||||||
|
NumRectWidth2.Minimum = new decimal(new int[] { 1, 0, 0, 0 });
|
||||||
|
NumRectWidth2.Name = "NumRectWidth2";
|
||||||
|
NumRectWidth2.Size = new Size(136, 23);
|
||||||
|
NumRectWidth2.TabIndex = 13;
|
||||||
|
NumRectWidth2.Value = new decimal(new int[] { 1, 0, 0, 0 });
|
||||||
|
//
|
||||||
|
// label2
|
||||||
|
//
|
||||||
|
label2.AutoSize = true;
|
||||||
|
label2.Location = new Point(6, 140);
|
||||||
|
label2.Name = "label2";
|
||||||
|
label2.Size = new Size(35, 17);
|
||||||
|
label2.TabIndex = 12;
|
||||||
|
label2.Text = "宽度:";
|
||||||
|
//
|
||||||
|
// tbLine2X2
|
||||||
|
//
|
||||||
|
tbLine2X2.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
|
||||||
|
tbLine2X2.Location = new Point(56, 80);
|
||||||
|
tbLine2X2.Name = "tbLine2X2";
|
||||||
|
tbLine2X2.Size = new Size(134, 23);
|
||||||
|
tbLine2X2.TabIndex = 9;
|
||||||
|
//
|
||||||
|
// label11
|
||||||
|
//
|
||||||
|
label11.AutoSize = true;
|
||||||
|
label11.Location = new Point(6, 83);
|
||||||
|
label11.Name = "label11";
|
||||||
|
label11.Size = new Size(26, 17);
|
||||||
|
label11.TabIndex = 8;
|
||||||
|
label11.Text = "X2:";
|
||||||
|
//
|
||||||
|
// tbLine2Y2
|
||||||
|
//
|
||||||
|
tbLine2Y2.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
|
||||||
|
tbLine2Y2.Location = new Point(56, 109);
|
||||||
|
tbLine2Y2.Name = "tbLine2Y2";
|
||||||
|
tbLine2Y2.Size = new Size(136, 23);
|
||||||
|
tbLine2Y2.TabIndex = 7;
|
||||||
|
//
|
||||||
|
// label12
|
||||||
|
//
|
||||||
|
label12.AutoSize = true;
|
||||||
|
label12.Location = new Point(6, 112);
|
||||||
|
label12.Name = "label12";
|
||||||
|
label12.Size = new Size(25, 17);
|
||||||
|
label12.TabIndex = 6;
|
||||||
|
label12.Text = "Y2:";
|
||||||
|
//
|
||||||
|
// tbLine2X1
|
||||||
|
//
|
||||||
|
tbLine2X1.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
|
||||||
|
tbLine2X1.Location = new Point(56, 22);
|
||||||
|
tbLine2X1.Name = "tbLine2X1";
|
||||||
|
tbLine2X1.Size = new Size(134, 23);
|
||||||
|
tbLine2X1.TabIndex = 5;
|
||||||
|
//
|
||||||
|
// tbLine2Y1
|
||||||
|
//
|
||||||
|
tbLine2Y1.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
|
||||||
|
tbLine2Y1.Location = new Point(56, 51);
|
||||||
|
tbLine2Y1.Name = "tbLine2Y1";
|
||||||
|
tbLine2Y1.Size = new Size(134, 23);
|
||||||
|
tbLine2Y1.TabIndex = 4;
|
||||||
|
//
|
||||||
|
// label13
|
||||||
|
//
|
||||||
|
label13.AutoSize = true;
|
||||||
|
label13.Location = new Point(6, 54);
|
||||||
|
label13.Name = "label13";
|
||||||
|
label13.Size = new Size(25, 17);
|
||||||
|
label13.TabIndex = 1;
|
||||||
|
label13.Text = "Y1:";
|
||||||
|
//
|
||||||
|
// label14
|
||||||
|
//
|
||||||
|
label14.AutoSize = true;
|
||||||
|
label14.Location = new Point(6, 25);
|
||||||
|
label14.Name = "label14";
|
||||||
|
label14.Size = new Size(26, 17);
|
||||||
|
label14.TabIndex = 0;
|
||||||
|
label14.Text = "X1:";
|
||||||
|
//
|
||||||
|
// groupBox2
|
||||||
|
//
|
||||||
|
groupBox2.Controls.Add(NumRectWidth1);
|
||||||
|
groupBox2.Controls.Add(label1);
|
||||||
|
groupBox2.Controls.Add(tbLine1X2);
|
||||||
|
groupBox2.Controls.Add(label8);
|
||||||
|
groupBox2.Controls.Add(tbLine1Y2);
|
||||||
|
groupBox2.Controls.Add(label5);
|
||||||
|
groupBox2.Controls.Add(tbLine1X1);
|
||||||
|
groupBox2.Controls.Add(tbLine1Y1);
|
||||||
|
groupBox2.Controls.Add(label6);
|
||||||
|
groupBox2.Controls.Add(label7);
|
||||||
|
groupBox2.Dock = DockStyle.Top;
|
||||||
|
groupBox2.Location = new Point(0, 36);
|
||||||
|
groupBox2.Name = "groupBox2";
|
||||||
|
groupBox2.Size = new Size(198, 180);
|
||||||
|
groupBox2.TabIndex = 13;
|
||||||
|
groupBox2.TabStop = false;
|
||||||
|
groupBox2.Text = "线1参数";
|
||||||
|
//
|
||||||
|
// NumRectWidth1
|
||||||
|
//
|
||||||
|
NumRectWidth1.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
|
||||||
|
NumRectWidth1.Location = new Point(54, 138);
|
||||||
|
NumRectWidth1.Maximum = new decimal(new int[] { 9000, 0, 0, 0 });
|
||||||
|
NumRectWidth1.Minimum = new decimal(new int[] { 1, 0, 0, 0 });
|
||||||
|
NumRectWidth1.Name = "NumRectWidth1";
|
||||||
|
NumRectWidth1.Size = new Size(135, 23);
|
||||||
|
NumRectWidth1.TabIndex = 11;
|
||||||
|
NumRectWidth1.Value = new decimal(new int[] { 1, 0, 0, 0 });
|
||||||
|
//
|
||||||
|
// label1
|
||||||
|
//
|
||||||
|
label1.AutoSize = true;
|
||||||
|
label1.Location = new Point(6, 140);
|
||||||
|
label1.Name = "label1";
|
||||||
|
label1.Size = new Size(35, 17);
|
||||||
|
label1.TabIndex = 10;
|
||||||
|
label1.Text = "宽度:";
|
||||||
|
//
|
||||||
|
// splitContainer
|
||||||
|
//
|
||||||
|
splitContainer.Dock = DockStyle.Fill;
|
||||||
|
splitContainer.Location = new Point(0, 0);
|
||||||
|
splitContainer.Name = "splitContainer";
|
||||||
|
//
|
||||||
|
// splitContainer.Panel1
|
||||||
|
//
|
||||||
|
splitContainer.Panel1.Controls.Add(panelGuide);
|
||||||
|
splitContainer.Panel1MinSize = 150;
|
||||||
|
//
|
||||||
|
// splitContainer.Panel2
|
||||||
|
//
|
||||||
|
splitContainer.Panel2.Controls.Add(panel1);
|
||||||
|
splitContainer.Size = new Size(1280, 640);
|
||||||
|
splitContainer.SplitterDistance = 200;
|
||||||
|
splitContainer.TabIndex = 11;
|
||||||
|
//
|
||||||
|
// lblElapsed
|
||||||
|
//
|
||||||
|
lblElapsed.AutoSize = true;
|
||||||
|
lblElapsed.Location = new Point(50, 328);
|
||||||
|
lblElapsed.Name = "lblElapsed";
|
||||||
|
lblElapsed.Size = new Size(32, 17);
|
||||||
|
lblElapsed.TabIndex = 13;
|
||||||
|
lblElapsed.Text = "0ms";
|
||||||
|
//
|
||||||
|
// label4
|
||||||
|
//
|
||||||
|
label4.AutoSize = true;
|
||||||
|
label4.Location = new Point(0, 328);
|
||||||
|
label4.Name = "label4";
|
||||||
|
label4.Size = new Size(44, 17);
|
||||||
|
label4.TabIndex = 12;
|
||||||
|
label4.Text = "耗时:";
|
||||||
|
//
|
||||||
|
// btnSave
|
||||||
|
//
|
||||||
|
btnSave.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
|
||||||
|
btnSave.Location = new Point(3, 541);
|
||||||
|
btnSave.Name = "btnSave";
|
||||||
|
btnSave.Size = new Size(186, 32);
|
||||||
|
btnSave.TabIndex = 26;
|
||||||
|
btnSave.Text = "保存数据";
|
||||||
|
btnSave.UseVisualStyleBackColor = true;
|
||||||
|
btnSave.Click += btnSave_Click;
|
||||||
|
//
|
||||||
|
// GuideLineLineCtrl
|
||||||
|
//
|
||||||
|
AutoScaleDimensions = new SizeF(7F, 17F);
|
||||||
|
AutoScaleMode = AutoScaleMode.Font;
|
||||||
|
Controls.Add(splitContainer);
|
||||||
|
Controls.Add(lblElapsed);
|
||||||
|
Controls.Add(label4);
|
||||||
|
Name = "GuideLineLineCtrl";
|
||||||
|
Size = new Size(1280, 640);
|
||||||
|
panel1.ResumeLayout(false);
|
||||||
|
panel1.PerformLayout();
|
||||||
|
statusStrip1.ResumeLayout(false);
|
||||||
|
statusStrip1.PerformLayout();
|
||||||
|
panelGuide.ResumeLayout(false);
|
||||||
|
panelGuide.PerformLayout();
|
||||||
|
groupBox3.ResumeLayout(false);
|
||||||
|
groupBox3.PerformLayout();
|
||||||
|
((System.ComponentModel.ISupportInitialize)NumRectWidth2).EndInit();
|
||||||
|
groupBox2.ResumeLayout(false);
|
||||||
|
groupBox2.PerformLayout();
|
||||||
|
((System.ComponentModel.ISupportInitialize)NumRectWidth1).EndInit();
|
||||||
|
splitContainer.Panel1.ResumeLayout(false);
|
||||||
|
splitContainer.Panel2.ResumeLayout(false);
|
||||||
|
((System.ComponentModel.ISupportInitialize)splitContainer).EndInit();
|
||||||
|
splitContainer.ResumeLayout(false);
|
||||||
|
ResumeLayout(false);
|
||||||
|
PerformLayout();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
private ToolStripStatusLabel lblStatus;
|
||||||
|
private Panel panel1;
|
||||||
|
private Canvas.UI.FlyCanvas canvas;
|
||||||
|
private StatusStrip statusStrip1;
|
||||||
|
private CtrlTitleBar ctrlTitleBar;
|
||||||
|
private TextBox tbLine1X2;
|
||||||
|
private Label label8;
|
||||||
|
private TextBox tbLine1Y2;
|
||||||
|
private Label label5;
|
||||||
|
private Label label10;
|
||||||
|
private TextBox tbLine1X1;
|
||||||
|
private TextBox tbLine1Y1;
|
||||||
|
private Label label6;
|
||||||
|
private Label label7;
|
||||||
|
private Button btnLoadImage;
|
||||||
|
private Label label9;
|
||||||
|
private Button btnExecute;
|
||||||
|
private Panel panelGuide;
|
||||||
|
private GroupBox groupBox2;
|
||||||
|
private SplitContainer splitContainer;
|
||||||
|
private Label lblElapsed;
|
||||||
|
private Label label4;
|
||||||
|
private GroupBox groupBox3;
|
||||||
|
private TextBox tbLine2X2;
|
||||||
|
private Label label11;
|
||||||
|
private TextBox tbLine2Y2;
|
||||||
|
private Label label12;
|
||||||
|
private TextBox tbLine2X1;
|
||||||
|
private TextBox tbLine2Y1;
|
||||||
|
private Label label13;
|
||||||
|
private Label label14;
|
||||||
|
private Label label1;
|
||||||
|
private Label label2;
|
||||||
|
private NumericUpDown NumRectWidth2;
|
||||||
|
private NumericUpDown NumRectWidth1;
|
||||||
|
private Label lblDistance;
|
||||||
|
private Label label17;
|
||||||
|
private Label lblResult;
|
||||||
|
private Label label15;
|
||||||
|
private Button btnSave;
|
||||||
|
}
|
||||||
|
}
|
||||||
526
CanFly/UI/GuidePanel/GuideLineLineCtrl.cs
Normal file
526
CanFly/UI/GuidePanel/GuideLineLineCtrl.cs
Normal file
@@ -0,0 +1,526 @@
|
|||||||
|
using CanFly.Canvas.Helper;
|
||||||
|
using CanFly.Canvas.Shape;
|
||||||
|
using CanFly.Helper;
|
||||||
|
using HalconDotNet;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.ComponentModel;
|
||||||
|
using System.Data;
|
||||||
|
using System.Drawing;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Windows.Forms;
|
||||||
|
|
||||||
|
namespace CanFly.UI.GuidePanel
|
||||||
|
{
|
||||||
|
public partial class GuideLineLineCtrl : BaseGuideControl
|
||||||
|
{
|
||||||
|
private FlyShape? _line1;
|
||||||
|
private FlyShape? _line2;
|
||||||
|
|
||||||
|
private float _line1X1;
|
||||||
|
private float _line1Y1;
|
||||||
|
private float _line1X2;
|
||||||
|
private float _line1Y2;
|
||||||
|
private float _lineWidth;
|
||||||
|
|
||||||
|
private float _line2X1;
|
||||||
|
private float _line2Y1;
|
||||||
|
private float _line2X2;
|
||||||
|
private float _line2Y2;
|
||||||
|
private float _line2Width;
|
||||||
|
|
||||||
|
protected override string GetScriptFileName() => "LineToLine.hdvp";
|
||||||
|
|
||||||
|
|
||||||
|
public GuideLineLineCtrl()
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
this.canvas.mouseMoved += Canvas_mouseMoved;
|
||||||
|
this.canvas.OnShapeUpdateEvent += UpdateShape;
|
||||||
|
this.canvas.selectionChanged += Canvas_selectionChanged;
|
||||||
|
|
||||||
|
this.canvas.OnShapeMoving += Canvas_OnShapeMoving;
|
||||||
|
this.canvas.newShape += Canvas_newShape;
|
||||||
|
|
||||||
|
this.ctrlTitleBar.OnCloseClicked += OnControlClose;
|
||||||
|
NumRectWidth1.ValueChanged -= NumRectWidth1_ValueChanged;
|
||||||
|
NumRectWidth1.Value = 40;
|
||||||
|
NumRectWidth1.ValueChanged += NumRectWidth1_ValueChanged;
|
||||||
|
|
||||||
|
NumRectWidth2.ValueChanged -= NumericUpDown2_ValueChanged;
|
||||||
|
NumRectWidth2.Value = 40;
|
||||||
|
NumRectWidth2.ValueChanged += NumericUpDown2_ValueChanged;
|
||||||
|
|
||||||
|
}
|
||||||
|
protected override void UpdateShape(FlyShape shape)
|
||||||
|
{
|
||||||
|
switch (shape.ShapeType)
|
||||||
|
{
|
||||||
|
case ShapeTypeEnum.Line:
|
||||||
|
// 判断是否为第一条直线或第二条直线
|
||||||
|
if (_line1 == shape)
|
||||||
|
{
|
||||||
|
//_line1 = shape;
|
||||||
|
var pts1 = _line1.Points;
|
||||||
|
_line1X1 = pts1[0].X;
|
||||||
|
_line1Y1 = pts1[0].Y;
|
||||||
|
_line1X2 = pts1[1].X;
|
||||||
|
_line1Y2 = pts1[1].Y;
|
||||||
|
_lineWidth = _line1.LineVirtualRectWidth;
|
||||||
|
|
||||||
|
tbLine1X1.Text = _line1X1.ToString("F3");
|
||||||
|
tbLine1Y1.Text = _line1Y1.ToString("F3");
|
||||||
|
tbLine1X2.Text = _line1X2.ToString("F3");
|
||||||
|
tbLine1Y2.Text = _line1Y2.ToString("F3");
|
||||||
|
//NumRectWidth1.Value = (decimal)_lineWidth;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//_line2 = shape;
|
||||||
|
var pts2 = _line2.Points;
|
||||||
|
_line2X1 = pts2[0].X;
|
||||||
|
_line2Y1 = pts2[0].Y;
|
||||||
|
_line2X2 = pts2[1].X;
|
||||||
|
_line2Y2 = pts2[1].Y;
|
||||||
|
_line2Width = _line2.LineVirtualRectWidth;
|
||||||
|
|
||||||
|
tbLine2X1.Text = _line2X1.ToString("F3");
|
||||||
|
tbLine2Y1.Text = _line2Y1.ToString("F3");
|
||||||
|
tbLine2X2.Text = _line2X2.ToString("F3");
|
||||||
|
tbLine2Y2.Text = _line2Y2.ToString("F3");
|
||||||
|
// NumRectWidth2.Value = (decimal)_line2Width;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private void GuideLineCircleCtrl_Load(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private void Canvas_mouseMoved(PointF pos)
|
||||||
|
{
|
||||||
|
if (InvokeRequired)
|
||||||
|
{
|
||||||
|
Invoke(Canvas_mouseMoved, pos);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
lblStatus.Text = $"X:{pos.X}, Y:{pos.Y}";
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private void Canvas_selectionChanged(List<FlyShape> shapes)
|
||||||
|
{
|
||||||
|
//if (shapes.Count != 1)
|
||||||
|
//{
|
||||||
|
// // panelGuide.Controls.Clear();
|
||||||
|
// return;
|
||||||
|
//}
|
||||||
|
//SwitchGuideForm(shapes[0].ShapeType);
|
||||||
|
// Canvas_OnShapeUpdateEvent(shapes[0]);
|
||||||
|
|
||||||
|
if (shapes.Count != 1)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
UpdateShape(shapes[0]);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private void Canvas_OnShapeMoving(List<FlyShape> shapes)
|
||||||
|
{
|
||||||
|
if (shapes.Count != 1)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
UpdateShape(shapes[0]);
|
||||||
|
}
|
||||||
|
private void Canvas_newShape()
|
||||||
|
{
|
||||||
|
// 自动切换到下一条直线绘制
|
||||||
|
if (_line1 == null)
|
||||||
|
{
|
||||||
|
_line1 = this.canvas.Shapes.LastOrDefault(shp => shp.ShapeType == ShapeTypeEnum.Line);
|
||||||
|
}
|
||||||
|
else if (_line2 == null)
|
||||||
|
{
|
||||||
|
_line2 = this.canvas.Shapes.LastOrDefault(shp => shp.ShapeType == ShapeTypeEnum.Line);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 停止绘制模式,用户可以根据需要重新启用
|
||||||
|
this.canvas.StopDraw();
|
||||||
|
//this.canvas.StopDraw();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void btnCreateLineOne_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
// this.canvas.Shapes.RemoveAll(shp => shp == _line1); // 移除第一条直线
|
||||||
|
this._line1 = null;
|
||||||
|
this.canvas.Invalidate();
|
||||||
|
this.canvas.StartDraw(ShapeTypeEnum.Line); // 启动绘制模式
|
||||||
|
this.canvas.Enabled = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void btnCreateLineTwo_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
// this.canvas.Shapes.RemoveAll(shp => shp == _line2); // 移除第二条直线
|
||||||
|
this._line2 = null;
|
||||||
|
this.canvas.Invalidate();
|
||||||
|
this.canvas.StartDraw(ShapeTypeEnum.Line); // 启动绘制模式
|
||||||
|
this.canvas.Enabled = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void btnExecute_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
if (this.canvas.pixmap == null)
|
||||||
|
{
|
||||||
|
MessageBox.Show("请先打开图片");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.canvas.OutsideShapes.Clear();
|
||||||
|
this.canvas.Invalidate();
|
||||||
|
|
||||||
|
flag = new List<double>();
|
||||||
|
Distance = new List<double>();
|
||||||
|
Line1_RowBegin = new List<double>();
|
||||||
|
Line1_ColBegin = new List<double>();
|
||||||
|
Line1_RowEnd = new List<double>();
|
||||||
|
Line1_ColEnd = new List<double>();
|
||||||
|
Line2_RowBegin = new List<double>();
|
||||||
|
Line2_ColBegin = new List<double>();
|
||||||
|
Line2_RowEnd = new List<double>();
|
||||||
|
Line2_ColEnd = new List<double>();
|
||||||
|
Dictionary<string, HObject> inputImg = new Dictionary<string, HObject>();
|
||||||
|
|
||||||
|
if (hImage == null)
|
||||||
|
{
|
||||||
|
HOperatorSet.ReadImage(out hImage, CurrentImageFile);
|
||||||
|
}
|
||||||
|
inputImg["INPUT_Image"] = hImage;
|
||||||
|
|
||||||
|
Dictionary<string, HTuple> inputPara = new Dictionary<string, HTuple>();
|
||||||
|
|
||||||
|
|
||||||
|
// 获取矩形的 4 个点
|
||||||
|
PointF[] Points = this._line1.LineVirtualRectPoints;
|
||||||
|
if (Points.Count() < 4)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
PointF Point1 = Points[0];
|
||||||
|
PointF Point2 = Points[1];
|
||||||
|
PointF Point3 = Points[2];
|
||||||
|
PointF Point4 = Points[3];
|
||||||
|
PointF Point5 = Points[0];
|
||||||
|
|
||||||
|
float x1 = Point1.X;
|
||||||
|
float y1 = Point1.Y;
|
||||||
|
|
||||||
|
float x2 = Point2.X;
|
||||||
|
float y2 = Point2.Y;
|
||||||
|
|
||||||
|
float x3 = Point3.X;
|
||||||
|
float y3 = Point3.Y;
|
||||||
|
|
||||||
|
float x4 = Point4.X;
|
||||||
|
float y4 = Point4.Y;
|
||||||
|
|
||||||
|
float x5 = Point5.X;
|
||||||
|
float y5 = Point5.Y;
|
||||||
|
|
||||||
|
|
||||||
|
float[] array1X = new float[] { x1, x2, x3, x4, x5 };
|
||||||
|
HTuple hTupleArray1X = new HTuple(array1X);
|
||||||
|
|
||||||
|
float[] array1Y = new float[] { y1, y2, y3, y4, y5 };
|
||||||
|
HTuple hTupleArray1Y = new HTuple(array1Y);
|
||||||
|
|
||||||
|
|
||||||
|
strarray1X = string.Join(",", array1X);
|
||||||
|
strarray1Y = string.Join(",", array1Y);
|
||||||
|
|
||||||
|
|
||||||
|
// 获取矩形的 4 个点
|
||||||
|
PointF[] Points2 = this._line2.LineVirtualRectPoints;
|
||||||
|
if (Points2.Count() < 4)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
PointF Point21 = Points2[0];
|
||||||
|
PointF Point22 = Points2[1];
|
||||||
|
PointF Point23 = Points2[2];
|
||||||
|
PointF Point24 = Points2[3];
|
||||||
|
PointF Point25 = Points2[0];
|
||||||
|
|
||||||
|
float x21 = Point21.X;
|
||||||
|
float y21 = Point21.Y;
|
||||||
|
|
||||||
|
float x22 = Point22.X;
|
||||||
|
float y22 = Point22.Y;
|
||||||
|
|
||||||
|
float x23 = Point23.X;
|
||||||
|
float y23 = Point23.Y;
|
||||||
|
|
||||||
|
float x24 = Point24.X;
|
||||||
|
float y24 = Point24.Y;
|
||||||
|
|
||||||
|
float x25 = Point25.X;
|
||||||
|
float y25 = Point25.Y;
|
||||||
|
|
||||||
|
|
||||||
|
float[] array2X = new float[] { x21, x22, x23, x24, x25 };
|
||||||
|
HTuple hTupleArray2X = new HTuple(array2X);
|
||||||
|
|
||||||
|
float[] array2Y = new float[] { y21, y22, y23, y24, y25 };
|
||||||
|
HTuple hTupleArray2Y = new HTuple(array2Y);
|
||||||
|
|
||||||
|
|
||||||
|
strarray2X = string.Join(",", array2X);
|
||||||
|
strarray2Y = string.Join(",", array2Y);
|
||||||
|
|
||||||
|
inputPara["Line1_LX"] = _line1X1;
|
||||||
|
inputPara["Line1_LY"] = _line1Y1;
|
||||||
|
inputPara["Line1_RX"] = _line1X2;
|
||||||
|
inputPara["Line1_RY"] = _line1Y2;
|
||||||
|
|
||||||
|
inputPara["Line2_LX"] = _line2X1;
|
||||||
|
inputPara["Line2_LY"] = _line2Y1;
|
||||||
|
inputPara["Line2_RX"] = _line2X2;
|
||||||
|
inputPara["Line2_RY"] = _line2Y2;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
inputPara["Line1_XRect"] = hTupleArray1X;
|
||||||
|
inputPara["Line1_YRect"] = hTupleArray1Y;
|
||||||
|
|
||||||
|
inputPara["Line2_XRect"] = hTupleArray2X;
|
||||||
|
inputPara["Line2_YRect"] = hTupleArray2Y;
|
||||||
|
|
||||||
|
List<string> outputKeys = new List<string>()
|
||||||
|
{
|
||||||
|
"OUTPUT_Flag",
|
||||||
|
"Distance",
|
||||||
|
"Line1_RowBegin",
|
||||||
|
"Line1_ColBegin",
|
||||||
|
"Line1_RowEnd",
|
||||||
|
"Line1_ColEnd",
|
||||||
|
"Line2_RowBegin",
|
||||||
|
"Line2_ColBegin",
|
||||||
|
"Line2_RowEnd",
|
||||||
|
"Line2_ColEnd"
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
ExecuteHScript(
|
||||||
|
inputImg,
|
||||||
|
inputPara,
|
||||||
|
outputKeys);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void btnLoadImage_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
OpenImageFile(bitmap =>
|
||||||
|
{
|
||||||
|
this.canvas.LoadPixmap(bitmap);
|
||||||
|
this.canvas.Enabled = true;
|
||||||
|
_line1 = new FlyShape();
|
||||||
|
_line2 = new FlyShape();
|
||||||
|
_line1.AddPoint(new Point(10, 10));
|
||||||
|
_line1.AddPoint(new Point(50, 10));
|
||||||
|
_line2.AddPoint(new Point(10, 20));
|
||||||
|
_line2.AddPoint(new Point(60, 20));
|
||||||
|
_line1.ShapeType = ShapeTypeEnum.Line;
|
||||||
|
_line2.ShapeType = ShapeTypeEnum.Line;
|
||||||
|
|
||||||
|
_line1.IsDrawLineVirtualRect = true;
|
||||||
|
_line1.LineVirtualRectWidth = 40;
|
||||||
|
_line2.IsDrawLineVirtualRect = true;
|
||||||
|
_line2.LineVirtualRectWidth = 40;
|
||||||
|
|
||||||
|
canvas.Shapes.Add(_line1);
|
||||||
|
canvas.Shapes.Add(_line2);
|
||||||
|
canvas.Invalidate();
|
||||||
|
|
||||||
|
UpdateShape(_line1);
|
||||||
|
UpdateShape(_line2);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
string strarray1X = string.Empty;
|
||||||
|
string strarray1Y = string.Empty;
|
||||||
|
string strarray2X = string.Empty;
|
||||||
|
string strarray2Y = string.Empty;
|
||||||
|
List<double> flag =new List<double>();
|
||||||
|
List<double> Distance = new List<double>();
|
||||||
|
List<double> Line1_RowBegin = new List<double>();
|
||||||
|
List<double> Line1_ColBegin = new List<double>();
|
||||||
|
List<double> Line1_RowEnd = new List<double>();
|
||||||
|
List<double> Line1_ColEnd = new List<double>();
|
||||||
|
List<double> Line2_RowBegin = new List<double>();
|
||||||
|
List<double> Line2_ColBegin = new List<double>();
|
||||||
|
List<double> Line2_RowEnd = new List<double>();
|
||||||
|
List<double> Line2_ColEnd = new List<double>();
|
||||||
|
protected override void OnExecuteHScriptResult(
|
||||||
|
bool success,
|
||||||
|
Dictionary<string, HTuple> resultDic,
|
||||||
|
int timeElasped)
|
||||||
|
{
|
||||||
|
if (!success)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//"OUTPUT_Flag",
|
||||||
|
// "Distance",
|
||||||
|
// "Line1_RowBegin",
|
||||||
|
// "Line1_ColBegin",
|
||||||
|
// "Line1_RowEnd",
|
||||||
|
// "Line1_ColEnd",
|
||||||
|
// "Line2_RowBegin",
|
||||||
|
// "Line2_ColBegin",
|
||||||
|
// "Line2_RowEnd",
|
||||||
|
// "Line2_ColEnd"
|
||||||
|
|
||||||
|
|
||||||
|
flag = resultDic["OUTPUT_Flag"].HTupleToDouble();
|
||||||
|
Distance = resultDic["Distance"].HTupleToDouble();
|
||||||
|
Line1_RowBegin = resultDic["Line1_RowBegin"].HTupleToDouble();
|
||||||
|
Line1_ColBegin = resultDic["Line1_ColBegin"].HTupleToDouble();
|
||||||
|
Line1_RowEnd = resultDic["Line1_RowEnd"].HTupleToDouble();
|
||||||
|
Line1_ColEnd = resultDic["Line1_ColEnd"].HTupleToDouble();
|
||||||
|
Line2_RowBegin = resultDic["Line2_RowBegin"].HTupleToDouble();
|
||||||
|
Line2_ColBegin = resultDic["Line2_ColBegin"].HTupleToDouble();
|
||||||
|
Line2_RowEnd = resultDic["Line2_RowEnd"].HTupleToDouble();
|
||||||
|
Line2_ColEnd = resultDic["Line2_ColEnd"].HTupleToDouble();
|
||||||
|
|
||||||
|
if (flag.Count > 0)
|
||||||
|
{
|
||||||
|
lblResult.Text = flag[0].ToString();
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
lblResult.Text = "无";
|
||||||
|
}
|
||||||
|
if (Distance.Count > 0)
|
||||||
|
{
|
||||||
|
lblDistance.Text = Distance[0].ToString();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
lblDistance.Text = "0";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (flag.Count > 0 && Distance.Count > 0 && Line1_RowBegin.Count > 0 && Line1_ColBegin.Count > 0 && Line1_RowEnd.Count > 0 && Line1_ColEnd.Count > 0 && Line2_RowBegin.Count > 0 && Line2_ColBegin.Count > 0 && Line2_RowEnd.Count > 0 && Line2_ColEnd.Count > 0)
|
||||||
|
{
|
||||||
|
float width = 0;
|
||||||
|
this.canvas.DrawLine(new PointF((float)Line1_ColBegin[0], (float)Line1_RowBegin[0]), new PointF((float)Line1_ColEnd[0], (float)Line1_RowEnd[0]), width);
|
||||||
|
this.canvas.DrawLine(new PointF((float)Line2_ColBegin[0], (float)Line2_RowBegin[0]), new PointF((float)Line2_ColEnd[0], (float)Line2_RowEnd[0]), width);
|
||||||
|
this.canvas.Invalidate();
|
||||||
|
lblElapsed.Text = $"{timeElasped} ms";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void NumRectWidth1_ValueChanged(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
if (_line1 != null)
|
||||||
|
{
|
||||||
|
//_line1.IsDrawLineVirtualRect = true;
|
||||||
|
_line1.LineVirtualRectWidth = (float)NumRectWidth1.Value;
|
||||||
|
UpdateShape(_line1);
|
||||||
|
this.canvas.Invalidate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void NumericUpDown2_ValueChanged(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
if (_line2 != null)
|
||||||
|
{
|
||||||
|
// _line2.IsDrawLineVirtualRect = true;
|
||||||
|
_line2.LineVirtualRectWidth = (float)NumRectWidth2.Value;
|
||||||
|
UpdateShape(_line2);
|
||||||
|
this.canvas.Invalidate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void btnSave_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
if (lblResult.Text.Equals("无"))
|
||||||
|
{
|
||||||
|
MessageBox.Show("请先进行绘制");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (lblResult.Text != "0")
|
||||||
|
{
|
||||||
|
MessageBox.Show("测量计算错误,无法保存");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//inputPara["Line1_LX"] = _line1X1;
|
||||||
|
//inputPara["Line1_LY"] = _line1Y1;
|
||||||
|
//inputPara["Line1_RX"] = _line1X2;
|
||||||
|
//inputPara["Line1_RY"] = _line1Y2;
|
||||||
|
|
||||||
|
//inputPara["Line2_LX"] = _line2X1;
|
||||||
|
//inputPara["Line2_LY"] = _line2Y1;
|
||||||
|
//inputPara["Line2_RX"] = _line2X2;
|
||||||
|
//inputPara["Line2_RY"] = _line2Y2;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//inputPara["Line1_XRect"] = hTupleArray1X;
|
||||||
|
//inputPara["Line1_YRect"] = hTupleArray1Y;
|
||||||
|
|
||||||
|
//inputPara["Line2_XRect"] = hTupleArray2X;
|
||||||
|
//inputPara["Line2_YRect"] = hTupleArray2Y;
|
||||||
|
|
||||||
|
|
||||||
|
string input = $"Line1_LX:{_line1X1};" +
|
||||||
|
$"Line1_LY:{_line1Y1};" +
|
||||||
|
$"Line1_RX:{_line1X2};" +
|
||||||
|
$"Line1_RY:{_line1Y2};" +
|
||||||
|
$"Line2_LX:{_line2X1};" +
|
||||||
|
$"Line2_LY:{_line2Y1};" +
|
||||||
|
$"Line2_RX:{_line2X2};" +
|
||||||
|
$"Line2_RY:{_line2Y2};" +
|
||||||
|
$"Line1_XRect:{strarray1X};" +
|
||||||
|
$"Line1_YRect:{strarray1Y};" +
|
||||||
|
$"Line2_XRect:{strarray2X};" +
|
||||||
|
$"Line2_YRect:{strarray2Y}"
|
||||||
|
;
|
||||||
|
|
||||||
|
|
||||||
|
string result = $"Distance:{Distance[0]}";
|
||||||
|
|
||||||
|
|
||||||
|
DataToTriggerEvent(input, result);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
145
CanFly/UI/GuidePanel/GuideLineLineCtrl.resx
Normal file
145
CanFly/UI/GuidePanel/GuideLineLineCtrl.resx
Normal file
@@ -0,0 +1,145 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<root>
|
||||||
|
<!--
|
||||||
|
Microsoft ResX Schema
|
||||||
|
|
||||||
|
Version 2.0
|
||||||
|
|
||||||
|
The primary goals of this format is to allow a simple XML format
|
||||||
|
that is mostly human readable. The generation and parsing of the
|
||||||
|
various data types are done through the TypeConverter classes
|
||||||
|
associated with the data types.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
... ado.net/XML headers & schema ...
|
||||||
|
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||||
|
<resheader name="version">2.0</resheader>
|
||||||
|
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||||
|
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||||
|
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||||
|
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||||
|
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||||
|
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||||
|
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||||
|
<comment>This is a comment</comment>
|
||||||
|
</data>
|
||||||
|
|
||||||
|
There are any number of "resheader" rows that contain simple
|
||||||
|
name/value pairs.
|
||||||
|
|
||||||
|
Each data row contains a name, and value. The row also contains a
|
||||||
|
type or mimetype. Type corresponds to a .NET class that support
|
||||||
|
text/value conversion through the TypeConverter architecture.
|
||||||
|
Classes that don't support this are serialized and stored with the
|
||||||
|
mimetype set.
|
||||||
|
|
||||||
|
The mimetype is used for serialized objects, and tells the
|
||||||
|
ResXResourceReader how to depersist the object. This is currently not
|
||||||
|
extensible. For a given mimetype the value must be set accordingly:
|
||||||
|
|
||||||
|
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||||
|
that the ResXResourceWriter will generate, however the reader can
|
||||||
|
read any of the formats listed below.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.binary.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.soap.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||||
|
value : The object must be serialized into a byte array
|
||||||
|
: using a System.ComponentModel.TypeConverter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
-->
|
||||||
|
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||||
|
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||||
|
<xsd:element name="root" msdata:IsDataSet="true">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:choice maxOccurs="unbounded">
|
||||||
|
<xsd:element name="metadata">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="assembly">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:attribute name="alias" type="xsd:string" />
|
||||||
|
<xsd:attribute name="name" type="xsd:string" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="data">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="resheader">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:choice>
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:schema>
|
||||||
|
<resheader name="resmimetype">
|
||||||
|
<value>text/microsoft-resx</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="version">
|
||||||
|
<value>2.0</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="reader">
|
||||||
|
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="writer">
|
||||||
|
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
<data name="canvas.OutsideShapes" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||||
|
<value>
|
||||||
|
AAEAAAD/////AQAAAAAAAAAMAgAAAERDYW5GbHkuQ2FudmFzLCBWZXJzaW9uPTEuMC4wLjAsIEN1bHR1
|
||||||
|
cmU9bmV1dHJhbCwgUHVibGljS2V5VG9rZW49bnVsbAQBAAAAdlN5c3RlbS5Db2xsZWN0aW9ucy5HZW5l
|
||||||
|
cmljLkxpc3RgMVtbQ2FuRmx5LkNhbnZhcy5TaGFwZS5GbHlTaGFwZSwgQ2FuRmx5LkNhbnZhcywgQ3Vs
|
||||||
|
dHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1udWxsXV0DAAAABl9pdGVtcwVfc2l6ZQhfdmVyc2lv
|
||||||
|
bgQAAB5DYW5GbHkuQ2FudmFzLlNoYXBlLkZseVNoYXBlW10CAAAACAgJAwAAAAAAAAAAAAAADAQAAAAz
|
||||||
|
Q2FuRmx5LkNhbnZhcywgQ3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1udWxsBwMAAAAAAQAA
|
||||||
|
AAAAAAAEHENhbkZseS5DYW52YXMuU2hhcGUuRmx5U2hhcGUEAAAACw==
|
||||||
|
</value>
|
||||||
|
</data>
|
||||||
|
<data name="canvas.Shapes" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||||
|
<value>
|
||||||
|
AAEAAAD/////AQAAAAAAAAAMAgAAAERDYW5GbHkuQ2FudmFzLCBWZXJzaW9uPTEuMC4wLjAsIEN1bHR1
|
||||||
|
cmU9bmV1dHJhbCwgUHVibGljS2V5VG9rZW49bnVsbAQBAAAAdlN5c3RlbS5Db2xsZWN0aW9ucy5HZW5l
|
||||||
|
cmljLkxpc3RgMVtbQ2FuRmx5LkNhbnZhcy5TaGFwZS5GbHlTaGFwZSwgQ2FuRmx5LkNhbnZhcywgQ3Vs
|
||||||
|
dHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1udWxsXV0DAAAABl9pdGVtcwVfc2l6ZQhfdmVyc2lv
|
||||||
|
bgQAAB5DYW5GbHkuQ2FudmFzLlNoYXBlLkZseVNoYXBlW10CAAAACAgJAwAAAAAAAAAAAAAADAQAAAAz
|
||||||
|
Q2FuRmx5LkNhbnZhcywgQ3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1udWxsBwMAAAAAAQAA
|
||||||
|
AAAAAAAEHENhbkZseS5DYW52YXMuU2hhcGUuRmx5U2hhcGUEAAAACw==
|
||||||
|
</value>
|
||||||
|
</data>
|
||||||
|
<metadata name="statusStrip1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||||
|
<value>17, 17</value>
|
||||||
|
</metadata>
|
||||||
|
</root>
|
||||||
41
CanFly/Util/FormUtils.cs
Normal file
41
CanFly/Util/FormUtils.cs
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace CanFly.Util
|
||||||
|
{
|
||||||
|
public static class FormUtils
|
||||||
|
{
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 显示窗体
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="panel"></param>
|
||||||
|
/// <param name="frm"></param>
|
||||||
|
public static void ShowForm(this Panel panel, Form frm)
|
||||||
|
{
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
frm.TopLevel = false;
|
||||||
|
panel.Controls.Clear();
|
||||||
|
panel.Controls.Add(frm);
|
||||||
|
frm.Show();
|
||||||
|
frm.Dock = DockStyle.Fill;
|
||||||
|
panel.Refresh();
|
||||||
|
foreach (Control item in frm.Controls)
|
||||||
|
{
|
||||||
|
item.Focus();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
throw ex;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
61
CanFly/XKRS.CanFly.csproj
Normal file
61
CanFly/XKRS.CanFly.csproj
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>net8.0-windows</TargetFramework>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
<BaseOutputPath>..\</BaseOutputPath>
|
||||||
|
<AppendTargetFrameworkToOutputPath>output</AppendTargetFrameworkToOutputPath>
|
||||||
|
<UseWindowsForms>true</UseWindowsForms>
|
||||||
|
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||||
|
<Platforms>AnyCPU;x64</Platforms>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\CanFly.Canvas\CanFly.Canvas.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<Folder Include="Halcon\" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="OpenCvSharp4" Version="4.10.0.20241108" />
|
||||||
|
<PackageReference Include="OpenCvSharp4.Extensions" Version="4.10.0.20241108" />
|
||||||
|
<PackageReference Include="OpenCvSharp4.runtime.win" Version="4.10.0.20241108" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<Reference Include="halcondotnet">
|
||||||
|
<HintPath>..\x64\Debug\halcondotnet.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="hdevenginedotnet">
|
||||||
|
<HintPath>..\x64\Debug\hdevenginedotnet.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<Compile Update="Properties\Resources.Designer.cs">
|
||||||
|
<DesignTime>True</DesignTime>
|
||||||
|
<AutoGen>True</AutoGen>
|
||||||
|
<DependentUpon>Resources.resx</DependentUpon>
|
||||||
|
</Compile>
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<EmbeddedResource Update="Properties\Resources.resx">
|
||||||
|
<Generator>ResXFileCodeGenerator</Generator>
|
||||||
|
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
|
||||||
|
</EmbeddedResource>
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
||||||
40
DH.Commons.Devies/DH.Commons.Devies.csproj
Normal file
40
DH.Commons.Devies/DH.Commons.Devies.csproj
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk.WindowsDesktop">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>net8.0-windows</TargetFramework>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
<BaseOutputPath>..\</BaseOutputPath>
|
||||||
|
<AppendTargetFrameworkToOutputPath>output</AppendTargetFrameworkToOutputPath>
|
||||||
|
<UseWindowsForms>true</UseWindowsForms>
|
||||||
|
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||||
|
<Platforms>AnyCPU;x64</Platforms>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<Folder Include="Enums\" />
|
||||||
|
<Folder Include="Helper\" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="AntdUI" Version="1.8.9" />
|
||||||
|
<PackageReference Include="OpenCvSharp4" Version="4.10.0.20241108" />
|
||||||
|
<PackageReference Include="OpenCvSharp4.Extensions" Version="4.10.0.20241108" />
|
||||||
|
<PackageReference Include="OpenCvSharp4.runtime.win" Version="4.10.0.20241108" />
|
||||||
|
<PackageReference Include="System.IO.Ports" Version="9.0.3" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\DH.Commons\DH.Commons.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<Reference Include="halcondotnet">
|
||||||
|
<HintPath>..\x64\Debug\halcondotnet.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="hdevenginedotnet">
|
||||||
|
<HintPath>..\x64\Debug\hdevenginedotnet.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
||||||
360
DH.Commons/Base/CameraBase.cs
Normal file
360
DH.Commons/Base/CameraBase.cs
Normal file
@@ -0,0 +1,360 @@
|
|||||||
|
using System;
|
||||||
|
using System.ComponentModel;
|
||||||
|
using System.Drawing.Imaging;
|
||||||
|
using AntdUI;
|
||||||
|
using DH.Commons.Enums;
|
||||||
|
using HalconDotNet;
|
||||||
|
using OpenCvSharp;
|
||||||
|
|
||||||
|
namespace DH.Commons.Base
|
||||||
|
{
|
||||||
|
public class MatSet
|
||||||
|
{
|
||||||
|
public DateTime ImageTime { get; set; } = DateTime.Now;
|
||||||
|
|
||||||
|
private string id = "";
|
||||||
|
public string Id
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(id))
|
||||||
|
{
|
||||||
|
id = ImageTime.ToString("HHmmssfff");
|
||||||
|
}
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
id = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public string CameraId { get; set; }
|
||||||
|
public Mat _mat { get; set; } = null;
|
||||||
|
|
||||||
|
public ImageFormat _imageFormat { get; set; } = ImageFormat.Jpeg;
|
||||||
|
public virtual void Dispose()
|
||||||
|
{
|
||||||
|
_mat?.Dispose();
|
||||||
|
_mat = null;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public class CameraBase : NotifyProperty
|
||||||
|
{
|
||||||
|
|
||||||
|
// public LoggerHelper LoggerHelper { get; set; } = new LoggerHelper();
|
||||||
|
|
||||||
|
// 私有字段 + 带通知的属性(与DetectionLabel风格一致)
|
||||||
|
private bool _isEnabled = false;
|
||||||
|
private bool _isallPicEnabled = true;//默认全画幅
|
||||||
|
private bool _isContinueMode = false;
|
||||||
|
private bool _isSavePicEnabled = false;
|
||||||
|
private string _imageSaveDirectory;
|
||||||
|
private EnumCamType _CamType;
|
||||||
|
private ImageFormat _imageFormat = ImageFormat.Jpeg;
|
||||||
|
private bool _isHardwareTrigger = true;
|
||||||
|
private string _serialNumber = string.Empty;
|
||||||
|
private string _cameraName = string.Empty;
|
||||||
|
private string _cameraIP = string.Empty;
|
||||||
|
private string _computerIP = string.Empty;
|
||||||
|
private bool _isDirectHardwareTrigger = false;
|
||||||
|
private float _gain =6;
|
||||||
|
private float _rotateImage = 0;
|
||||||
|
private float _exposure = 200;
|
||||||
|
private float _triggerDelay = 0;
|
||||||
|
private decimal _roiX = 0;
|
||||||
|
private decimal _roiY = 0;
|
||||||
|
private decimal _roiW = 2448;
|
||||||
|
private decimal _roiH = 2048;
|
||||||
|
private int _lineDebouncerTime = 0;
|
||||||
|
|
||||||
|
public volatile int SnapshotCount = 0;
|
||||||
|
|
||||||
|
[Category("采图模式")]
|
||||||
|
[DisplayName("连续模式")]
|
||||||
|
[Description("是否连续模式。true:连续模式采图;false:触发模式采图")]
|
||||||
|
public bool IsContinueMode
|
||||||
|
{
|
||||||
|
get => _isContinueMode;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (_isContinueMode == value) return;
|
||||||
|
_isContinueMode = value;
|
||||||
|
OnPropertyChanged(nameof(IsContinueMode));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual bool IsEnabled
|
||||||
|
{
|
||||||
|
get => _isEnabled;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (_isEnabled == value) return;
|
||||||
|
_isEnabled = value;
|
||||||
|
OnPropertyChanged(nameof(IsEnabled));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public virtual bool IsAllPicEnabled
|
||||||
|
{
|
||||||
|
get => _isallPicEnabled;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (_isallPicEnabled == value) return;
|
||||||
|
_isallPicEnabled = value;
|
||||||
|
OnPropertyChanged(nameof(IsAllPicEnabled));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public virtual bool IsSavePicEnabled
|
||||||
|
{
|
||||||
|
get => _isSavePicEnabled;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (_isSavePicEnabled == value) return;
|
||||||
|
_isSavePicEnabled = value;
|
||||||
|
OnPropertyChanged(nameof(IsSavePicEnabled));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Category("图片保存")]
|
||||||
|
[DisplayName("图片保存文件夹")]
|
||||||
|
[Description("图片保存文件夹")]
|
||||||
|
public virtual string ImageSaveDirectory
|
||||||
|
{
|
||||||
|
get => _imageSaveDirectory;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (_imageSaveDirectory == value) return;
|
||||||
|
_imageSaveDirectory = value;
|
||||||
|
OnPropertyChanged(nameof(ImageSaveDirectory));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Category("图片保存")]
|
||||||
|
[DisplayName("图片保存格式")]
|
||||||
|
[Description("图片保存格式")]
|
||||||
|
public ImageFormat ImageFormat
|
||||||
|
{
|
||||||
|
get => _imageFormat;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (_imageFormat == value) return;
|
||||||
|
_imageFormat = value;
|
||||||
|
OnPropertyChanged(nameof(ImageFormat));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
[Category("设备配置")]
|
||||||
|
[DisplayName("相机类型")]
|
||||||
|
[Description("相机类型")]
|
||||||
|
public EnumCamType CamType
|
||||||
|
{
|
||||||
|
get => _CamType;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (_CamType == value) return;
|
||||||
|
_CamType = value;
|
||||||
|
OnPropertyChanged(nameof(CamType));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Category("采图模式")]
|
||||||
|
[DisplayName("硬触发")]
|
||||||
|
[Description("是否硬触发模式。true:硬触发;false:软触发")]
|
||||||
|
public bool IsHardwareTrigger
|
||||||
|
{
|
||||||
|
get => _isHardwareTrigger;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (_isHardwareTrigger == value) return;
|
||||||
|
_isHardwareTrigger = value;
|
||||||
|
OnPropertyChanged(nameof(IsHardwareTrigger));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public string SerialNumber
|
||||||
|
{
|
||||||
|
get => _serialNumber;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (_serialNumber == value) return;
|
||||||
|
_serialNumber = value;
|
||||||
|
OnPropertyChanged(nameof(SerialNumber));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public string CameraName
|
||||||
|
{
|
||||||
|
get => _cameraName;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (_cameraName == value) return;
|
||||||
|
_cameraName = value;
|
||||||
|
OnPropertyChanged(nameof(CameraName));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public string CameraIP
|
||||||
|
{
|
||||||
|
get => _cameraIP;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (_cameraIP == value) return;
|
||||||
|
_cameraIP = value;
|
||||||
|
OnPropertyChanged(nameof(CameraIP));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public string ComputerIP
|
||||||
|
{
|
||||||
|
get => _computerIP;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (_computerIP == value) return;
|
||||||
|
_computerIP = value;
|
||||||
|
OnPropertyChanged(nameof(ComputerIP));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Category("采图模式")]
|
||||||
|
[DisplayName("是否传感器直接硬触发")]
|
||||||
|
[Description("是否传感器直接硬触发。true:传感器硬触发,不通过软件触发;false:通过软件触发IO 的硬触发模式")]
|
||||||
|
public bool IsDirectHardwareTrigger
|
||||||
|
{
|
||||||
|
get => _isDirectHardwareTrigger;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (_isDirectHardwareTrigger == value) return;
|
||||||
|
_isDirectHardwareTrigger = value;
|
||||||
|
OnPropertyChanged(nameof(IsDirectHardwareTrigger));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Category("相机设置")]
|
||||||
|
[DisplayName("增益")]
|
||||||
|
[Description("Gain:增益,-1:不设置,不同型号相机的增益,请参考mvs")]
|
||||||
|
public float Gain
|
||||||
|
{
|
||||||
|
get => _gain;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (_gain.Equals(value)) return;
|
||||||
|
_gain = value;
|
||||||
|
OnPropertyChanged(nameof(Gain));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Category("图像旋转")]
|
||||||
|
[DisplayName("默认旋转")]
|
||||||
|
[Description("默认旋转,相机开启后默认不旋转")]
|
||||||
|
public virtual float RotateImage
|
||||||
|
{
|
||||||
|
get => _rotateImage;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (_rotateImage.Equals(value)) return;
|
||||||
|
_rotateImage = value;
|
||||||
|
OnPropertyChanged(nameof(RotateImage));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Category("取像配置")]
|
||||||
|
[DisplayName("曝光")]
|
||||||
|
[Description("曝光")]
|
||||||
|
public virtual float Exposure
|
||||||
|
{
|
||||||
|
get => _exposure;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (_exposure.Equals(value)) return;
|
||||||
|
_exposure = value;
|
||||||
|
OnPropertyChanged(nameof(Exposure));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Category("相机设置")]
|
||||||
|
[DisplayName("硬触发后的延迟")]
|
||||||
|
[Description("TriggerDelay:硬触发后的延迟,单位:us 微秒")]
|
||||||
|
public float TriggerDelay
|
||||||
|
{
|
||||||
|
get => _triggerDelay;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (_triggerDelay.Equals(value)) return;
|
||||||
|
_triggerDelay = value;
|
||||||
|
OnPropertyChanged(nameof(TriggerDelay));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public decimal ROIX
|
||||||
|
{
|
||||||
|
get => _roiX;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (_roiX == value) return;
|
||||||
|
_roiX = value;
|
||||||
|
OnPropertyChanged(nameof(ROIX));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public decimal ROIY
|
||||||
|
{
|
||||||
|
get => _roiY;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (_roiY == value) return;
|
||||||
|
_roiY = value;
|
||||||
|
OnPropertyChanged(nameof(ROIY));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public decimal ROIW
|
||||||
|
{
|
||||||
|
get => _roiW;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (_roiW == value) return;
|
||||||
|
_roiW = value;
|
||||||
|
OnPropertyChanged(nameof(ROIW));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public decimal ROIH
|
||||||
|
{
|
||||||
|
get => _roiH;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (_roiH == value) return;
|
||||||
|
_roiH = value;
|
||||||
|
OnPropertyChanged(nameof(ROIH));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Category("相机设置")]
|
||||||
|
[DisplayName("滤波时间")]
|
||||||
|
[Description("LineDebouncerTime:I/O去抖时间 单位:us")]
|
||||||
|
public int LineDebouncerTime
|
||||||
|
{
|
||||||
|
get => _lineDebouncerTime;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (_lineDebouncerTime == value) return;
|
||||||
|
_lineDebouncerTime = value;
|
||||||
|
OnPropertyChanged(nameof(LineDebouncerTime));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 其他方法保持原有逻辑
|
||||||
|
public Action<DateTime, CameraBase, Mat> OnHImageOutput { get; set; }
|
||||||
|
|
||||||
|
public virtual bool CameraConnect() { return false; }
|
||||||
|
|
||||||
|
public virtual bool CameraDisConnect() { return false; }
|
||||||
|
|
||||||
|
public virtual void SetExposure(int exposureTime, string cameraName) { }
|
||||||
|
|
||||||
|
public virtual void SetGain(int gain, string cameraName) { }
|
||||||
|
|
||||||
|
internal virtual void SetAcquisitionMode(int mode) { }
|
||||||
|
|
||||||
|
internal virtual void SetAcqRegion(int offsetV, int offsetH, int imageH, int imageW, string cameraName) { }
|
||||||
|
}
|
||||||
|
}
|
||||||
1464
DH.Commons/Base/DetectionConfig.cs
Normal file
1464
DH.Commons/Base/DetectionConfig.cs
Normal file
File diff suppressed because it is too large
Load Diff
389
DH.Commons/Base/DeviceBase.cs
Normal file
389
DH.Commons/Base/DeviceBase.cs
Normal file
@@ -0,0 +1,389 @@
|
|||||||
|
|
||||||
|
using DH.Commons.Enums;
|
||||||
|
using OpenCvSharp.Internal;
|
||||||
|
using System;
|
||||||
|
using System.ComponentModel;
|
||||||
|
using System.IO;
|
||||||
|
using System.Text.Json.Serialization;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using static DH.Commons.Enums.EnumHelper;
|
||||||
|
using Timer = System.Threading.Timer;
|
||||||
|
|
||||||
|
namespace DH.Commons.Base
|
||||||
|
{
|
||||||
|
public abstract class DeviceBase : IDisposable
|
||||||
|
{
|
||||||
|
#region Event
|
||||||
|
[JsonIgnore]
|
||||||
|
[Browsable(false)]
|
||||||
|
public Action<DateTime, Exception> OnExceptionOccured { get; set; }
|
||||||
|
//public event Action<DateTime, LogLevel, string> OnLog;
|
||||||
|
public event Action<LogMsg> OnLog;
|
||||||
|
// public event Action<IDevice, DeviceState> OnDeviceStateChanged;
|
||||||
|
public event PropertyChangedEventHandler PropertyChanged;
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region field
|
||||||
|
int RetryTime = 3;
|
||||||
|
/// <summary>
|
||||||
|
/// 和设备暂停状态关联的信号量
|
||||||
|
/// </summary>
|
||||||
|
private readonly ManualResetEvent pauseHandle = new ManualResetEvent(true);
|
||||||
|
readonly Timer stateChangedTimer;
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Property
|
||||||
|
#region State
|
||||||
|
private EnumHelper.DeviceState _currentStateToBe = EnumHelper.DeviceState.DSUninit;
|
||||||
|
/// <summary>
|
||||||
|
/// 当前设备状态
|
||||||
|
/// </summary>
|
||||||
|
[JsonIgnore]
|
||||||
|
internal EnumHelper.DeviceState CurrentStateToBe
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return _currentStateToBe;
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (value != _currentStateToBe)
|
||||||
|
{
|
||||||
|
var initialState = _currentStateToBe;
|
||||||
|
_currentStateToBe = value;
|
||||||
|
|
||||||
|
if (_currentStateToBe != EnumHelper.DeviceState.DSExcept)
|
||||||
|
{
|
||||||
|
// OnStateChanged(initialState);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
stateChangedTimer.Change(Timeout.Infinite, Timeout.Infinite);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//private EnumHelper.DeviceState initialState = EnumHelper.DeviceState.DSUninit;
|
||||||
|
private EnumHelper.DeviceState _currentState = EnumHelper.DeviceState.DSUninit;
|
||||||
|
public EnumHelper.DeviceState CurrentState
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return _currentState;
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_currentState = value;
|
||||||
|
|
||||||
|
if (value != EnumHelper.DeviceState.TBD)
|
||||||
|
{
|
||||||
|
// OnDeviceStateChanged?.Invoke(this, _currentState);
|
||||||
|
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("CurrentState"));
|
||||||
|
}
|
||||||
|
//else
|
||||||
|
//{
|
||||||
|
// initialState = _currentState;
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 设备标识符 从数据库获取
|
||||||
|
/// </summary>
|
||||||
|
public string Id { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 设备名称 从数据库获取
|
||||||
|
/// </summary>
|
||||||
|
public string Name { get; set; }
|
||||||
|
|
||||||
|
//private IInitialConfig initialConfig = null;
|
||||||
|
///// <summary>
|
||||||
|
///// 设备初始化配置 从数据库获取
|
||||||
|
///// </summary>
|
||||||
|
//public virtual IInitialConfig InitialConfig
|
||||||
|
//{
|
||||||
|
// get => initialConfig;
|
||||||
|
// set
|
||||||
|
// {
|
||||||
|
// initialConfig = value;
|
||||||
|
// Id = initialConfig.Id;
|
||||||
|
// Name = initialConfig.Name;
|
||||||
|
|
||||||
|
// LoggerHelper.LogPath = initialConfig.LogPath;
|
||||||
|
// LoggerHelper.LogPrefix = initialConfig.Name;
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region 构造函数
|
||||||
|
public DeviceBase()
|
||||||
|
{
|
||||||
|
RegisterFileWriterException();
|
||||||
|
// stateChangedTimer = new Timer(new TimerCallback(CheckDeviceOpTimeOut), null, Timeout.Infinite, Timeout.Infinite);
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region 设备抽象方法
|
||||||
|
protected virtual void Init()
|
||||||
|
{
|
||||||
|
LogAsync(DateTime.Now, LogLevel.Information, $"{Name}初始化完成");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
protected virtual void Start()
|
||||||
|
{
|
||||||
|
LogAsync(DateTime.Now, LogLevel.Information, $"{Name}启动");
|
||||||
|
}
|
||||||
|
|
||||||
|
protected virtual void Stop()
|
||||||
|
{
|
||||||
|
LogAsync(DateTime.Now, LogLevel.Information, $"{Name}停止");
|
||||||
|
}
|
||||||
|
|
||||||
|
//public abstract void AttachToProcess(IProcess process);
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 常用操作封装方法
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="opConfig"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
//public virtual ResponseMessage RunWrap(IOperationConfig opConfig)
|
||||||
|
//{
|
||||||
|
// ResponseMessage msg = new ResponseMessage();
|
||||||
|
// msg.Message = "设备基类默认操作";
|
||||||
|
// return msg;
|
||||||
|
//}
|
||||||
|
|
||||||
|
#region 状态切换
|
||||||
|
//[DeviceExceptionAspect]
|
||||||
|
//public void StateChange(EnumHelper.DeviceState stateToBe)
|
||||||
|
//{
|
||||||
|
// if (CurrentState == stateToBe)
|
||||||
|
// {
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// if (!stateToBe.CheckPreStateValid((int)CurrentStateToBe))
|
||||||
|
// {
|
||||||
|
// string currentStateStr = CurrentStateToBe.GetEnumDescription();
|
||||||
|
// string stateToBeStr = stateToBe.GetEnumDescription();
|
||||||
|
// throw new ProcessException($"{InitialConfig.Name}设备的当前状态为{currentStateStr},无法切换至{stateToBeStr}");
|
||||||
|
// }
|
||||||
|
|
||||||
|
// CurrentState = EnumHelper.DeviceState.TBD;
|
||||||
|
// CurrentStateToBe = stateToBe;
|
||||||
|
//}
|
||||||
|
|
||||||
|
//[DeviceExceptionAspect]
|
||||||
|
//private void OnStateChanged(EnumHelper.DeviceState initialState)
|
||||||
|
//{
|
||||||
|
// try
|
||||||
|
// {
|
||||||
|
// if (CurrentStateToBe != EnumHelper.DeviceState.DSExcept)
|
||||||
|
// {
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
// {
|
||||||
|
// if (CurrentState == EnumHelper.DeviceState.DSExcept)
|
||||||
|
// {
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
// {
|
||||||
|
// throw new ProcessException($"{InitialConfig.Name}设备操作超时");
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// if (RetryTime >= 0)
|
||||||
|
// {
|
||||||
|
// if (initialState == CurrentStateToBe)
|
||||||
|
// {
|
||||||
|
// CurrentState = CurrentStateToBe;
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// #region 状态切换操作
|
||||||
|
// switch (CurrentStateToBe)
|
||||||
|
// {
|
||||||
|
// case EnumHelper.DeviceState.DSInit:
|
||||||
|
// if (initialState == EnumHelper.DeviceState.DSOpen)
|
||||||
|
// {
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
// {
|
||||||
|
// Init();
|
||||||
|
// }
|
||||||
|
// break;
|
||||||
|
// case EnumHelper.DeviceState.DSOpen:
|
||||||
|
// if (initialState == EnumHelper.DeviceState.DSInit)
|
||||||
|
// {
|
||||||
|
// Start();
|
||||||
|
// }
|
||||||
|
// else if (initialState == EnumHelper.DeviceState.DSPause)
|
||||||
|
// {
|
||||||
|
// Resume();
|
||||||
|
// pauseHandle.Set();
|
||||||
|
// }
|
||||||
|
// break;
|
||||||
|
// case EnumHelper.DeviceState.DSPause:
|
||||||
|
// pauseHandle.Reset();
|
||||||
|
// Pause();
|
||||||
|
// break;
|
||||||
|
// case EnumHelper.DeviceState.DSClose:
|
||||||
|
// if (initialState != DeviceState.DSUninit)
|
||||||
|
// {
|
||||||
|
// Stop();
|
||||||
|
// }
|
||||||
|
// break;
|
||||||
|
// default:
|
||||||
|
// break;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// RetryTime = 3;
|
||||||
|
// CurrentState = CurrentStateToBe;
|
||||||
|
// #endregion
|
||||||
|
// }
|
||||||
|
|
||||||
|
// stateChangedTimer.Change(Timeout.Infinite, Timeout.Infinite);
|
||||||
|
// }
|
||||||
|
// catch (Exception ex)
|
||||||
|
// {
|
||||||
|
// RetryTime--;
|
||||||
|
// if (RetryTime > 0)
|
||||||
|
// {
|
||||||
|
// OnStateChanged(initialState);
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
// {
|
||||||
|
// if (CurrentState != EnumHelper.DeviceState.DSExcept)
|
||||||
|
// {
|
||||||
|
// RetryTime = 3;
|
||||||
|
// throw new ProcessException($"设备{InitialConfig.Name}的{CurrentStateToBe.GetEnumDescription()}操作重复3次失败", ex, ExceptionLevel.Warning);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
|
||||||
|
//private void CheckDeviceOpTimeOut(object state)
|
||||||
|
//{
|
||||||
|
// stateChangedTimer?.Change(Timeout.Infinite, Timeout.Infinite);
|
||||||
|
|
||||||
|
// if (CurrentState != EnumHelper.DeviceState.DSExcept)
|
||||||
|
// {
|
||||||
|
// StateChange(EnumHelper.DeviceState.DSExcept);
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region 日志处理
|
||||||
|
private void RegisterFileWriterException()
|
||||||
|
{
|
||||||
|
LoggerHelper.OnLogExceptionRaised -= LoggerHelper_OnLogExceptionRaised;
|
||||||
|
// CSVHelper.OnCSVExceptionRaised -= LoggerHelper_OnLogExceptionRaised;
|
||||||
|
|
||||||
|
LoggerHelper.OnLogExceptionRaised += LoggerHelper_OnLogExceptionRaised;
|
||||||
|
// CSVHelper.OnCSVExceptionRaised += LoggerHelper_OnLogExceptionRaised;
|
||||||
|
}
|
||||||
|
// public CSVHelper CSVHelper { get; set; } = new CSVHelper();
|
||||||
|
|
||||||
|
public LoggerHelper LoggerHelper { get; set; } = new LoggerHelper();
|
||||||
|
|
||||||
|
public virtual void LogAsync(LogMsg msg)
|
||||||
|
{
|
||||||
|
msg.MsgSource = Name;
|
||||||
|
msg.ThreadId = Thread.CurrentThread.ManagedThreadId;
|
||||||
|
|
||||||
|
//OnLog?.BeginInvoke(msg, null, null);
|
||||||
|
OnLog?.Invoke(msg);
|
||||||
|
|
||||||
|
//if (InitialConfig.IsEnableLog)
|
||||||
|
//{
|
||||||
|
// LoggerHelper.LogAsync(msg);
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual void LogAsync(DateTime dt, LogLevel logLevel, string msg)
|
||||||
|
{
|
||||||
|
LogAsync(new LogMsg(dt, logLevel, msg));
|
||||||
|
}
|
||||||
|
private void LoggerHelper_OnLogExceptionRaised(DateTime dt, string msg)
|
||||||
|
{
|
||||||
|
OnLog?.Invoke(new LogMsg(dt, LogLevel.Error, msg));
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// CSV异步数据输出
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="csvFile">CSV输出文件的文件全路径</param>
|
||||||
|
/// <param name="csvData">CSV输出数据</param>
|
||||||
|
/// <param name="csvHead">CSV文件表头</param>
|
||||||
|
public virtual void CSVRecordAsync(string csvFile, string csvData, string csvHead = "")
|
||||||
|
{
|
||||||
|
// CSVHelper.CSVOutputAsync(csvFile, csvData, csvHead);
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region 报警记录
|
||||||
|
//object _alarmLock = new object();
|
||||||
|
//protected virtual async void SaveAlarmCSVAsync(DateTime now, string deviceName, IWarningSet ws)
|
||||||
|
//{
|
||||||
|
// await Task.Run(() =>
|
||||||
|
// {
|
||||||
|
// LogAsync(now, LogLevel.Warning, $"{ws.WarningCode}-{ws.WarningDescription} {(ws.CurrentStatus ? "发生" : "取消")}");
|
||||||
|
|
||||||
|
// if (string.IsNullOrWhiteSpace(this.InitialConfig.LogPath) || !InitialConfig.IsEnableCSV)
|
||||||
|
// return;
|
||||||
|
|
||||||
|
// string path = Path.Combine(InitialConfig.LogPath, $"Alarm_{Name}_{now.ToString("yyyyMMdd")}.csv");
|
||||||
|
// string head = "Time,Source,AlarmCode,AlarmDescription,AlarmStatus";
|
||||||
|
// string data = $"{now.ToString("HH:mm:ss.fff")},{deviceName},{ws.WarningCode},{ws.WarningDescription},{(ws.CurrentStatus ? "报警发生" : "报警取消")}";
|
||||||
|
// CSVRecordAsync(path, data, head);
|
||||||
|
// });
|
||||||
|
//}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region IDisposable Support
|
||||||
|
private bool disposedValue = false; // 要检测冗余调用
|
||||||
|
|
||||||
|
protected virtual void Dispose(bool disposing)
|
||||||
|
{
|
||||||
|
if (!disposedValue)
|
||||||
|
{
|
||||||
|
if (disposing)
|
||||||
|
{
|
||||||
|
//释放托管状态(托管对象)。
|
||||||
|
stateChangedTimer?.Dispose();
|
||||||
|
pauseHandle?.Dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: 释放未托管的资源(未托管的对象)并在以下内容中替代终结器。
|
||||||
|
// TODO: 将大型字段设置为 null。
|
||||||
|
|
||||||
|
disposedValue = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: 仅当以上 Dispose(bool disposing) 拥有用于释放未托管资源的代码时才替代终结器。
|
||||||
|
// ~DeviceBase()
|
||||||
|
// {
|
||||||
|
// // 请勿更改此代码。将清理代码放入以上 Dispose(bool disposing) 中。
|
||||||
|
// Dispose(false);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// 添加此代码以正确实现可处置模式。
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
// 请勿更改此代码。将清理代码放入以上 Dispose(bool disposing) 中。
|
||||||
|
Dispose(true);
|
||||||
|
// TODO: 如果在以上内容中替代了终结器,则取消注释以下行。
|
||||||
|
// GC.SuppressFinalize(this);
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
131
DH.Commons/Base/GlobalConfig.cs
Normal file
131
DH.Commons/Base/GlobalConfig.cs
Normal file
@@ -0,0 +1,131 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.ComponentModel;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Xml.Linq;
|
||||||
|
using AntdUI;
|
||||||
|
|
||||||
|
namespace DH.Commons.Base
|
||||||
|
{
|
||||||
|
public class GlobalConfig : NotifyProperty
|
||||||
|
{
|
||||||
|
string _name;
|
||||||
|
private BindingList<PLCItem> _InitProcessList = new BindingList<PLCItem>();
|
||||||
|
private BindingList<PLCItem> _StartProcessList = new BindingList<PLCItem>();
|
||||||
|
private BindingList<PLCItem> _StopProcessList = new BindingList<PLCItem>();
|
||||||
|
private BindingList<PLCItem> _StartResetList = new BindingList<PLCItem>();
|
||||||
|
private BindingList<PLCItem> _StopResetList = new BindingList<PLCItem>();
|
||||||
|
public string Name
|
||||||
|
{
|
||||||
|
get => _name;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (_name != value)
|
||||||
|
{
|
||||||
|
_name = value;
|
||||||
|
OnPropertyChanged(nameof(Name));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public BindingList<PLCItem> InitProcessList
|
||||||
|
{
|
||||||
|
get => _InitProcessList;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (_InitProcessList == value) return;
|
||||||
|
_InitProcessList = value;
|
||||||
|
OnPropertyChanged(nameof(InitProcessList));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public BindingList<PLCItem> StartProcessList
|
||||||
|
{
|
||||||
|
get => _StartProcessList;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (_StartProcessList == value) return;
|
||||||
|
_StartProcessList = value;
|
||||||
|
OnPropertyChanged(nameof(StartProcessList));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public BindingList<PLCItem> StopProcessList
|
||||||
|
{
|
||||||
|
get => _StopProcessList;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (_StopProcessList == value) return;
|
||||||
|
_StopProcessList = value;
|
||||||
|
OnPropertyChanged(nameof(StopProcessList));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public BindingList<PLCItem> StartResetList
|
||||||
|
{
|
||||||
|
get => _StartResetList;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (_StartResetList == value) return;
|
||||||
|
_StartResetList = value;
|
||||||
|
OnPropertyChanged(nameof(StartResetList));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public BindingList<PLCItem> StopResetList
|
||||||
|
{
|
||||||
|
get => _StopResetList;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (_StopResetList == value) return;
|
||||||
|
_StopResetList = value;
|
||||||
|
OnPropertyChanged(nameof(StopResetList));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
string _imgSavePath;
|
||||||
|
string _dbSavePath;
|
||||||
|
string _configSavePath;
|
||||||
|
|
||||||
|
public string ImgSavePath
|
||||||
|
{
|
||||||
|
get => _imgSavePath;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (_imgSavePath != value)
|
||||||
|
{
|
||||||
|
_imgSavePath = value;
|
||||||
|
OnPropertyChanged(nameof(ImgSavePath));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public string DbSavePath
|
||||||
|
{
|
||||||
|
get => _dbSavePath;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (_dbSavePath != value)
|
||||||
|
{
|
||||||
|
_dbSavePath = value;
|
||||||
|
OnPropertyChanged(nameof(DbSavePath));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public string ConfigSavePath
|
||||||
|
{
|
||||||
|
get => _configSavePath;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (_configSavePath != value)
|
||||||
|
{
|
||||||
|
_configSavePath = value;
|
||||||
|
OnPropertyChanged(nameof(ConfigSavePath));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
378
DH.Commons/Base/PLCBase.cs
Normal file
378
DH.Commons/Base/PLCBase.cs
Normal file
@@ -0,0 +1,378 @@
|
|||||||
|
using System.ComponentModel;
|
||||||
|
using System.IO.Ports;
|
||||||
|
using System.Text.Json.Serialization;
|
||||||
|
using AntdUI;
|
||||||
|
using DH.Commons.Enums; // 请确保此命名空间包含EnumPLCType
|
||||||
|
|
||||||
|
namespace DH.Commons.Base
|
||||||
|
{
|
||||||
|
public class PLCBase : NotifyProperty
|
||||||
|
{
|
||||||
|
|
||||||
|
// 私有字段
|
||||||
|
private bool _enable;
|
||||||
|
private bool _connected;
|
||||||
|
private string _plcName;
|
||||||
|
private EnumPLCType _plcType;
|
||||||
|
private string _com = "COM1";
|
||||||
|
private int _baudRate = 9600;
|
||||||
|
private int _dataBit = 8;
|
||||||
|
private StopBits _stopBit = StopBits.One;
|
||||||
|
private Parity _parity = Parity.None;
|
||||||
|
private string _ip = "192.168.6.61";
|
||||||
|
private int _port = 502;
|
||||||
|
private BindingList<PLCItem> _PLCItemList = new BindingList<PLCItem>();
|
||||||
|
|
||||||
|
[Category("设备配置")]
|
||||||
|
[DisplayName("是否启用")]
|
||||||
|
[Description("是否启用")]
|
||||||
|
public bool Enable
|
||||||
|
{
|
||||||
|
get => _enable;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (_enable == value) return;
|
||||||
|
_enable = value;
|
||||||
|
OnPropertyChanged(nameof(Enable));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
[Category("状态监控")]
|
||||||
|
[DisplayName("连接状态")]
|
||||||
|
[Description("PLC连接状态")]
|
||||||
|
public bool Connected
|
||||||
|
{
|
||||||
|
get => _connected;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (_connected == value) return;
|
||||||
|
_connected = value;
|
||||||
|
OnPropertyChanged(nameof(Connected));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Category("设备配置")]
|
||||||
|
[DisplayName("PLC名称")]
|
||||||
|
[Description("PLC设备名称")]
|
||||||
|
public string PLCName
|
||||||
|
{
|
||||||
|
get => _plcName;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (_plcName == value) return;
|
||||||
|
_plcName = value;
|
||||||
|
OnPropertyChanged(nameof(PLCName));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Category("设备配置")]
|
||||||
|
[DisplayName("PLC类型")]
|
||||||
|
[Description("PLC通信协议类型")]
|
||||||
|
public EnumPLCType PLCType
|
||||||
|
{
|
||||||
|
get => _plcType;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (_plcType == value) return;
|
||||||
|
_plcType = value;
|
||||||
|
OnPropertyChanged(nameof(PLCType));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Category("串口配置")]
|
||||||
|
[DisplayName("COM端口")]
|
||||||
|
[Description("串口号,如COM1")]
|
||||||
|
public string COM
|
||||||
|
{
|
||||||
|
get => _com;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (_com == value) return;
|
||||||
|
_com = value;
|
||||||
|
OnPropertyChanged(nameof(COM));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Category("串口配置")]
|
||||||
|
[DisplayName("波特率")]
|
||||||
|
[Description("串口通信波特率")]
|
||||||
|
public int BaudRate
|
||||||
|
{
|
||||||
|
get => _baudRate;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (_baudRate == value) return;
|
||||||
|
_baudRate = value;
|
||||||
|
OnPropertyChanged(nameof(BaudRate));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Category("串口配置")]
|
||||||
|
[DisplayName("数据位")]
|
||||||
|
[Description("数据位长度(5/6/7/8)")]
|
||||||
|
public int DataBit
|
||||||
|
{
|
||||||
|
get => _dataBit;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (_dataBit == value) return;
|
||||||
|
_dataBit = value;
|
||||||
|
OnPropertyChanged(nameof(DataBit));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Category("串口配置")]
|
||||||
|
[DisplayName("停止位")]
|
||||||
|
[Description("停止位设置")]
|
||||||
|
public StopBits StopBit
|
||||||
|
{
|
||||||
|
get => _stopBit;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (_stopBit == value) return;
|
||||||
|
_stopBit = value;
|
||||||
|
OnPropertyChanged(nameof(StopBit));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Category("串口配置")]
|
||||||
|
[DisplayName("校验位")]
|
||||||
|
[Description("奇偶校验方式")]
|
||||||
|
public Parity Parity
|
||||||
|
{
|
||||||
|
get => _parity;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (_parity == value) return;
|
||||||
|
_parity = value;
|
||||||
|
OnPropertyChanged(nameof(Parity));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Category("网络配置")]
|
||||||
|
[DisplayName("IP地址")]
|
||||||
|
[Description("PLC网络地址")]
|
||||||
|
public string IP
|
||||||
|
{
|
||||||
|
get => _ip;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (_ip == value) return;
|
||||||
|
_ip = value;
|
||||||
|
OnPropertyChanged(nameof(IP));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Category("网络配置")]
|
||||||
|
[DisplayName("端口号")]
|
||||||
|
[Description("网络通信端口")]
|
||||||
|
public int Port
|
||||||
|
{
|
||||||
|
get => _port;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (_port == value) return;
|
||||||
|
_port = value;
|
||||||
|
OnPropertyChanged(nameof(Port));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Category("点位配置")]
|
||||||
|
[DisplayName("点位配置")]
|
||||||
|
[Description("点位配置")]
|
||||||
|
public BindingList<PLCItem> PLCItemList
|
||||||
|
{
|
||||||
|
get => _PLCItemList;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (_PLCItemList == value) return;
|
||||||
|
_PLCItemList = value;
|
||||||
|
OnPropertyChanged(nameof(PLCItemList));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public virtual bool PLCConnect()
|
||||||
|
{
|
||||||
|
Connected = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual bool PLCDisConnect()
|
||||||
|
{
|
||||||
|
Connected = false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual Int16 ReadInt16(string address) { return 0; }
|
||||||
|
|
||||||
|
public virtual Int32 ReadInt32(string address) { return 0; }
|
||||||
|
|
||||||
|
public virtual UInt16 ReadUInt16(string address) { return 0; }
|
||||||
|
|
||||||
|
public virtual UInt32 ReadUInt32(string address) { return 0; }
|
||||||
|
public virtual float ReadFloat(string address) { return 0; }
|
||||||
|
public virtual bool ReadBool(string address) { return false; }
|
||||||
|
|
||||||
|
public virtual bool WriteInt16(string address, Int16 value, bool waitForReply = true) { return false; }
|
||||||
|
public virtual bool WriteInt32(string address, Int32 value, bool waitForReply = true) { return false; }
|
||||||
|
|
||||||
|
|
||||||
|
public virtual bool WriteUInt16(string address, UInt16 value, bool waitForReply = true) { return false; }
|
||||||
|
public virtual bool WriteUInt32(string address, UInt32 value, bool waitForReply = true) { return false; }
|
||||||
|
|
||||||
|
public virtual bool WriteFloat(string address, float value, bool waitForReply = true) { return false; }
|
||||||
|
public virtual bool WriteBool(string address, bool value, bool waitForReply = true) { return false; }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public class PLCItem : NotifyProperty
|
||||||
|
{
|
||||||
|
private bool _selected;
|
||||||
|
private string _name = string.Empty;
|
||||||
|
private EnumPLCDataType _type;
|
||||||
|
private string _value = string.Empty;
|
||||||
|
private bool _startexecute;
|
||||||
|
private int _startindex;
|
||||||
|
private string _address;
|
||||||
|
/// <summary>
|
||||||
|
/// 是否选中
|
||||||
|
/// </summary>
|
||||||
|
public bool Selected
|
||||||
|
{
|
||||||
|
get => _selected;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (_selected != value)
|
||||||
|
{
|
||||||
|
_selected = value;
|
||||||
|
OnPropertyChanged(nameof(Selected));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 参数名称
|
||||||
|
/// </summary>
|
||||||
|
public string Name
|
||||||
|
{
|
||||||
|
get => _name;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (_name != value)
|
||||||
|
{
|
||||||
|
_name = value;
|
||||||
|
OnPropertyChanged(nameof(Name));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public EnumPLCDataType Type
|
||||||
|
{
|
||||||
|
get => _type;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (_type != value)
|
||||||
|
{
|
||||||
|
_type = value;
|
||||||
|
OnPropertyChanged(nameof(Type));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// 参数类型
|
||||||
|
/// </summary>
|
||||||
|
public string Address
|
||||||
|
{
|
||||||
|
get => _address;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (_address != value)
|
||||||
|
{
|
||||||
|
_address = value;
|
||||||
|
OnPropertyChanged(nameof(Address));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 参数值
|
||||||
|
/// </summary>
|
||||||
|
public string Value
|
||||||
|
{
|
||||||
|
get => _value;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (_value != value)
|
||||||
|
{
|
||||||
|
_value = value;
|
||||||
|
OnPropertyChanged(nameof(Value));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 启用状态
|
||||||
|
/// </summary>
|
||||||
|
public bool StartExecute
|
||||||
|
{
|
||||||
|
get => _startexecute;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (_startexecute != value)
|
||||||
|
{
|
||||||
|
_startexecute = value;
|
||||||
|
OnPropertyChanged(nameof(StartExecute));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 顺序
|
||||||
|
/// </summary>
|
||||||
|
public int StartIndex
|
||||||
|
{
|
||||||
|
get => _startindex;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (_startindex != value)
|
||||||
|
{
|
||||||
|
_startindex = value;
|
||||||
|
OnPropertyChanged(nameof(StartIndex));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private CellLink[] cellLinks;
|
||||||
|
[JsonIgnore]
|
||||||
|
public CellLink[] CellLinks
|
||||||
|
{
|
||||||
|
get { return cellLinks; }
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (cellLinks == value) return;
|
||||||
|
cellLinks = value;
|
||||||
|
OnPropertyChanged(nameof(CellLinks));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//private CellTag[] cellTags;
|
||||||
|
//[JsonIgnore]
|
||||||
|
//public CellTag[] CellTags
|
||||||
|
//{
|
||||||
|
// get { return cellTags; }
|
||||||
|
// set
|
||||||
|
// {
|
||||||
|
// if (cellTags == value) return;
|
||||||
|
// cellTags = value;
|
||||||
|
// OnPropertyChanged(nameof(CellTags));
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
78
DH.Commons/Base/VisionEngineBase.cs
Normal file
78
DH.Commons/Base/VisionEngineBase.cs
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
using System.Collections;
|
||||||
|
using System.ComponentModel;
|
||||||
|
using System.Drawing;
|
||||||
|
using System.Drawing.Imaging;
|
||||||
|
using DH.Commons.Enums;
|
||||||
|
using DH.Commons.Helper;
|
||||||
|
using HalconDotNet;
|
||||||
|
using OpenCvSharp;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
namespace DH.Commons.Base
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 视觉处理引擎:1.传统视觉 2.深度学习
|
||||||
|
/// CV深度学习 四大领域
|
||||||
|
/// Image Classification 图像分类:判别图中物体是什么,比如是猫还是狗;
|
||||||
|
/// Semantic Segmentation 语义分割:对图像进行像素级分类,预测每个像素属于的类别,不区分个体;
|
||||||
|
/// Object Detection 目标检测:寻找图像中的物体并进行定位;
|
||||||
|
/// Instance Segmentation 实例分割:定位图中每个物体,并进行像素级标注,区分不同个体;
|
||||||
|
/// </summary>
|
||||||
|
public abstract class VisionEngineBase : DeviceBase
|
||||||
|
{
|
||||||
|
public List<DetectionConfig> DetectionConfigs = new List<DetectionConfig>();
|
||||||
|
#region event
|
||||||
|
public event Action<string, List<double>> OnCropParamsOutput;
|
||||||
|
public event Action<string, Bitmap, List<IShapeElement>> OnDetectionDone;
|
||||||
|
public event Action<string> OnDetectionWarningStop;//有无检测 需要报警停机
|
||||||
|
#endregion
|
||||||
|
//public VisionEngineInitialConfigBase IConfig
|
||||||
|
//{
|
||||||
|
// get => InitialConfig as VisionEngineInitialConfigBase;
|
||||||
|
//}
|
||||||
|
// public ImageSaveHelper ImageSaveHelper { get; set; } = new ImageSaveHelper();
|
||||||
|
public string BatchNO { get; set; }
|
||||||
|
|
||||||
|
public HTuple hv_ModelID;
|
||||||
|
|
||||||
|
public abstract DetectStationResult RunInference(Mat originImgSet, string detectionId = null);
|
||||||
|
|
||||||
|
//public abstract void SaveDetectResultAsync(DetectStationResult detectResult);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public virtual void DetectionDone(string detectionId, Bitmap image, List<IShapeElement> detectionResults)
|
||||||
|
{
|
||||||
|
OnDetectionDone?.Invoke(detectionId, image, detectionResults);
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual void DetectionWarningStop(string detectionDes)
|
||||||
|
{
|
||||||
|
OnDetectionWarningStop?.Invoke(detectionDes);
|
||||||
|
}
|
||||||
|
public ImageSaveHelper ImageSaveHelper { get; set; } = new ImageSaveHelper();
|
||||||
|
public virtual void SaveImageAsync(string fullname, Bitmap saveMap, ImageFormat imageFormat)
|
||||||
|
{
|
||||||
|
if (saveMap != null)
|
||||||
|
{
|
||||||
|
ImageSaveSet imageSaveSet = new ImageSaveSet()
|
||||||
|
{
|
||||||
|
FullName = fullname,
|
||||||
|
SaveImage = saveMap.CopyBitmap(),
|
||||||
|
ImageFormat = imageFormat.DeepSerializeClone()
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
ImageSaveHelper.ImageSaveAsync(imageSaveSet);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,10 +1,35 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk.WindowsDesktop">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net8.0</TargetFramework>
|
<TargetFramework>net8.0-windows</TargetFramework>
|
||||||
<ImplicitUsings>enable</ImplicitUsings>
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
<Nullable>enable</Nullable>
|
<Nullable>enable</Nullable>
|
||||||
<Platforms>AnyCPU;X64</Platforms>
|
<BaseOutputPath>..\</BaseOutputPath>
|
||||||
|
<AppendTargetFrameworkToOutputPath>output</AppendTargetFrameworkToOutputPath>
|
||||||
|
<UseWindowsForms>true</UseWindowsForms>
|
||||||
|
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||||
|
<Platforms>AnyCPU;x64</Platforms>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="AntdUI" Version="1.8.9" />
|
||||||
|
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
||||||
|
<PackageReference Include="OpenCvSharp4" Version="4.10.0.20241108" />
|
||||||
|
<PackageReference Include="OpenCvSharp4.Extensions" Version="4.10.0.20241108" />
|
||||||
|
<PackageReference Include="OpenCvSharp4.runtime.win" Version="4.10.0.20241108" />
|
||||||
|
<PackageReference Include="System.IO.Ports" Version="9.0.3" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<Reference Include="halcondotnet">
|
||||||
|
<HintPath>..\x64\Debug\halcondotnet.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="hdevenginedotnet">
|
||||||
|
<HintPath>..\x64\Debug\hdevenginedotnet.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
@@ -7,12 +7,61 @@ using System.Threading.Tasks;
|
|||||||
|
|
||||||
namespace DH.Commons.Enums
|
namespace DH.Commons.Enums
|
||||||
{
|
{
|
||||||
|
public enum EnumStatus
|
||||||
|
{
|
||||||
|
未运行,
|
||||||
|
运行中,
|
||||||
|
警告,
|
||||||
|
异常
|
||||||
|
}
|
||||||
|
public enum ModelType
|
||||||
|
{
|
||||||
|
图像分类 = 1,
|
||||||
|
目标检测 = 2,
|
||||||
|
语义分割 = 3,
|
||||||
|
实例分割 = 4,
|
||||||
|
目标检测GPU = 5
|
||||||
|
}
|
||||||
|
public enum SelectPicType
|
||||||
|
{
|
||||||
|
[Description("训练图片")]
|
||||||
|
train = 0,
|
||||||
|
[Description("测试图片")]
|
||||||
|
test
|
||||||
|
|
||||||
|
}
|
||||||
|
public enum NetModel
|
||||||
|
{
|
||||||
|
[Description("目标检测")]
|
||||||
|
training = 0,
|
||||||
|
[Description("语义分割")]
|
||||||
|
train_seg,
|
||||||
|
[Description("模型导出")]
|
||||||
|
emport,
|
||||||
|
[Description("推理预测")]
|
||||||
|
infernce
|
||||||
|
|
||||||
|
}
|
||||||
|
public enum EnumCamType
|
||||||
|
{
|
||||||
|
[Description("度申相机")]
|
||||||
|
度申Do3think = 0,
|
||||||
|
[Description("海康相机")]
|
||||||
|
海康hik ,
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public enum EnumPLCType
|
public enum EnumPLCType
|
||||||
{
|
{
|
||||||
信捷XC_串口,
|
[Description("信捷XC串口")]
|
||||||
信捷XC_网口,
|
信捷XC串口 = 0,
|
||||||
信捷XD_串口,
|
[Description("信捷XC网口")]
|
||||||
信捷XD_网口
|
信捷XC网口 = 1,
|
||||||
|
[Description("信捷XD串口")]
|
||||||
|
信捷XD串口 = 2,
|
||||||
|
[Description("信捷XD网口")]
|
||||||
|
信捷XD网口 = 3
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -28,35 +77,70 @@ namespace DH.Commons.Enums
|
|||||||
public enum EnumPLCOutputIO
|
public enum EnumPLCOutputIO
|
||||||
{
|
{
|
||||||
转盘方向=0,
|
转盘方向=0,
|
||||||
转盘速度=1,
|
转盘速度,
|
||||||
转盘使能=2,
|
转盘使能,
|
||||||
转盘启动=3,
|
转盘启动,
|
||||||
转盘清料=4,
|
转盘清料,
|
||||||
指示灯绿=5,
|
指示灯绿,
|
||||||
指示灯黄=6,
|
指示灯黄,
|
||||||
指示灯红=7,
|
指示灯红,
|
||||||
蜂鸣器=8,
|
蜂鸣器,
|
||||||
振动盘=9,
|
振动盘,
|
||||||
皮带=10,
|
皮带,
|
||||||
工位1=11,
|
工位1,
|
||||||
工位2=12,
|
工位2,
|
||||||
工位3=13,
|
工位3,
|
||||||
工位4=14,
|
工位4,
|
||||||
工位5=15,
|
工位5,
|
||||||
OK料盒=16,
|
工位6 ,
|
||||||
NG料盒=17,
|
工位7 ,
|
||||||
OK吹气时间=18,
|
工位8 ,
|
||||||
NG吹气时间=19,
|
工位9 ,
|
||||||
产品计数=20,
|
工位10 ,
|
||||||
计数清零=21,
|
相机触发时间,
|
||||||
工件最小值=22,
|
吹气时间,
|
||||||
工具最大值=23,
|
产品计数,
|
||||||
启用心跳=24,
|
计数清零,
|
||||||
心跳=25
|
工件最小值,
|
||||||
|
工件最大值,
|
||||||
|
启用心跳,
|
||||||
|
心跳地址,
|
||||||
|
挡料电机回原点,
|
||||||
|
挡料电机回原点速度,
|
||||||
|
挡料电机速度,
|
||||||
|
挡料电机顺时针,
|
||||||
|
挡料电机逆时针,
|
||||||
|
挡料电机位置,
|
||||||
|
OK脉冲,
|
||||||
|
NG脉冲,
|
||||||
|
状态复位,
|
||||||
|
启用定位,
|
||||||
|
定位完成脉冲值
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public enum EnumPLCDataType
|
||||||
|
{
|
||||||
|
单字整型,
|
||||||
|
双字整型,
|
||||||
|
浮点型,
|
||||||
|
布尔型
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum EnumBool
|
||||||
|
{
|
||||||
|
关闭,
|
||||||
|
启用
|
||||||
|
}
|
||||||
|
public enum EnumBool1
|
||||||
|
{
|
||||||
|
False,
|
||||||
|
True
|
||||||
|
}
|
||||||
public enum StreamFormat
|
public enum StreamFormat
|
||||||
{
|
{
|
||||||
[Description("8位图像")]
|
[Description("8位图像")]
|
||||||
@@ -542,5 +626,15 @@ namespace DH.Commons.Enums
|
|||||||
//[Description("插补模式")]
|
//[Description("插补模式")]
|
||||||
//Coordinate = 11
|
//Coordinate = 11
|
||||||
}
|
}
|
||||||
|
public enum CameraAcquisitionMode
|
||||||
|
{
|
||||||
|
连续模式=0,
|
||||||
|
触发模式=1
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum CameraTriggerMode
|
||||||
|
{
|
||||||
|
软触发 = 0,
|
||||||
|
硬触发 = 1
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ using System.Linq;
|
|||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace XKRS.Common.Model.SolidMotionCard
|
namespace DH.Commons.Enums
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
64
DH.Commons/Exception/ExceptionHelper.cs
Normal file
64
DH.Commons/Exception/ExceptionHelper.cs
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
using System;
|
||||||
|
using static DH.Commons.Enums.EnumHelper;
|
||||||
|
|
||||||
|
|
||||||
|
namespace DH.Commons.Helper
|
||||||
|
{
|
||||||
|
public enum ExceptionLevel
|
||||||
|
{
|
||||||
|
Info = 0,
|
||||||
|
Warning = 1,
|
||||||
|
Fatal = 2,
|
||||||
|
}
|
||||||
|
|
||||||
|
//public delegate void OnProcessExceptionRaisedDelegate(DateTime dt, ProcessException ex);
|
||||||
|
//[Serializable]
|
||||||
|
public class ProcessException : Exception
|
||||||
|
{
|
||||||
|
public ExceptionLevel Level { get; set; } = ExceptionLevel.Warning;
|
||||||
|
|
||||||
|
public ProcessException()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public ProcessException(Exception ex, ExceptionLevel lvl = ExceptionLevel.Warning) : base(ex.Message, ex)
|
||||||
|
{
|
||||||
|
Level = lvl;
|
||||||
|
ExceptionNotice();
|
||||||
|
}
|
||||||
|
|
||||||
|
public ProcessException(string error, Exception ex = null, ExceptionLevel lvl = ExceptionLevel.Warning) : base(error, ex)
|
||||||
|
{
|
||||||
|
Level = lvl;
|
||||||
|
ExceptionNotice();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ExceptionNotice()
|
||||||
|
{
|
||||||
|
//OnProcessExceptionRaised?.Invoke(DateTime.Now, this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class ExceptionHelper
|
||||||
|
{
|
||||||
|
public static LogLevel LogLevel = LogLevel.Information;
|
||||||
|
public static string GetExceptionMessage(this Exception ex)
|
||||||
|
{
|
||||||
|
string msg = "异常信息:" + ex.Message;
|
||||||
|
if (ex.InnerException != null)
|
||||||
|
{
|
||||||
|
msg += ";\t内部异常信息:" + ex.InnerException.GetExceptionMessage();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (LogLevel <= LogLevel.Assist)
|
||||||
|
{
|
||||||
|
msg += (";\r\n\t\tStackTrace:" + ex.StackTrace);
|
||||||
|
}
|
||||||
|
return msg;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class AuthorityException : ProcessException
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
39
DH.Commons/GlobalVar.cs
Normal file
39
DH.Commons/GlobalVar.cs
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
|
||||||
|
|
||||||
|
namespace DH.Commons.Enums
|
||||||
|
{
|
||||||
|
public static class GlobalVar
|
||||||
|
{
|
||||||
|
|
||||||
|
//public const string SEPERATOR = "|";
|
||||||
|
|
||||||
|
//public static ContainerBuilder Builder { get; set; } = new ContainerBuilder();
|
||||||
|
|
||||||
|
//private static object containerLock = new object();
|
||||||
|
|
||||||
|
//private static IContainer container = null;
|
||||||
|
//public static IContainer Container
|
||||||
|
//{
|
||||||
|
// get
|
||||||
|
// {
|
||||||
|
// if (container == null)
|
||||||
|
// {
|
||||||
|
// lock (containerLock)
|
||||||
|
// {
|
||||||
|
// if (container == null)
|
||||||
|
// {
|
||||||
|
// container = Builder.Build();
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// return container;
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
|
||||||
|
//public static void InitialAutoFac()
|
||||||
|
//{
|
||||||
|
// Container = Builder.Build();
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
}
|
||||||
162
DH.Commons/Helper/AttributeHelper.cs
Normal file
162
DH.Commons/Helper/AttributeHelper.cs
Normal file
@@ -0,0 +1,162 @@
|
|||||||
|
using DH.Commons.Enums;
|
||||||
|
using System;
|
||||||
|
using System.ComponentModel;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
using static DH.Commons.Enums.EnumHelper;
|
||||||
|
|
||||||
|
|
||||||
|
namespace DH.Commons.Enums
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 设备特性,指示该信息的设备类型,适用于设备信息和配置信息
|
||||||
|
/// </summary>
|
||||||
|
public class DeviceAttribute : Attribute
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 设备类型
|
||||||
|
/// </summary>
|
||||||
|
public string TypeCode { get; set; }
|
||||||
|
|
||||||
|
public string TypeDescription { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 特性修饰类别
|
||||||
|
/// </summary>
|
||||||
|
public DeviceAttributeType AttrType { get; set; }
|
||||||
|
|
||||||
|
public DeviceAttribute(string typeCode, string typeDesc, EnumHelper.DeviceAttributeType attrType)
|
||||||
|
{
|
||||||
|
TypeCode = typeCode;
|
||||||
|
TypeDescription = typeDesc;
|
||||||
|
AttrType = attrType;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 预置状态特性 指定该修饰信息的前置状态允许范围
|
||||||
|
/// </summary>
|
||||||
|
public class PreStateAttribute : Attribute
|
||||||
|
{
|
||||||
|
public int PreState { get; set; }
|
||||||
|
public PreStateAttribute(int _preState)
|
||||||
|
{
|
||||||
|
PreState = _preState;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 检查当前待执行操作的前置状态要求是否合法
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="currentState"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public bool CheckPreStateValid(int currentState)
|
||||||
|
{
|
||||||
|
return (currentState & PreState) == currentState;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class ColorSelectAttribute : Attribute
|
||||||
|
{
|
||||||
|
public string SelectedColor { get; set; }
|
||||||
|
public ColorSelectAttribute(string selectedColor)
|
||||||
|
{
|
||||||
|
SelectedColor = selectedColor;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class FontColorSelectAttribute : Attribute
|
||||||
|
{
|
||||||
|
public string SelectedColor { get; set; }
|
||||||
|
public FontColorSelectAttribute(string selectedColor)
|
||||||
|
{
|
||||||
|
SelectedColor = selectedColor;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum InvokeType
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 不公开调用
|
||||||
|
/// </summary>
|
||||||
|
[Description("不公开调用")]
|
||||||
|
NoneInvoke = 0,
|
||||||
|
/// <summary>
|
||||||
|
/// 测试调用
|
||||||
|
/// </summary>
|
||||||
|
[Description("测试调用")]
|
||||||
|
TestInvoke = 1,
|
||||||
|
/// <summary>
|
||||||
|
/// 标定调用
|
||||||
|
/// </summary>
|
||||||
|
[Description("标定调用")]
|
||||||
|
CalibInvoke = 2,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 用来修饰对外开放的调用方法的特性
|
||||||
|
/// 调用方法参数顺序:IOperationConfig,InvokeDevice,SourceDevice
|
||||||
|
/// </summary>
|
||||||
|
public class ProcessMethodAttribute : Attribute
|
||||||
|
{
|
||||||
|
public string MethodCode { get; set; }
|
||||||
|
public string MethodDesc { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 是否提供人工调用测试
|
||||||
|
/// </summary>
|
||||||
|
public InvokeType InvokeType { get; set; }
|
||||||
|
|
||||||
|
public string DeviceType { get; set; }
|
||||||
|
|
||||||
|
public ProcessMethodAttribute(string deviceType, string code, string description, InvokeType invokeType)
|
||||||
|
{
|
||||||
|
DeviceType = deviceType;
|
||||||
|
MethodCode = code;
|
||||||
|
MethodDesc = description;
|
||||||
|
InvokeType = invokeType;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class SwitchDisplayAttribute : Attribute
|
||||||
|
{
|
||||||
|
public string SwitchName { get; set; }
|
||||||
|
|
||||||
|
public bool SwithOnStatus { get; set; } = true;
|
||||||
|
|
||||||
|
public SwitchDisplayAttribute(string name, bool status)
|
||||||
|
{
|
||||||
|
SwitchName = name;
|
||||||
|
SwithOnStatus = status;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class ElementAttribute : Attribute
|
||||||
|
{
|
||||||
|
public string Name { get; set; }
|
||||||
|
|
||||||
|
public string Desc { get; set; }
|
||||||
|
|
||||||
|
public string IconPath { get; set; }
|
||||||
|
|
||||||
|
public bool IsShowInToolBar { get; set; }
|
||||||
|
|
||||||
|
public ElementAttribute(string desc, string iconPath, bool isShowInToolBar = true, [CallerMemberName] string name = "")
|
||||||
|
{
|
||||||
|
Name = name;
|
||||||
|
Desc = desc;
|
||||||
|
IconPath = iconPath;
|
||||||
|
IsShowInToolBar = isShowInToolBar;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class ProcessAttribute : Attribute
|
||||||
|
{
|
||||||
|
public string ProcessCode { get; set; }
|
||||||
|
public DeviceAttributeType AttrType { get; set; }
|
||||||
|
|
||||||
|
public ProcessAttribute(string stationCode, DeviceAttributeType attrType)
|
||||||
|
{
|
||||||
|
ProcessCode = stationCode;
|
||||||
|
AttrType = attrType;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
272
DH.Commons/Helper/ConfigHelper.cs
Normal file
272
DH.Commons/Helper/ConfigHelper.cs
Normal file
@@ -0,0 +1,272 @@
|
|||||||
|
using System;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.IO;
|
||||||
|
using System.Text.Json;
|
||||||
|
using System.Text.Json.Serialization;
|
||||||
|
using AntdUI;
|
||||||
|
using DH.Commons.Base;
|
||||||
|
using DH.Commons.Models;
|
||||||
|
|
||||||
|
namespace DH.Commons.Helper
|
||||||
|
{
|
||||||
|
public static class ConfigHelper
|
||||||
|
{
|
||||||
|
private static readonly JsonSerializerOptions _jsonOptions = new JsonSerializerOptions
|
||||||
|
{
|
||||||
|
WriteIndented = true,
|
||||||
|
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
|
||||||
|
IgnoreNullValues = true
|
||||||
|
};
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 配置存储根目录
|
||||||
|
/// </summary>
|
||||||
|
private static string ConfigsRoot => Path.Combine(
|
||||||
|
AppDomain.CurrentDomain.BaseDirectory,
|
||||||
|
"configs");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取当前方案的主配置文件路径
|
||||||
|
/// </summary>
|
||||||
|
private static string CurrentConfigPath
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
ValidateCurrentScheme();
|
||||||
|
return Path.Combine(
|
||||||
|
ConfigsRoot,
|
||||||
|
$"config_{SystemModel.CurrentScheme}.json");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取当前方案的备份目录路径
|
||||||
|
/// </summary>
|
||||||
|
private static string CurrentBackupDir
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
ValidateCurrentScheme();
|
||||||
|
return Path.Combine(
|
||||||
|
ConfigsRoot,
|
||||||
|
$"bak_{SystemModel.CurrentScheme}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 初始化新方案(创建空文件)
|
||||||
|
/// </summary>
|
||||||
|
public static void InitializeScheme(string scheme)
|
||||||
|
{
|
||||||
|
SystemModel.CurrentScheme = scheme;
|
||||||
|
|
||||||
|
// 创建空配置文件
|
||||||
|
if (!File.Exists(CurrentConfigPath))
|
||||||
|
{
|
||||||
|
Directory.CreateDirectory(ConfigsRoot);
|
||||||
|
File.WriteAllText(CurrentConfigPath, "{}");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 创建备份目录
|
||||||
|
Directory.CreateDirectory(CurrentBackupDir);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 保存当前配置(自动备份)
|
||||||
|
/// </summary>
|
||||||
|
public static void SaveConfig()
|
||||||
|
{
|
||||||
|
ValidateCurrentScheme();
|
||||||
|
|
||||||
|
// 确保配置目录存在
|
||||||
|
Directory.CreateDirectory(ConfigsRoot);
|
||||||
|
|
||||||
|
// 备份现有配置
|
||||||
|
if (File.Exists(CurrentConfigPath))
|
||||||
|
{
|
||||||
|
var backupName = $"config_{SystemModel.CurrentScheme}_{DateTime.Now:yyyyMMddHHmmss}.json";
|
||||||
|
var backupPath = Path.Combine(CurrentBackupDir, backupName);
|
||||||
|
|
||||||
|
Directory.CreateDirectory(CurrentBackupDir);
|
||||||
|
File.Copy(CurrentConfigPath, backupPath);
|
||||||
|
}
|
||||||
|
//重置标签文件路径和内容
|
||||||
|
ConfigModel.DetectionList.ForEach(config =>
|
||||||
|
{
|
||||||
|
GenerateLabelFile(config);
|
||||||
|
});
|
||||||
|
|
||||||
|
// 序列化当前配置
|
||||||
|
var json = JsonSerializer.Serialize(new
|
||||||
|
{
|
||||||
|
ConfigModel.CameraBaseList,
|
||||||
|
ConfigModel.PLCBaseList,
|
||||||
|
ConfigModel.DetectionList,
|
||||||
|
ConfigModel.GlobalList,
|
||||||
|
}, _jsonOptions);
|
||||||
|
|
||||||
|
// 写入新配置
|
||||||
|
File.WriteAllText(CurrentConfigPath, json);
|
||||||
|
}
|
||||||
|
private static void GenerateLabelFile(DetectionConfig config)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (config.DetectionLableList == null || string.IsNullOrEmpty(config.In_lable_path))
|
||||||
|
return;
|
||||||
|
|
||||||
|
// 确保目录存在
|
||||||
|
var directory = Path.GetDirectoryName(config.In_lable_path);
|
||||||
|
if (!string.IsNullOrEmpty(directory) && !Directory.Exists(directory))
|
||||||
|
{
|
||||||
|
Directory.CreateDirectory(directory);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 写入文件内容
|
||||||
|
using (var writer = new StreamWriter(config.In_lable_path, false))
|
||||||
|
{
|
||||||
|
foreach (var label in config.DetectionLableList)
|
||||||
|
{
|
||||||
|
// 根据实际需求格式化输出
|
||||||
|
writer.WriteLine(label.LabelName.ToString()); // 假设DetectionLable重写了ToString()
|
||||||
|
|
||||||
|
// 或者明确指定格式:
|
||||||
|
// writer.WriteLine($"{label.Id},{label.Name},{label.Confidence}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Debug.WriteLine($"生成标签文件失败: {ex.Message}");
|
||||||
|
// 可以考虑记录更详细的日志
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// 加载当前方案配置
|
||||||
|
/// </summary>
|
||||||
|
public static void LoadConfig()
|
||||||
|
{
|
||||||
|
ValidateCurrentScheme();
|
||||||
|
|
||||||
|
if (!File.Exists(CurrentConfigPath))
|
||||||
|
{
|
||||||
|
InitializeScheme(SystemModel.CurrentScheme);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var json = File.ReadAllText(CurrentConfigPath);
|
||||||
|
var data = JsonSerializer.Deserialize<ConfigData>(json, _jsonOptions);
|
||||||
|
|
||||||
|
ConfigModel.CameraBaseList = data?.Cameras ?? new List<CameraBase>();
|
||||||
|
ConfigModel.DetectionList = data?.Detections ?? new List<DetectionConfig>();
|
||||||
|
ConfigModel.PLCBaseList = data?.PLCs ?? new List<PLCBase>();
|
||||||
|
ConfigModel.GlobalList = data?.GlobalConfigs ?? new List<GlobalConfig>();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 验证当前方案有效性
|
||||||
|
/// </summary>
|
||||||
|
private static void ValidateCurrentScheme()
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(SystemModel.CurrentScheme))
|
||||||
|
throw new InvalidOperationException("当前方案未设置");
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// 派生新方案(基于当前方案创建副本)
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="newSchemeName">新方案名称</param>
|
||||||
|
public static void DeriveScheme(string newSchemeName)
|
||||||
|
{
|
||||||
|
// 验证输入
|
||||||
|
if (string.IsNullOrWhiteSpace(newSchemeName))
|
||||||
|
{
|
||||||
|
throw new ArgumentException("新方案名称不能为空");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 验证当前方案是否有效
|
||||||
|
ValidateCurrentScheme();
|
||||||
|
|
||||||
|
// 检查新方案是否已存在
|
||||||
|
var newConfigPath = Path.Combine(ConfigsRoot, $"config_{newSchemeName}.json");
|
||||||
|
if (File.Exists(newConfigPath))
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException($"方案 {newSchemeName} 已存在");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 保存当前配置确保最新
|
||||||
|
SaveConfig();
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// 复制配置文件
|
||||||
|
File.Copy(CurrentConfigPath, newConfigPath);
|
||||||
|
|
||||||
|
// 创建备份目录
|
||||||
|
var newBackupDir = Path.Combine(ConfigsRoot, $"bak_{newSchemeName}");
|
||||||
|
Directory.CreateDirectory(newBackupDir);
|
||||||
|
|
||||||
|
// 可选:自动切换新方案
|
||||||
|
// SystemModel.CurrentScheme = newSchemeName;
|
||||||
|
}
|
||||||
|
catch (IOException ex)
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException($"方案派生失败: {ex.Message}", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 删除指定方案的配置文件及备份目录
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="schemeName">要删除的方案名称</param>
|
||||||
|
/// <exception cref="ArgumentException">当方案名称为空时抛出</exception>
|
||||||
|
/// <exception cref="IOException">文件操作失败时抛出</exception>
|
||||||
|
public static void DeleteSchemeConfig(string schemeName)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(schemeName))
|
||||||
|
throw new ArgumentException("方案名称无效");
|
||||||
|
|
||||||
|
// 构造路径
|
||||||
|
var configPath = Path.Combine(ConfigsRoot, $"config_{schemeName}.json");
|
||||||
|
var backupDir = Path.Combine(ConfigsRoot, $"bak_{schemeName}");
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// 删除配置文件
|
||||||
|
if (File.Exists(configPath))
|
||||||
|
{
|
||||||
|
File.Delete(configPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 删除备份目录(递归删除)
|
||||||
|
if (Directory.Exists(backupDir))
|
||||||
|
{
|
||||||
|
Directory.Delete(backupDir, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex) when (ex is IOException || ex is UnauthorizedAccessException)
|
||||||
|
{
|
||||||
|
throw new IOException($"删除方案 {schemeName} 的配置文件失败: {ex.Message}", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 配置数据模型(内部类)
|
||||||
|
/// </summary>
|
||||||
|
private class ConfigData
|
||||||
|
{
|
||||||
|
[JsonPropertyName("cameraBaseList")]
|
||||||
|
public List<CameraBase> Cameras { get; set; } = new List<CameraBase>();
|
||||||
|
|
||||||
|
[JsonPropertyName("plcBaseList")]
|
||||||
|
public List<PLCBase> PLCs { get; set; } = new List<PLCBase>();
|
||||||
|
|
||||||
|
[JsonPropertyName("detectionList")]
|
||||||
|
public List<DetectionConfig> Detections { get; set; } = new List<DetectionConfig>();
|
||||||
|
[JsonPropertyName("globalList")]
|
||||||
|
public List<GlobalConfig> GlobalConfigs { get; set; } = new List<GlobalConfig>();
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
779
DH.Commons/Helper/EnumHelper.cs
Normal file
779
DH.Commons/Helper/EnumHelper.cs
Normal file
@@ -0,0 +1,779 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.ComponentModel;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
|
|
||||||
|
namespace DH.Commons.Enums
|
||||||
|
{
|
||||||
|
public static class EnumHelper
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 根据枚举的代码名称获取枚举列表信息
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="enumName"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static List<dynamic> GetEnumListByName(string enumName, string assemblyName = "Common.Model.Helper.EnumHelper+")
|
||||||
|
{
|
||||||
|
List<dynamic> list = new List<dynamic>();
|
||||||
|
|
||||||
|
string fullName = assemblyName + enumName;
|
||||||
|
|
||||||
|
Type t = typeof(EnumHelper).Assembly.GetType(fullName);
|
||||||
|
|
||||||
|
t.GetEnumNames().ToList().ForEach(e =>
|
||||||
|
{
|
||||||
|
int value = Convert.ToInt32(Enum.Parse(t, e));
|
||||||
|
string desc = ((Enum)Enum.Parse(t, e)).GetEnumDescription();
|
||||||
|
var item = new { Value = value, Desc = desc, Code = e };
|
||||||
|
list.Add(item);
|
||||||
|
});
|
||||||
|
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取枚举的列表信息,一般供下拉列表使用
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="enumType">枚举类型</param>
|
||||||
|
/// <returns>Desc:中文描述 Value:整形值 Code:枚举值</returns>
|
||||||
|
public static List<dynamic> GetEnumListByType(Type enumType)
|
||||||
|
{
|
||||||
|
List<dynamic> list = new List<dynamic>();
|
||||||
|
|
||||||
|
enumType.GetEnumNames().ToList().ForEach(e =>
|
||||||
|
{
|
||||||
|
int value = Convert.ToInt32(Enum.Parse(enumType, e));
|
||||||
|
string desc = ((Enum)Enum.Parse(enumType, e)).GetEnumDescription();
|
||||||
|
var item = new { Value = value, Desc = desc, Code = e };
|
||||||
|
list.Add(item);
|
||||||
|
});
|
||||||
|
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取具体某一枚举的中文描述
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="enumObj"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static string GetEnumDescription(this Enum enumObj)
|
||||||
|
{
|
||||||
|
Type t = enumObj.GetType();
|
||||||
|
FieldInfo f = t.GetField(enumObj.ToString());
|
||||||
|
if (f == null)
|
||||||
|
{
|
||||||
|
return enumObj.ToString();
|
||||||
|
}
|
||||||
|
DescriptionAttribute attr = f.GetCustomAttribute<DescriptionAttribute>();
|
||||||
|
if (attr != null)
|
||||||
|
{
|
||||||
|
return attr.Description;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return enumObj.ToString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 根据描述获取枚举值(泛型方法)
|
||||||
|
public static T GetEnumFromDescription<T>(string description) where T : Enum
|
||||||
|
{
|
||||||
|
Type enumType = typeof(T);
|
||||||
|
foreach (T value in Enum.GetValues(enumType))
|
||||||
|
{
|
||||||
|
string desc = GetEnumDescription(value);
|
||||||
|
if (desc == description)
|
||||||
|
{
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw new ArgumentException($"在枚举 {enumType.Name} 中未找到描述为 '{description}' 的值");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取枚举类型的所有描述文本
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="enumType">枚举类型</param>
|
||||||
|
/// <returns>描述文本列表</returns>
|
||||||
|
public static List<string> GetEnumDescriptions(Type enumType)
|
||||||
|
{
|
||||||
|
// 验证类型是否为枚举
|
||||||
|
if (!enumType.IsEnum)
|
||||||
|
throw new ArgumentException("传入的类型必须是枚举类型", nameof(enumType));
|
||||||
|
|
||||||
|
var descriptions = new List<string>();
|
||||||
|
|
||||||
|
foreach (var value in Enum.GetValues(enumType))
|
||||||
|
{
|
||||||
|
var fieldInfo = enumType.GetField(value.ToString());
|
||||||
|
var attribute = fieldInfo.GetCustomAttribute<DescriptionAttribute>();
|
||||||
|
descriptions.Add(attribute?.Description ?? value.ToString());
|
||||||
|
}
|
||||||
|
|
||||||
|
return descriptions;
|
||||||
|
}
|
||||||
|
public static string GetEnumDescription1(Enum value)
|
||||||
|
{
|
||||||
|
var field = value.GetType().GetField(value.ToString());
|
||||||
|
var attribute = field.GetCustomAttributes(typeof(DescriptionAttribute), false)
|
||||||
|
.FirstOrDefault() as DescriptionAttribute;
|
||||||
|
return attribute?.Description ?? value.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static System.Drawing.Color GetEnumSelectedColor(this Enum enumObj)
|
||||||
|
{
|
||||||
|
Type t = enumObj.GetType();
|
||||||
|
FieldInfo f = t.GetField(enumObj.ToString());
|
||||||
|
|
||||||
|
ColorSelectAttribute attr = f.GetCustomAttribute<ColorSelectAttribute>();
|
||||||
|
if (attr != null)
|
||||||
|
{
|
||||||
|
return System.Drawing.Color.FromName(attr.SelectedColor);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return System.Drawing.Color.Transparent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static System.Drawing.Color GetEnumSelectedFontColor(this Enum enumObj)
|
||||||
|
{
|
||||||
|
Type t = enumObj.GetType();
|
||||||
|
FieldInfo f = t.GetField(enumObj.ToString());
|
||||||
|
|
||||||
|
var attr = f.GetCustomAttribute<FontColorSelectAttribute>();
|
||||||
|
if (attr != null)
|
||||||
|
{
|
||||||
|
return System.Drawing.Color.FromName(attr.SelectedColor);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return System.Drawing.Color.Transparent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
[Flags]
|
||||||
|
public enum DeviceAttributeType
|
||||||
|
{
|
||||||
|
[Description("设备驱动")]
|
||||||
|
Device = 1,
|
||||||
|
|
||||||
|
[Description("初始配置")]
|
||||||
|
InitialConfig = 2,
|
||||||
|
[Description("操作配置")]
|
||||||
|
OperationConfig = 4,
|
||||||
|
[Description("设备配置")]
|
||||||
|
DeviceConfig = 8,
|
||||||
|
[Description("输入配置")]
|
||||||
|
InputConfig = 16,
|
||||||
|
|
||||||
|
[Description("初始配置控件")]
|
||||||
|
InitialConfigCtrl = 32,
|
||||||
|
[Description("操作配置控件")]
|
||||||
|
OperationConfigCtrl = 64,
|
||||||
|
[Description("设备配置控件")]
|
||||||
|
DeviceConfigCtrl = 128,
|
||||||
|
[Description("输入配置控件")]
|
||||||
|
InputConfigCtrl = 256,
|
||||||
|
|
||||||
|
[Description("运行控件")]
|
||||||
|
RunCtrl = 512,
|
||||||
|
|
||||||
|
[Description("操作配置面板")]
|
||||||
|
OperationConfigPanel = 1024,
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum EnableState
|
||||||
|
{
|
||||||
|
[Description("启用")]
|
||||||
|
Enabled = 0,
|
||||||
|
[Description("禁用")]
|
||||||
|
Disabled = 1,
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum EnableStateFilter
|
||||||
|
{
|
||||||
|
[Description("全部")]
|
||||||
|
All = -1,
|
||||||
|
[Description("启用")]
|
||||||
|
Enabled = 0,
|
||||||
|
[Description("禁用")]
|
||||||
|
Disabled = 1,
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum OutputResult
|
||||||
|
{
|
||||||
|
[Description("OK")]
|
||||||
|
OK = 1,
|
||||||
|
[Description("NG")]
|
||||||
|
NG = 2,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// PLC项目的值的类型
|
||||||
|
/// </summary>
|
||||||
|
public enum PLCItemType
|
||||||
|
{
|
||||||
|
[Description("布尔类型")]
|
||||||
|
Bool = 0,
|
||||||
|
[Description("整型")]
|
||||||
|
Integer = 1,
|
||||||
|
[Description("字符串型")]
|
||||||
|
String = 2,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 对PLC项目的操作类型
|
||||||
|
/// </summary>
|
||||||
|
public enum PLCOpType
|
||||||
|
{
|
||||||
|
[Description("读取")]
|
||||||
|
Read = 1,
|
||||||
|
[Description("写入")]
|
||||||
|
Write = 2,
|
||||||
|
[Description("监控")]
|
||||||
|
Monitor = 4,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 报警监控 1+8
|
||||||
|
/// </summary>
|
||||||
|
[Description("报警监控")]
|
||||||
|
WarningMonitor = 9,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// CT监控 1+16
|
||||||
|
/// </summary>
|
||||||
|
[Description("CT监控")]
|
||||||
|
CTMonitor = 17,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 相机运行模式
|
||||||
|
/// </summary>
|
||||||
|
public enum CameraOpMode
|
||||||
|
{
|
||||||
|
[Description("单次拍照")]
|
||||||
|
SingleSnapShot = 1,
|
||||||
|
[Description("连续模式")]
|
||||||
|
ContinuousMode = 2,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 日志类型
|
||||||
|
/// </summary>
|
||||||
|
public enum LogType
|
||||||
|
{
|
||||||
|
[Description("警告信息")]
|
||||||
|
Exception_Warning = 1,
|
||||||
|
[Description("错误信息")]
|
||||||
|
Exception_Error = 2,
|
||||||
|
[Description("致命信息")]
|
||||||
|
Exception_Fatal = 3,
|
||||||
|
|
||||||
|
[Description("设备信息")]
|
||||||
|
Info_Device = 11,
|
||||||
|
[Description("工序信息")]
|
||||||
|
Info_Process = 12,
|
||||||
|
[Description("操作信息")]
|
||||||
|
Info_Operation = 13,
|
||||||
|
|
||||||
|
[Description("用户操作信息")]
|
||||||
|
User_Operation = 21,
|
||||||
|
|
||||||
|
[Description("测量结果")]
|
||||||
|
MeasureResult = 31,
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum LogLevel
|
||||||
|
{
|
||||||
|
[Description("详细")]
|
||||||
|
[ColorSelect("White")]
|
||||||
|
[FontColorSelect("Green")]
|
||||||
|
Detail = 2,
|
||||||
|
[Description("信息")]
|
||||||
|
[ColorSelect("White")]
|
||||||
|
[FontColorSelect("Dark")]
|
||||||
|
Information = 3,
|
||||||
|
[Description("辅助")]
|
||||||
|
[ColorSelect("White")]
|
||||||
|
[FontColorSelect("Blue")]
|
||||||
|
Assist = 4,
|
||||||
|
[Description("动作")]
|
||||||
|
[ColorSelect("DarkGreen")]
|
||||||
|
[FontColorSelect("Yellow")]
|
||||||
|
Action = 5,
|
||||||
|
[Description("错误")]
|
||||||
|
[ColorSelect("Orange")]
|
||||||
|
[FontColorSelect("White")]
|
||||||
|
Error = 6,
|
||||||
|
[Description("警报")]
|
||||||
|
[ColorSelect("Brown")]
|
||||||
|
[FontColorSelect("White")]
|
||||||
|
Warning = 7,
|
||||||
|
[Description("异常")]
|
||||||
|
[ColorSelect("Red")]
|
||||||
|
[FontColorSelect("White")]
|
||||||
|
Exception = 8,
|
||||||
|
}
|
||||||
|
//public enum CameraDriverType
|
||||||
|
//{
|
||||||
|
// Halcon,
|
||||||
|
// //HalconPlugIn,
|
||||||
|
// Hik,
|
||||||
|
//}
|
||||||
|
|
||||||
|
//public enum ImageType
|
||||||
|
//{
|
||||||
|
// Bmp,
|
||||||
|
// Png,
|
||||||
|
// Jpeg,
|
||||||
|
//}
|
||||||
|
|
||||||
|
//public enum ReplyValue
|
||||||
|
//{
|
||||||
|
// OK = 1,
|
||||||
|
// NG = -1,
|
||||||
|
// IGNORE = -999,
|
||||||
|
//}
|
||||||
|
public enum DeviceState
|
||||||
|
{
|
||||||
|
TBD = -1,
|
||||||
|
|
||||||
|
[ColorSelect("Gray")]
|
||||||
|
[FontColorSelect("Black")]
|
||||||
|
[Description("未初始化")]
|
||||||
|
DSUninit = 1,
|
||||||
|
|
||||||
|
[ColorSelect("Gold")]
|
||||||
|
[FontColorSelect("White")]
|
||||||
|
[PreState(1 + 2 + 4 + 8 + 32)]
|
||||||
|
[Description("初始化")]
|
||||||
|
DSInit = 2,
|
||||||
|
|
||||||
|
[ColorSelect("Lime")]
|
||||||
|
[FontColorSelect("Black")]
|
||||||
|
[PreState(2 + 4 + 16)]
|
||||||
|
[Description("运行中")]
|
||||||
|
DSOpen = 4,
|
||||||
|
|
||||||
|
[ColorSelect("Gray")]
|
||||||
|
[FontColorSelect("White")]
|
||||||
|
[PreState(1 + 4 + 8 + 16 + 32)]
|
||||||
|
[Description("关闭")]
|
||||||
|
DSClose = 8,
|
||||||
|
|
||||||
|
[ColorSelect("Gold")]
|
||||||
|
[FontColorSelect("White")]
|
||||||
|
[PreState(4 + 16)]
|
||||||
|
[Description("暂停")]
|
||||||
|
DSPause = 16,
|
||||||
|
|
||||||
|
[ColorSelect("Red")]
|
||||||
|
[FontColorSelect("White")]
|
||||||
|
[Description("异常")]
|
||||||
|
DSExcept = 32
|
||||||
|
}
|
||||||
|
public enum RunState
|
||||||
|
{
|
||||||
|
[ColorSelect("Gold")]
|
||||||
|
[Description("空闲")]
|
||||||
|
Idle = 1,
|
||||||
|
[ColorSelect("Lime")]
|
||||||
|
[Description("运行中")]
|
||||||
|
Running = 2,
|
||||||
|
[ColorSelect("Gray")]
|
||||||
|
[Description("停止")]
|
||||||
|
Stop = 3,
|
||||||
|
[ColorSelect("Red")]
|
||||||
|
[Description("宕机")]
|
||||||
|
Down = 99,
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum PriorityDirection
|
||||||
|
{
|
||||||
|
X,
|
||||||
|
Y,
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum ElementState
|
||||||
|
{
|
||||||
|
New = 1,
|
||||||
|
MouseHover = 2,
|
||||||
|
MouseInSide = 3,
|
||||||
|
Selected = 4,
|
||||||
|
Moving = 5,
|
||||||
|
Editing = 6,
|
||||||
|
|
||||||
|
Normal = 11,
|
||||||
|
|
||||||
|
Measuring = 21,
|
||||||
|
MeasureDoneOK = 22,
|
||||||
|
MeasureDoneNG = 23,
|
||||||
|
|
||||||
|
CanStretchLeft = 41,
|
||||||
|
CanStretchRight = 42,
|
||||||
|
CanStretchTop = 43,
|
||||||
|
CanStretchBottom = 44,
|
||||||
|
|
||||||
|
CanStretchLeftUpperCorner = 45,
|
||||||
|
CanStretchLeftLowerCorner = 46,
|
||||||
|
CanStretchRightUpperCorner = 47,
|
||||||
|
CanStretchRightLowerCorner = 48,
|
||||||
|
|
||||||
|
StretchingLeft = 31,
|
||||||
|
StretchingRight = 32,
|
||||||
|
StretchingTop = 33,
|
||||||
|
StretchingBottom = 34,
|
||||||
|
|
||||||
|
StretchingLeftUpperCorner = 35,
|
||||||
|
StretchingLeftLowerCorner = 36,
|
||||||
|
StretchingRightUpperCorner = 37,
|
||||||
|
StretchingRightLowerCorner = 38,
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum MouseState
|
||||||
|
{
|
||||||
|
Normal = 1,
|
||||||
|
HoverElement = 2,
|
||||||
|
InSideElement = 3,
|
||||||
|
|
||||||
|
MoveElement = 4,
|
||||||
|
|
||||||
|
StretchingLeft = 11,
|
||||||
|
StretchingRight = 12,
|
||||||
|
StretchingTop = 13,
|
||||||
|
StretchingBottom = 14,
|
||||||
|
|
||||||
|
StretchingLeftUpperCorner = 15,
|
||||||
|
StretchingLeftLowerCorner = 16,
|
||||||
|
StretchingRightUpperCorner = 17,
|
||||||
|
StretchingRightLowerCorner = 18,
|
||||||
|
|
||||||
|
New = 21,
|
||||||
|
Editing = 22,
|
||||||
|
//SelectedElement = 23,
|
||||||
|
|
||||||
|
MovingAll = 31,
|
||||||
|
|
||||||
|
SelectionZone = 41,
|
||||||
|
SelectionZoneDoing = 42,
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum RunMode
|
||||||
|
{
|
||||||
|
[Description("正常运行模式")]
|
||||||
|
NormalMode = 1,
|
||||||
|
[Description("调试模式")]
|
||||||
|
DebugMode = 0,
|
||||||
|
[Description("模拟模式")]
|
||||||
|
DemoMode = 2,
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum MoveType
|
||||||
|
{
|
||||||
|
[Description("绝对运动")]
|
||||||
|
AbsoluteMove = 1,
|
||||||
|
[Description("机器人坐标系相对运动")]
|
||||||
|
RobotRelativeMove = 2,
|
||||||
|
[Description("相对某个基准点位的相对运动")]
|
||||||
|
BasedPointRelativeMove = 3,
|
||||||
|
[Description("回原点")]
|
||||||
|
Origin = 4,
|
||||||
|
[Description("左侧姿势")]
|
||||||
|
LeftPose = 6,
|
||||||
|
[Description("右侧姿势")]
|
||||||
|
RightPose = 5,
|
||||||
|
[Description("前侧姿势")]
|
||||||
|
FrontPose = 7,
|
||||||
|
[Description("相机坐标系相对运动")]
|
||||||
|
CameraRelativeMove = 12,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 马达/运动板卡运行模式
|
||||||
|
/// </summary>
|
||||||
|
public enum MotionMode
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 普通点位运动
|
||||||
|
/// </summary>
|
||||||
|
[Description("普通点位运动")]
|
||||||
|
P2P = 1,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 找正限位运动
|
||||||
|
/// </summary>
|
||||||
|
[Description("找正限位运动")]
|
||||||
|
FindPositive = 4,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 离开正限位
|
||||||
|
/// </summary>
|
||||||
|
[Description("离开正限位")]
|
||||||
|
LeavePositive = 5,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 找负限位运动
|
||||||
|
/// </summary>
|
||||||
|
[Description("找负限位运动")]
|
||||||
|
FindNegative = 6,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 离开负限位
|
||||||
|
/// </summary>
|
||||||
|
[Description("离开负限位")]
|
||||||
|
LeaveNegative = 7,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 找原点运动
|
||||||
|
/// </summary>
|
||||||
|
[Description("回原点运动")]
|
||||||
|
GoHome = 8,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Jog模式
|
||||||
|
/// </summary>
|
||||||
|
[Description("Jog模式")]
|
||||||
|
Jog = 9,
|
||||||
|
|
||||||
|
///// <summary>
|
||||||
|
///// 读数头找原点方式
|
||||||
|
///// </summary>
|
||||||
|
//[Description("找原点inde")]
|
||||||
|
//FindOriIndex = 10,
|
||||||
|
|
||||||
|
///// <summary>
|
||||||
|
///// 插补模式
|
||||||
|
///// </summary>
|
||||||
|
//[Description("插补模式")]
|
||||||
|
//Coordinate = 11
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// IO预定义类型 主要针对输出
|
||||||
|
/// </summary>
|
||||||
|
public enum IOPrestatement
|
||||||
|
{
|
||||||
|
[Description("自定义")]
|
||||||
|
Customized = 0,
|
||||||
|
|
||||||
|
[Description("指示灯-黄")]
|
||||||
|
Light_Yellow = 1,
|
||||||
|
[Description("指示灯-绿")]
|
||||||
|
Light_Green = 2,
|
||||||
|
[Description("指示灯-红")]
|
||||||
|
Light_Red = 3,
|
||||||
|
[Description("蜂鸣器")]
|
||||||
|
Beep = 4,
|
||||||
|
[Description("照明灯")]
|
||||||
|
Light = 5,
|
||||||
|
|
||||||
|
[Description("急停")]
|
||||||
|
EmergencyStop = 99,
|
||||||
|
}
|
||||||
|
|
||||||
|
///// <summary>
|
||||||
|
///// GTS运动板卡控制返回控制码
|
||||||
|
///// </summary>
|
||||||
|
//public enum GTSRetCode
|
||||||
|
//{
|
||||||
|
// [Description("指令执行成功")]
|
||||||
|
// GRCRunOK = 0, // 指令执行成功
|
||||||
|
// [Description("指令执行错误")]
|
||||||
|
// GRCRunErr = 1, // 指令执行错误
|
||||||
|
// [Description("icense不支持")]
|
||||||
|
// GRCNotSupport = 2, // icense不支持
|
||||||
|
// [Description("指令参数错误")]
|
||||||
|
// GRCInvalidParam = 7, // 指令参数错误
|
||||||
|
// [Description("主机和运动控制器通讯失败")]
|
||||||
|
// GRCCommErr = -1, // 主机和运动控制器通讯失败
|
||||||
|
// [Description("打开控制器失败")]
|
||||||
|
// GRCOpenErr = -6, // 打开控制器失败
|
||||||
|
// [Description("运动控制器没有响应")]
|
||||||
|
// GRCNotAck = -7 // 运动控制器没有响应
|
||||||
|
//}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 运动板卡 IO 类型(IN OUT)
|
||||||
|
/// </summary>
|
||||||
|
public enum IOType
|
||||||
|
{
|
||||||
|
[Description("INPUT")]
|
||||||
|
INPUT = 0,
|
||||||
|
[Description("OUTPUT")]
|
||||||
|
OUTPUT = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum IOValue
|
||||||
|
{
|
||||||
|
[Description("关闭")]
|
||||||
|
FALSE = 0,
|
||||||
|
[Description("开启")]
|
||||||
|
TRUE = 1,
|
||||||
|
[Description("反转")]
|
||||||
|
REVERSE = 2,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// PubSubCenter事件中心的消息类型
|
||||||
|
/// </summary>
|
||||||
|
public enum PubSubCenterMessageType
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 运行界面更新产品下拉
|
||||||
|
/// </summary>
|
||||||
|
[Description("更新产品下拉")]
|
||||||
|
UpdateProductionCodes,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 流程是否关闭
|
||||||
|
/// </summary>
|
||||||
|
[Description("流程是否打开")]
|
||||||
|
IsProcessOpened,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 清除数据
|
||||||
|
/// </summary>
|
||||||
|
[Description("清除数据")]
|
||||||
|
ClearData,
|
||||||
|
/// <summary>
|
||||||
|
/// 更新批次信息
|
||||||
|
/// </summary>
|
||||||
|
[Description("更新批次信息")]
|
||||||
|
UpdateBatchNO,
|
||||||
|
/// <summary>
|
||||||
|
/// 请求批次信息
|
||||||
|
/// </summary>
|
||||||
|
[Description("更新批次信息")]
|
||||||
|
RequestBatchNO,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 模型检测异常
|
||||||
|
/// </summary>
|
||||||
|
[Description("模型检测异常")]
|
||||||
|
MLDetectException,
|
||||||
|
}
|
||||||
|
public enum SizeEnum
|
||||||
|
{
|
||||||
|
[Description("圆形测量")]
|
||||||
|
圆形测量 = 1,
|
||||||
|
[Description("直线测量")]
|
||||||
|
直线测量 = 2,
|
||||||
|
[Description("线线测量")]
|
||||||
|
线线测量 = 3,
|
||||||
|
[Description("线圆测量")]
|
||||||
|
线圆测量 = 4,
|
||||||
|
[Description("高度测量")]
|
||||||
|
高度测量 = 5,
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum MachineState
|
||||||
|
{
|
||||||
|
Unknown = 0,
|
||||||
|
Ready = 1,
|
||||||
|
Running = 2,
|
||||||
|
Alarm = 3,
|
||||||
|
Pause = 4,
|
||||||
|
Resetting = 5,
|
||||||
|
Closing = 6,
|
||||||
|
ClearProduct = 7,
|
||||||
|
Warning = 8,
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum ResultState
|
||||||
|
{
|
||||||
|
[Description("NA")]
|
||||||
|
NA = -5,
|
||||||
|
[Description("尺寸NG")]
|
||||||
|
SizeNG = -4,
|
||||||
|
[Description("检测NG")]
|
||||||
|
DetectNG = -3,
|
||||||
|
|
||||||
|
//[Description("检测不足TBD")]
|
||||||
|
// ShortageTBD = -2,
|
||||||
|
[Description("检测结果TBD")]
|
||||||
|
ResultTBD = -1,
|
||||||
|
[Description("OK")]
|
||||||
|
OK = 1,
|
||||||
|
// [Description("NG")]
|
||||||
|
// NG = 2,
|
||||||
|
//统计结果
|
||||||
|
[Description("A类NG")]
|
||||||
|
A_NG = 25,
|
||||||
|
[Description("B类NG")]
|
||||||
|
B_NG = 26,
|
||||||
|
[Description("C类NG")]
|
||||||
|
C_NG = 27,
|
||||||
|
}
|
||||||
|
public enum HikCameraType
|
||||||
|
{
|
||||||
|
[Description("HikCamera-Gige")]
|
||||||
|
Gige = 0,
|
||||||
|
[Description("HikCamera-USB")]
|
||||||
|
USB = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 光源操作
|
||||||
|
/// </summary>
|
||||||
|
public enum LightOperation
|
||||||
|
{
|
||||||
|
[Description("打开")]
|
||||||
|
Open = 1,
|
||||||
|
[Description("关闭")]
|
||||||
|
Close = 2,
|
||||||
|
[Description("写入")]
|
||||||
|
Write = 3,
|
||||||
|
[Description("读取")]
|
||||||
|
Read = 4,
|
||||||
|
[Description("频闪")]
|
||||||
|
Flash = 5,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 监听反馈数据值
|
||||||
|
/// </summary>
|
||||||
|
public enum ReturnValue
|
||||||
|
{
|
||||||
|
OKVALUE = 1,
|
||||||
|
NGVALUE = -1,
|
||||||
|
EXCEPTIONVALUE = -2,
|
||||||
|
UNAUTHORIZATION = -10,
|
||||||
|
IGNORE = -999,
|
||||||
|
}
|
||||||
|
|
||||||
|
//public enum LogLevel
|
||||||
|
//{
|
||||||
|
// [Description("详细")]
|
||||||
|
// [ColorSelect("White")]
|
||||||
|
// [FontColorSelect("Green")]
|
||||||
|
// Detail = 2,
|
||||||
|
// [Description("信息")]
|
||||||
|
// [ColorSelect("White")]
|
||||||
|
// [FontColorSelect("Dark")]
|
||||||
|
// Information = 3,
|
||||||
|
// [Description("辅助")]
|
||||||
|
// [ColorSelect("White")]
|
||||||
|
// [FontColorSelect("Blue")]
|
||||||
|
// Assist = 4,
|
||||||
|
// [Description("动作")]
|
||||||
|
// [ColorSelect("DarkGreen")]
|
||||||
|
// [FontColorSelect("Yellow")]
|
||||||
|
// Action = 5,
|
||||||
|
// [Description("错误")]
|
||||||
|
// [ColorSelect("Orange")]
|
||||||
|
// [FontColorSelect("White")]
|
||||||
|
// Error = 6,
|
||||||
|
// [Description("警报")]
|
||||||
|
// [ColorSelect("Brown")]
|
||||||
|
// [FontColorSelect("White")]
|
||||||
|
// Warning = 7,
|
||||||
|
// [Description("异常")]
|
||||||
|
// [ColorSelect("Red")]
|
||||||
|
// [FontColorSelect("White")]
|
||||||
|
// Exception = 8,
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
}
|
||||||
677
DH.Commons/Helper/HDevEngineTool.cs
Normal file
677
DH.Commons/Helper/HDevEngineTool.cs
Normal file
@@ -0,0 +1,677 @@
|
|||||||
|
using HalconDotNet;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.Drawing;
|
||||||
|
using System.Drawing.Imaging;
|
||||||
|
using System.Runtime.ExceptionServices;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
|
namespace DH.Commons.Enums
|
||||||
|
{
|
||||||
|
public class HDevEngineTool : IDisposable
|
||||||
|
{
|
||||||
|
#region 常量
|
||||||
|
|
||||||
|
// path of external procedures
|
||||||
|
readonly string ProcedurePath = Environment.CurrentDirectory + "\\Vision\\";
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region 成员变量
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 处理过程名
|
||||||
|
/// </summary>
|
||||||
|
public string ProcedureName;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// hdev程序启动引擎
|
||||||
|
/// </summary>
|
||||||
|
private readonly HDevEngine myEngine;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 过程载入工具 .hdvp
|
||||||
|
/// </summary>
|
||||||
|
private HDevProcedureCall procedureCall;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 程序运行是否成功
|
||||||
|
/// </summary>
|
||||||
|
public bool IsSuccessful { get; set; } = false;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 控制参数字典
|
||||||
|
/// </summary>
|
||||||
|
public Dictionary<string, HTuple> InputTupleDic { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 图形参数字典
|
||||||
|
/// </summary>
|
||||||
|
public Dictionary<string, HObject> InputImageDic { get; set; }
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region 初始化
|
||||||
|
/// <summary>
|
||||||
|
/// 实例化 默认搜索路径为: 启动路径//Vision//
|
||||||
|
/// </summary>
|
||||||
|
public HDevEngineTool()
|
||||||
|
{
|
||||||
|
ProcedureName = "";
|
||||||
|
myEngine = new HDevEngine();
|
||||||
|
myEngine.SetProcedurePath(ProcedurePath);
|
||||||
|
|
||||||
|
InputImageDic = new Dictionary<string, HObject>();
|
||||||
|
InputTupleDic = new Dictionary<string, HTuple>();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 实例化
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="path">外部函数搜索路径</param>
|
||||||
|
public HDevEngineTool(string path)
|
||||||
|
{
|
||||||
|
myEngine = new HDevEngine();
|
||||||
|
myEngine.SetProcedurePath(path);
|
||||||
|
|
||||||
|
InputImageDic = new Dictionary<string, HObject>();
|
||||||
|
InputTupleDic = new Dictionary<string, HTuple>();
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 设置函数运行所需参数
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="_tupleDictionary">控制参数</param>
|
||||||
|
/// <param name="_imageDictionary">图形参数</param>
|
||||||
|
public void SetDictionary(Dictionary<string, HTuple> _tupleDictionary, Dictionary<string, HObject> _imageDictionary)
|
||||||
|
{
|
||||||
|
InputTupleDic = _tupleDictionary;
|
||||||
|
InputImageDic = _imageDictionary;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 载入过程 .hdvp
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="procedureName">过程名</param>
|
||||||
|
public void LoadProcedure(string procedureName)
|
||||||
|
{
|
||||||
|
ProcedureName = procedureName;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
HDevProcedure procedure = new HDevProcedure(procedureName);
|
||||||
|
procedureCall = new HDevProcedureCall(procedure);
|
||||||
|
}
|
||||||
|
catch (HDevEngineException Ex)
|
||||||
|
{
|
||||||
|
Trace.TraceInformation("HDevProgram {0} Load fail ,Error Line : {1}, Line number: {2}, Halcon error number : {3}", Ex.ProcedureName, Ex.LineText, Ex.LineNumber, Ex.HalconError);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 执行过程
|
||||||
|
/// </summary>
|
||||||
|
[HandleProcessCorruptedStateExceptions]
|
||||||
|
public bool RunProcedure(out string errorMsg, out int timeElasped)
|
||||||
|
{
|
||||||
|
//lock (_runLock)
|
||||||
|
{
|
||||||
|
errorMsg = "";
|
||||||
|
Stopwatch sw = new Stopwatch();
|
||||||
|
sw.Start();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
foreach (KeyValuePair<string, HTuple> pair in InputTupleDic)
|
||||||
|
{
|
||||||
|
procedureCall.SetInputCtrlParamTuple(pair.Key, pair.Value);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (KeyValuePair<string, HObject> pair in InputImageDic)
|
||||||
|
{
|
||||||
|
procedureCall.SetInputIconicParamObject(pair.Key, pair.Value);
|
||||||
|
}
|
||||||
|
|
||||||
|
procedureCall.Execute();
|
||||||
|
|
||||||
|
IsSuccessful = true;
|
||||||
|
}
|
||||||
|
catch (HDevEngineException ex)
|
||||||
|
{
|
||||||
|
IsSuccessful = false;
|
||||||
|
errorMsg = $"HDevProgram {ex.ProcedureName} Run fail , Line number: {ex.LineNumber}, Halcon error number : {ex.HalconError},ex:{ex.Message}";
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
sw.Stop();
|
||||||
|
timeElasped = (int)sw.ElapsedMilliseconds;
|
||||||
|
}
|
||||||
|
return IsSuccessful;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
object _runLock = new object();
|
||||||
|
/// <summary>
|
||||||
|
/// 执行过程
|
||||||
|
/// </summary>
|
||||||
|
public Tuple<bool, Dictionary<string, HTuple>, Dictionary<string, HObject>, string, int> RunProcedure(Dictionary<string, HTuple> inputHTupleDict, Dictionary<string, HObject> inputImgDict, List<string> outputHTuples = null, List<string> outputObjs = null)
|
||||||
|
{
|
||||||
|
lock (_runLock)
|
||||||
|
{
|
||||||
|
string errorMsg = "";
|
||||||
|
int timeElasped = 0;
|
||||||
|
bool result = false;
|
||||||
|
Dictionary<string, HTuple> outputHTupleDict = new Dictionary<string, HTuple>();
|
||||||
|
Dictionary<string, HObject> outputObjDict = new Dictionary<string, HObject>();
|
||||||
|
|
||||||
|
Stopwatch sw = new Stopwatch();
|
||||||
|
sw.Start();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (inputHTupleDict != null && inputHTupleDict.Count > 0)
|
||||||
|
{
|
||||||
|
foreach (KeyValuePair<string, HTuple> pair in inputHTupleDict)
|
||||||
|
{
|
||||||
|
procedureCall.SetInputCtrlParamTuple(pair.Key, pair.Value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (InputImageDic != null && inputImgDict.Count > 0)
|
||||||
|
{
|
||||||
|
foreach (KeyValuePair<string, HObject> pair in inputImgDict)
|
||||||
|
{
|
||||||
|
procedureCall.SetInputIconicParamObject(pair.Key, pair.Value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
procedureCall.Execute();
|
||||||
|
|
||||||
|
result = true;
|
||||||
|
}
|
||||||
|
catch (HDevEngineException ex)
|
||||||
|
{
|
||||||
|
result = false;
|
||||||
|
errorMsg += $"HDevProgram {ex.ProcedureName} Run fail , Line number: {ex.LineNumber}, Halcon error number : {ex.HalconError},ex:{ex.Message}";
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
sw.Stop();
|
||||||
|
timeElasped = (int)sw.ElapsedMilliseconds;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result)
|
||||||
|
{
|
||||||
|
if (outputHTuples != null && outputHTuples.Count > 0)
|
||||||
|
{
|
||||||
|
outputHTuples.ForEach(t =>
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
outputHTupleDict[t] = procedureCall.GetOutputCtrlParamTuple(t);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
result = false;
|
||||||
|
errorMsg += $"\r\n获取{t}结果异常:{ex.Message}";
|
||||||
|
|
||||||
|
outputHTupleDict[t] = null;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (outputObjs != null && outputObjs.Count > 0)
|
||||||
|
{
|
||||||
|
outputObjs.ForEach(t =>
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
outputObjDict[t] = procedureCall.GetOutputIconicParamObject(t);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
result = false;
|
||||||
|
errorMsg += $"\r\n获取{t}结果异常:{ex.Message}";
|
||||||
|
|
||||||
|
outputObjDict[t] = null;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Tuple<bool, Dictionary<string, HTuple>, Dictionary<string, HObject>, string, int> ret = new Tuple<bool, Dictionary<string, HTuple>, Dictionary<string, HObject>, string, int>(result, outputHTupleDict, outputObjDict, errorMsg, timeElasped);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public HTuple GetResultTuple(string key)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (IsSuccessful)
|
||||||
|
{
|
||||||
|
return procedureCall.GetOutputCtrlParamTuple(key);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return new HTuple();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
return new HTuple();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public HObject GetResultObject(string key, bool ignoreError = false)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (ignoreError || IsSuccessful)
|
||||||
|
{
|
||||||
|
return procedureCall.GetOutputIconicParamObject(key);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return new HObject();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
return new HObject();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
procedureCall?.Dispose();
|
||||||
|
myEngine?.Dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class HalconHelper
|
||||||
|
{
|
||||||
|
[DllImport("kernel32.dll", EntryPoint = "CopyMemory", SetLastError = false)]
|
||||||
|
public static extern void CopyMemory(IntPtr dest, IntPtr src, uint count);
|
||||||
|
|
||||||
|
public static HImage Convert8GrayBitmapToHImage(this Bitmap bmp)
|
||||||
|
{
|
||||||
|
HImage himage = new HImage();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
//判断输入图像不为null
|
||||||
|
if (bmp == null)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
//重绘himage
|
||||||
|
//HImage curImage = new HImage();
|
||||||
|
BitmapData bmpData = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadOnly, PixelFormat.Format8bppIndexed);
|
||||||
|
himage.GenImage1("byte", bmp.Width, bmp.Height, bmpData.Scan0);
|
||||||
|
bmp.UnlockBits(bmpData);
|
||||||
|
//himage = curImage;
|
||||||
|
}
|
||||||
|
return himage;
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Bitmap ConvertHImageToBitmap(this HObject hImage)
|
||||||
|
{
|
||||||
|
HOperatorSet.CountChannels(hImage, out HTuple chanels);
|
||||||
|
if (chanels.I == 1)
|
||||||
|
{
|
||||||
|
return hImage.ConvertHImageTo8GrayBitmap();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return hImage.ConvertHImageToRGBBitmap();
|
||||||
|
//return hImage.HObject2BitmapRGB();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Bitmap HObject2BitmapRGB(this HObject hObject)
|
||||||
|
{
|
||||||
|
////获取图像尺寸
|
||||||
|
HTuple width0, height0, type, width, height;
|
||||||
|
//获取图像尺寸
|
||||||
|
HOperatorSet.GetImageSize(hObject, out width0, out height0);
|
||||||
|
// 创建交错格式图像
|
||||||
|
HOperatorSet.InterleaveChannels(hObject, out HObject InterImage, "argb", "match", 255); //"rgb", 4 * width0, 0 "argb", "match", 255
|
||||||
|
|
||||||
|
//获取交错格式图像指针
|
||||||
|
HOperatorSet.GetImagePointer1(InterImage, out HTuple Pointer, out type, out width, out height);
|
||||||
|
IntPtr ptr = Pointer;
|
||||||
|
//构建新Bitmap图像
|
||||||
|
Bitmap res32 = new Bitmap(width / 4, height, width, PixelFormat.Format32bppArgb, ptr); // Format32bppArgb Format24bppRgb
|
||||||
|
|
||||||
|
//32位Bitmap转24位
|
||||||
|
var res24 = new Bitmap(res32.Width, res32.Height, PixelFormat.Format24bppRgb);
|
||||||
|
Graphics graphics = Graphics.FromImage(res24);
|
||||||
|
graphics.DrawImage(res32, new Rectangle(0, 0, res32.Width, res32.Height));
|
||||||
|
|
||||||
|
return res24;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Bitmap ConvertHImageTo8GrayBitmap(this HObject hImage)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
HTuple type, width, height, pointer;
|
||||||
|
HOperatorSet.GetImagePointer1(hImage, out pointer, out type, out width, out height);
|
||||||
|
|
||||||
|
Bitmap bmp = new Bitmap(width.I, height.I, PixelFormat.Format8bppIndexed);
|
||||||
|
ColorPalette pal = bmp.Palette;
|
||||||
|
for (int i = 0; i <= 255; i++)
|
||||||
|
{
|
||||||
|
pal.Entries[i] = Color.FromArgb(255, i, i, i);
|
||||||
|
}
|
||||||
|
bmp.Palette = pal;
|
||||||
|
|
||||||
|
BitmapData bitmapData = bmp.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.WriteOnly, PixelFormat.Format8bppIndexed);
|
||||||
|
|
||||||
|
if (width % 4 == 0)
|
||||||
|
{
|
||||||
|
CopyMemory(bitmapData.Scan0, (IntPtr)pointer.D, (uint)(bitmapData.Stride * height.I));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Parallel.For(0, height.I, h =>
|
||||||
|
{
|
||||||
|
CopyMemory(bitmapData.Scan0 + h * bitmapData.Stride, (IntPtr)(pointer.D + h * width.I), (uint)width.I);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
bmp.UnlockBits(bitmapData);
|
||||||
|
return bmp;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Bitmap ConvertHImageToRGBBitmap(this HObject hImage)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
HOperatorSet.GetImagePointer3(hImage, out HTuple pointRed, out HTuple pointGreen, out HTuple pointBlue, out HTuple type, out HTuple width, out HTuple height);
|
||||||
|
Bitmap image = new Bitmap(width.I, height.I, PixelFormat.Format24bppRgb);
|
||||||
|
BitmapData imageData = image.LockBits(new Rectangle(0, 0, width.I, height.I), ImageLockMode.ReadWrite, image.PixelFormat);
|
||||||
|
IntPtr pR = (IntPtr)pointRed.D;
|
||||||
|
IntPtr pG = (IntPtr)pointGreen.D;
|
||||||
|
IntPtr pB = (IntPtr)pointBlue.D;
|
||||||
|
Parallel.For(0, imageData.Height, h =>
|
||||||
|
{
|
||||||
|
Parallel.For(0, imageData.Width, w =>
|
||||||
|
{
|
||||||
|
int dest = h * imageData.Stride + w * 3;
|
||||||
|
int source = h * imageData.Width + w;
|
||||||
|
|
||||||
|
Marshal.WriteByte(imageData.Scan0, dest, Marshal.ReadByte(pB, source));
|
||||||
|
Marshal.WriteByte(imageData.Scan0, dest + 1, Marshal.ReadByte(pG, source));
|
||||||
|
Marshal.WriteByte(imageData.Scan0, dest + 2, Marshal.ReadByte(pR, source));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
image.UnlockBits(imageData);
|
||||||
|
return image;
|
||||||
|
}
|
||||||
|
catch (Exception exc)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Bitmap ConvertHImageTo16GrayBitmap(this HImage originHImage)
|
||||||
|
{
|
||||||
|
//IntPtr pointer = hImage.GetImagePointer1(out string type, out int width, out int height);
|
||||||
|
|
||||||
|
//int widthIn4 = (int)Math.Ceiling(width / 4.0) * 4;
|
||||||
|
|
||||||
|
////Bitmap bmp = new Bitmap(widthIn4, height, PixelFormat.Format48bppRgb);
|
||||||
|
//Bitmap showImage = new Bitmap(widthIn4, height, PixelFormat.Format48bppRgb);
|
||||||
|
|
||||||
|
//Rectangle rect = new Rectangle(0, 0, widthIn4, height);
|
||||||
|
////BitmapData bitmapData = bmp.LockBits(rect, ImageLockMode.WriteOnly, PixelFormat.Format48bppRgb);
|
||||||
|
//BitmapData showImageData = showImage.LockBits(rect, ImageLockMode.WriteOnly, PixelFormat.Format48bppRgb);
|
||||||
|
//unsafe
|
||||||
|
//{
|
||||||
|
// byte* data = (byte*)pointer;
|
||||||
|
// //byte* bitmapBuffer = (byte*)bitmapData.Scan0;
|
||||||
|
// byte* showBitmapBuffer = (byte*)showImageData.Scan0;
|
||||||
|
|
||||||
|
// Parallel.For(0, width * height, i =>
|
||||||
|
// {
|
||||||
|
// int index = (i + 1) % width + widthIn4 * ((int)Math.Floor((double)(i + 1) / width)) - 1;
|
||||||
|
|
||||||
|
// //showBitmapBuffer[index * 6] = bitmapBuffer[index * 6] = data[i * 2];
|
||||||
|
// //showBitmapBuffer[index * 6 + 1] = bitmapBuffer[index * 6 + 1] = data[i * 2 + 1];
|
||||||
|
// showBitmapBuffer[index * 6] = data[i * 2];
|
||||||
|
// showBitmapBuffer[index * 6 + 1] = data[i * 2 + 1];
|
||||||
|
// });
|
||||||
|
//}
|
||||||
|
|
||||||
|
////bmp.UnlockBits(bitmapData);
|
||||||
|
//showImage.UnlockBits(showImageData);
|
||||||
|
|
||||||
|
//return showImage;
|
||||||
|
|
||||||
|
// dev_set_draw('margin')
|
||||||
|
//read_image(Image, '0.tif')
|
||||||
|
|
||||||
|
HImage hImage = originHImage.Clone();
|
||||||
|
|
||||||
|
//* 如果16位图像非常暗的话,建议在这一步进行提亮,因为后面8位图像大幅度提亮易造成色阶断裂,出现不连续的像素块
|
||||||
|
// * scale_image(Image, Image, 25, 0)
|
||||||
|
//hImage = hImage.ScaleImage(25.0, 0.0);
|
||||||
|
|
||||||
|
//get_domain(Image, rectangle)
|
||||||
|
//* 获取全图中像素灰度值的最大和最小值
|
||||||
|
//min_max_gray(rectangle, Image, 0, Min, Max, range)
|
||||||
|
hImage.MinMaxGray(hImage.GetDomain(), 0, out double min, out double max, out double range);
|
||||||
|
|
||||||
|
//* 将16位图的灰度值映射到0 - 255上
|
||||||
|
double mult = 255.0 / (max - min);
|
||||||
|
double add = -mult * min;
|
||||||
|
hImage = hImage.ScaleImage(mult, add);
|
||||||
|
|
||||||
|
//* 转换为'byte'类型
|
||||||
|
//convert_image_type(Image_scaled, ImageConverted, 'byte')
|
||||||
|
hImage = hImage.ConvertImageType("byte");
|
||||||
|
|
||||||
|
Bitmap showImage = hImage.ConvertHImageTo8GrayBitmap();
|
||||||
|
|
||||||
|
hImage.Dispose();
|
||||||
|
|
||||||
|
return showImage;
|
||||||
|
|
||||||
|
//* 如果转换以后图像整体对比度太低的话,可以提高对比度(这里是对8位图像处理)
|
||||||
|
//Min:= 20
|
||||||
|
//Max:= 160
|
||||||
|
//Mult:= 255.0 / (Max - Min)
|
||||||
|
//Add:= -Mult * Min
|
||||||
|
//scale_image(ImageConverted, ImageConverted_scaled, Mult, Add)
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<double> HTupleToDouble(this HTuple tuple)
|
||||||
|
{
|
||||||
|
List<double> list = new List<double>();
|
||||||
|
|
||||||
|
for (int i = 0; i < tuple.Length; i++)
|
||||||
|
{
|
||||||
|
list.Add(tuple[i].D);
|
||||||
|
}
|
||||||
|
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public static HImage ConvertHObjectToHImage(this HObject obj)
|
||||||
|
{
|
||||||
|
HOperatorSet.CountChannels(obj, out HTuple channels);
|
||||||
|
|
||||||
|
HImage img = new HImage();
|
||||||
|
if (channels.I == 1)
|
||||||
|
{
|
||||||
|
HTuple pointer, type, width, height;
|
||||||
|
HOperatorSet.GetImagePointer1(obj, out pointer, out type, out width, out height);
|
||||||
|
|
||||||
|
img.GenImage1(type, width, height, pointer);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
HTuple pRed, pGreen, pBlue, type, width, height;
|
||||||
|
HOperatorSet.GetImagePointer3(obj, out pRed, out pGreen, out pBlue, out type, out width, out height);
|
||||||
|
|
||||||
|
img.GenImage3(type, width, height, pRed, pGreen, pBlue);
|
||||||
|
}
|
||||||
|
|
||||||
|
return img;
|
||||||
|
}
|
||||||
|
|
||||||
|
#region 灰度图转换为伪彩图
|
||||||
|
public static Bitmap ConvertGrayImageToPesudoColorfulImage(this HImage hImage, double max = 0, double min = 0, double zoom = 1, bool isShowHeightTip = false, int zResolution = 100000)
|
||||||
|
{
|
||||||
|
hImage.GetImageSize(out int width, out int height);
|
||||||
|
hImage.MinMaxGray(new HRegion(0.0, 0.0, width, height), 3, out HTuple roiMin, out HTuple roiMax, out _);
|
||||||
|
|
||||||
|
if (max == 0)
|
||||||
|
{
|
||||||
|
max = roiMax;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (min == 0)
|
||||||
|
{
|
||||||
|
min = roiMin;
|
||||||
|
}
|
||||||
|
|
||||||
|
double mult = 235 / (zoom * (max - min));
|
||||||
|
double add = (0 - mult) * min * zoom + 10;
|
||||||
|
HOperatorSet.ScaleImage(hImage, out HObject imageScaled, mult, add);
|
||||||
|
HOperatorSet.ConvertImageType(imageScaled, out imageScaled, "byte");
|
||||||
|
Stopwatch sw = new Stopwatch();
|
||||||
|
sw.Start();
|
||||||
|
|
||||||
|
HOperatorSet.GetImagePointer1(imageScaled, out HTuple pointer, out HTuple type, out _, out _);
|
||||||
|
Bitmap bitmap = new Bitmap(width, height, PixelFormat.Format24bppRgb);
|
||||||
|
BitmapData bitmapData = bitmap.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadWrite, bitmap.PixelFormat);
|
||||||
|
|
||||||
|
unsafe
|
||||||
|
{
|
||||||
|
byte* data = (byte*)(IntPtr)pointer;
|
||||||
|
byte* bitmapDataBuff = (byte*)bitmapData.Scan0;
|
||||||
|
|
||||||
|
if (width % 4 != 0)
|
||||||
|
{
|
||||||
|
Parallel.For(0, height, h =>
|
||||||
|
{
|
||||||
|
Parallel.For(0, width, w =>
|
||||||
|
{
|
||||||
|
byte gray = data[h * width + w];
|
||||||
|
byte[] convertBytes = ConvertByteToColorfulArray(gray);
|
||||||
|
|
||||||
|
Marshal.Copy(convertBytes, 0, (IntPtr)(bitmapDataBuff + h * bitmapData.Stride + w * 3), 3);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Parallel.For(0, width * height, i =>
|
||||||
|
{
|
||||||
|
byte gray = data[i];
|
||||||
|
byte[] convertBytes = ConvertByteToColorfulArray(gray);
|
||||||
|
|
||||||
|
Marshal.Copy(convertBytes, 0, (IntPtr)(bitmapDataBuff + i * 3), 3);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
bitmap.UnlockBits(bitmapData);
|
||||||
|
|
||||||
|
if (isShowHeightTip)
|
||||||
|
{
|
||||||
|
List<byte> lableList = new List<byte>() { 5, 30, 60, 90, 120, 150, 180, 210, 240, 255 };
|
||||||
|
Dictionary<double, Color> lableColorDict = lableList.ToDictionary(
|
||||||
|
u => (u - add) / (mult * zResolution),
|
||||||
|
u =>
|
||||||
|
{
|
||||||
|
byte[] colorBytes = ConvertByteToColorfulArray(u);
|
||||||
|
return Color.FromArgb(colorBytes[2], colorBytes[1], colorBytes[0]);
|
||||||
|
});
|
||||||
|
|
||||||
|
using (Graphics g = Graphics.FromImage(bitmap))
|
||||||
|
{
|
||||||
|
int rectHeight = (int)(bitmap.Height / (5.0 * lableColorDict.Count));
|
||||||
|
Font font = new Font("宋体", (int)(rectHeight * 0.75), GraphicsUnit.Pixel);
|
||||||
|
|
||||||
|
string lable = lableColorDict.ElementAt(0).Key.ToString("f3");
|
||||||
|
SizeF lableSize = g.MeasureString(lable, font);
|
||||||
|
int rectWidth = (int)(lableSize.Width * 1.5);
|
||||||
|
|
||||||
|
int startX = 0;
|
||||||
|
int startY = 0;
|
||||||
|
foreach (KeyValuePair<double, Color> pair in lableColorDict)
|
||||||
|
{
|
||||||
|
g.FillRectangle(new SolidBrush(pair.Value), startX, startY, rectWidth, rectHeight);
|
||||||
|
g.DrawString(pair.Key.ToString("f3"), font, new SolidBrush(Color.White), (float)(startX + (rectWidth - lableSize.Width) / 2.0), (float)(startY + (rectHeight - lableSize.Height) / 2.0));
|
||||||
|
|
||||||
|
startY += rectHeight;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sw.Stop();
|
||||||
|
//LogAsync(DateTime.Now, EnumHelper.LogLevel.Information, $"转换耗时{sw.ElapsedMilliseconds}ms");
|
||||||
|
return bitmap;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static byte[] ConvertByteToColorfulArray(byte gray)
|
||||||
|
{
|
||||||
|
byte[] bytes = new byte[3];
|
||||||
|
if (gray == 0)
|
||||||
|
{
|
||||||
|
bytes[2] = 255;
|
||||||
|
bytes[1] = 255;
|
||||||
|
bytes[0] = 255;
|
||||||
|
}
|
||||||
|
if (gray > 0 && gray <= 63)
|
||||||
|
{
|
||||||
|
bytes[2] = 0;
|
||||||
|
bytes[+1] = (byte)(254 - 4 * gray);
|
||||||
|
bytes[0] = 255;
|
||||||
|
}
|
||||||
|
if (gray >= 64 && gray <= 127)
|
||||||
|
{
|
||||||
|
bytes[2] = 0;
|
||||||
|
bytes[1] = (byte)(4 * gray - 254);
|
||||||
|
bytes[0] = (byte)(510 - 4 * gray);
|
||||||
|
}
|
||||||
|
if (gray >= 128 && gray <= 191)
|
||||||
|
{
|
||||||
|
bytes[2] = (byte)(4 * gray - 510);
|
||||||
|
bytes[1] = 255;
|
||||||
|
bytes[0] = 0;
|
||||||
|
}
|
||||||
|
if (gray >= 192 && gray <= 255)
|
||||||
|
{
|
||||||
|
bytes[2] = 255;
|
||||||
|
bytes[1] = (byte)(1022 - 4 * gray);
|
||||||
|
bytes[0] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return bytes;
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
107
DH.Commons/Helper/ImageSaveHelper.cs
Normal file
107
DH.Commons/Helper/ImageSaveHelper.cs
Normal file
@@ -0,0 +1,107 @@
|
|||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Concurrent;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Drawing;
|
||||||
|
using System.Drawing.Imaging;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using DH.Commons.Helper;
|
||||||
|
|
||||||
|
namespace DH.Commons.Enums
|
||||||
|
{
|
||||||
|
public class ImageSaveHelper
|
||||||
|
{
|
||||||
|
public event Action<DateTime, string> OnImageSaveExceptionRaised;
|
||||||
|
|
||||||
|
//private string baseDirectory = "";
|
||||||
|
//public string BaseDirectory
|
||||||
|
//{
|
||||||
|
// get => baseDirectory;
|
||||||
|
// set
|
||||||
|
// {
|
||||||
|
// baseDirectory = value;
|
||||||
|
// if (string.IsNullOrWhiteSpace(baseDirectory) || !Path.IsPathRooted(baseDirectory))
|
||||||
|
// {
|
||||||
|
// baseDirectory = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Images");
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
public bool EnableImageSave { get; set; } = true;
|
||||||
|
|
||||||
|
public ImageSaveHelper() { }
|
||||||
|
public ImageSaveHelper(bool enableImageSave = true)
|
||||||
|
{
|
||||||
|
EnableImageSave = enableImageSave;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
object lockObj = new object();
|
||||||
|
////耗时操作从 _taskFactory分配线程
|
||||||
|
//public TaskFactory _taskFactory = new TaskFactory(TaskCreationOptions.LongRunning, TaskContinuationOptions.LongRunning);
|
||||||
|
readonly ConcurrentQueue<ImageSaveSet> _imageQueue = new ConcurrentQueue<ImageSaveSet>();
|
||||||
|
Task _saveTask = null;
|
||||||
|
readonly object _saveLock = new object();
|
||||||
|
|
||||||
|
public async void ImageSaveAsync(ImageSaveSet set)
|
||||||
|
{
|
||||||
|
if (!EnableImageSave)
|
||||||
|
return;
|
||||||
|
|
||||||
|
await Task.Run(() =>
|
||||||
|
{
|
||||||
|
_imageQueue.Enqueue(set);
|
||||||
|
|
||||||
|
lock (_saveLock)
|
||||||
|
{
|
||||||
|
if (_saveTask == null)
|
||||||
|
{
|
||||||
|
_saveTask = Task.Run(async () =>
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
while (_imageQueue.Count > 0)
|
||||||
|
{
|
||||||
|
if (_imageQueue.TryDequeue(out ImageSaveSet saveSet))
|
||||||
|
{
|
||||||
|
if (!Directory.Exists(Path.GetDirectoryName(saveSet.FullName)))
|
||||||
|
{
|
||||||
|
Directory.CreateDirectory(Path.GetDirectoryName(saveSet.FullName));
|
||||||
|
}
|
||||||
|
if (saveSet.SaveImage != null)
|
||||||
|
{
|
||||||
|
saveSet.SaveImage.Save(saveSet.FullName, saveSet.ImageFormat);
|
||||||
|
saveSet.SaveImage.Dispose();
|
||||||
|
}
|
||||||
|
saveSet = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
await Task.Delay(2000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
OnImageSaveExceptionRaised?.Invoke(DateTime.Now, $"图片保存异常:{ex.GetExceptionMessage()}");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class ImageSaveSet
|
||||||
|
{
|
||||||
|
public string FullName { get; set; }//带后缀 全路径
|
||||||
|
|
||||||
|
public Bitmap SaveImage { get; set; }
|
||||||
|
|
||||||
|
public ImageFormat ImageFormat { get; set; } = ImageFormat.Jpeg;
|
||||||
|
}
|
||||||
|
}
|
||||||
138
DH.Commons/Helper/LoggerHelper.cs
Normal file
138
DH.Commons/Helper/LoggerHelper.cs
Normal file
@@ -0,0 +1,138 @@
|
|||||||
|
using DH.Commons.Helper;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Concurrent;
|
||||||
|
using System.IO;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using static DH.Commons.Enums.EnumHelper;
|
||||||
|
|
||||||
|
namespace DH.Commons.Enums
|
||||||
|
{
|
||||||
|
public interface ILogOutput
|
||||||
|
{
|
||||||
|
event Action<LogMsg> OnLogMsgOutput;
|
||||||
|
void LogDisplay(LogMsg msg);
|
||||||
|
}
|
||||||
|
public interface ILogger
|
||||||
|
{
|
||||||
|
event Action<LogMsg> OnLog;
|
||||||
|
LoggerHelper LoggerHelper { get; set; }
|
||||||
|
//void LogAsync(DateTime dt, LogLevel loglevel, string msg);
|
||||||
|
void LogAsync(LogMsg msg);
|
||||||
|
}
|
||||||
|
public class LoggerHelper
|
||||||
|
{
|
||||||
|
public event Action<DateTime, string> OnLogExceptionRaised;
|
||||||
|
|
||||||
|
public string LogPath { get; set; }
|
||||||
|
public string LogPrefix { get; set; }
|
||||||
|
|
||||||
|
LogLevel LogLevel = LogLevel.Information;
|
||||||
|
|
||||||
|
public LoggerHelper() { }
|
||||||
|
public LoggerHelper(string logPath, string logPrefix, LogLevel logLevel = LogLevel.Information)
|
||||||
|
{
|
||||||
|
LogPath = logPath;
|
||||||
|
LogPrefix = logPrefix;
|
||||||
|
|
||||||
|
LogLevel = logLevel;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetLogLevel(LogLevel logLevel)
|
||||||
|
{
|
||||||
|
if (LogLevel != logLevel)
|
||||||
|
LogLevel = logLevel;
|
||||||
|
}
|
||||||
|
////耗时操作从 _taskFactory分配线程
|
||||||
|
//public TaskFactory _taskFactory = new TaskFactory(TaskCreationOptions.LongRunning, TaskContinuationOptions.LongRunning);
|
||||||
|
readonly ConcurrentQueue<LogMsg> _logQueue = new ConcurrentQueue<LogMsg>();
|
||||||
|
Task _logTask = null;
|
||||||
|
readonly object _logLock = new object();
|
||||||
|
|
||||||
|
public async void LogAsync(LogMsg msg)
|
||||||
|
{
|
||||||
|
await Task.Run(() =>
|
||||||
|
{
|
||||||
|
_logQueue.Enqueue(msg);
|
||||||
|
|
||||||
|
lock (_logLock)
|
||||||
|
{
|
||||||
|
if (_logTask == null)
|
||||||
|
{
|
||||||
|
_logTask = Task.Run(async () =>
|
||||||
|
{
|
||||||
|
string filePath = Path.Combine(LogPath, $"{(string.IsNullOrWhiteSpace(LogPrefix) ? "Log_" : ("Log_" + LogPrefix + "_"))}{DateTime.Now.ToString("yyyyMMdd")}.txt");
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (!StaticHelper.CheckFilesCanUse(filePath))
|
||||||
|
{
|
||||||
|
OnLogExceptionRaised?.Invoke(DateTime.Now, $"日志文件{filePath}被占用,无法写入");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
using (StreamWriter writer = new StreamWriter(filePath, true, System.Text.Encoding.UTF8))
|
||||||
|
{
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
if (!Directory.Exists(LogPath))
|
||||||
|
{
|
||||||
|
Directory.CreateDirectory(LogPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
while (_logQueue.Count > 0)
|
||||||
|
{
|
||||||
|
if (_logQueue.TryDequeue(out LogMsg log))
|
||||||
|
{
|
||||||
|
if (log.LogLevel >= LogLevel)
|
||||||
|
{
|
||||||
|
writer.WriteLine($"{log.LogTime.ToString("yyyy-MM-dd HH:mm:ss.fff")}[{log.ThreadId}]\t{log.LogLevel.GetEnumDescription()}\t{log.Msg}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
writer.Flush();
|
||||||
|
|
||||||
|
await Task.Delay(2000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
//OnLogExceptionRaised?.Invoke(DateTime.Now, $"日志文件{filePath}写入异常:/*{ex.GetExceptionMessage()*/}");
|
||||||
|
OnLogExceptionRaised?.Invoke(DateTime.Now, $"日志文件{filePath}写入异常");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public void LogAsync(DateTime dt, LogLevel logLevel, string msg)
|
||||||
|
{
|
||||||
|
LogAsync(new LogMsg(dt, logLevel, msg));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class LogMsg
|
||||||
|
{
|
||||||
|
public DateTime LogTime { get; set; }
|
||||||
|
public LogLevel LogLevel { get; set; }
|
||||||
|
//public string Prefix { get; set; }
|
||||||
|
public string Msg { get; set; }
|
||||||
|
|
||||||
|
public string MsgSource { get; set; }
|
||||||
|
|
||||||
|
public int ThreadId { get; set; }
|
||||||
|
|
||||||
|
public LogMsg() { }
|
||||||
|
public LogMsg(DateTime dt, LogLevel logLevel, string msg)
|
||||||
|
{
|
||||||
|
LogTime = dt;
|
||||||
|
LogLevel = logLevel;
|
||||||
|
Msg = msg;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
return $"{LogTime.ToString("HH:mm:ss.fff")}\t{MsgSource}\t{Msg}";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
724
DH.Commons/Helper/OpenCVEngineTool.cs
Normal file
724
DH.Commons/Helper/OpenCVEngineTool.cs
Normal file
@@ -0,0 +1,724 @@
|
|||||||
|
using HalconDotNet;
|
||||||
|
using OpenCvSharp;
|
||||||
|
using OpenCvSharp.Extensions;
|
||||||
|
using System;
|
||||||
|
using System.Drawing;
|
||||||
|
using System.Drawing.Imaging;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace DH.Commons.Enums
|
||||||
|
{
|
||||||
|
public class OpenCVEngineTool : IDisposable
|
||||||
|
{
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static class OpenCVHelper
|
||||||
|
{
|
||||||
|
[DllImport("kernel32.dll", EntryPoint = "RtlMoveMemory", SetLastError = false)]
|
||||||
|
public static extern void CopyMemory(IntPtr dest, IntPtr src, uint count);
|
||||||
|
|
||||||
|
|
||||||
|
public static byte[] MatToBytes(this Mat image)
|
||||||
|
{
|
||||||
|
if (image != null && image.Data != IntPtr.Zero)
|
||||||
|
{
|
||||||
|
int size = (int)(image.Total() * image.ElemSize());
|
||||||
|
byte[] bytes = new byte[size];
|
||||||
|
Marshal.Copy(image.Data, bytes, 0, size);
|
||||||
|
return bytes;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取水平拼接图片
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="map1"></param>
|
||||||
|
/// <param name="map2"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static Bitmap GetHConcatImage(Bitmap map1, Bitmap map2)
|
||||||
|
{
|
||||||
|
var mat1 = map1.ToMat();
|
||||||
|
var mat2 = map2.ToMat();
|
||||||
|
//var maxChannel = Math.Max(mat1.Channels(), mat2.Channels());
|
||||||
|
//var maxType = Math.Max(mat1.Type(), mat2.Type());
|
||||||
|
|
||||||
|
//转通道数
|
||||||
|
mat1 = mat1.CvtColor(ColorConversionCodes.GRAY2BGRA);
|
||||||
|
//转位深
|
||||||
|
mat1.ConvertTo(mat1, mat2.Type());
|
||||||
|
Mat resMat = new Mat(mat1.Height, mat1.Width, mat2.Type(), new Scalar(0));
|
||||||
|
Cv2.HConcat(mat1, mat2, resMat);
|
||||||
|
mat1.Dispose();
|
||||||
|
mat2.Dispose();
|
||||||
|
return resMat.ToBitmap();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Mat To3Channels(this Mat img)
|
||||||
|
{
|
||||||
|
if (img == null)
|
||||||
|
return null;
|
||||||
|
Mat resMat = new Mat(img.Rows, img.Cols, MatType.CV_8UC3);
|
||||||
|
Mat[] channels = new Mat[3]; ;
|
||||||
|
for (int i = 0; i < 3; i++)
|
||||||
|
{
|
||||||
|
channels[i] = img;
|
||||||
|
}
|
||||||
|
Cv2.Merge(channels, resMat);
|
||||||
|
img.Dispose();
|
||||||
|
img = null;
|
||||||
|
return resMat;
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// 把OpenCV图像转换到Halcon图像
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="mImage">OpenCV图像_Mat</param>
|
||||||
|
/// <returns>Halcon图像_HObject</returns>
|
||||||
|
public static HObject MatToHImage(Mat mImage)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
HObject hImage;
|
||||||
|
int matChannels = 0; // 通道数
|
||||||
|
Type matType = null;
|
||||||
|
uint width, height; // 宽,高
|
||||||
|
width = height = 0; // 宽,高初始化
|
||||||
|
|
||||||
|
// 获取通道数
|
||||||
|
matChannels = mImage.Channels();
|
||||||
|
if (matChannels == 0)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (matChannels == 1) // 单通道
|
||||||
|
//if (true) // 单通道
|
||||||
|
{
|
||||||
|
IntPtr ptr; // 灰度图通道
|
||||||
|
Mat[] mats = mImage.Split();
|
||||||
|
|
||||||
|
// 改自:Mat.GetImagePointer1(mImage, out ptr, out matType, out width, out height); // ptr=2157902018096 cType=byte width=830 height=822
|
||||||
|
ptr = mats[0].Data; // 取灰度图值
|
||||||
|
matType = mImage.GetType(); // byte
|
||||||
|
height = (uint)mImage.Rows; // 高
|
||||||
|
width = (uint)mImage.Cols; // 宽
|
||||||
|
|
||||||
|
// 改自:hImage = new HObject(new OpenCvSharp.Size(width, height), MatType.CV_8UC1, newScalar(0));
|
||||||
|
byte[] dataGrayScaleImage = new byte[width * height]; //Mat dataGrayScaleImage = new Mat(new OpenCvSharp.Size(width, height), MatType.CV_8UC1);
|
||||||
|
|
||||||
|
unsafe
|
||||||
|
{
|
||||||
|
fixed (byte* ptrdata = dataGrayScaleImage)
|
||||||
|
{
|
||||||
|
|
||||||
|
#region 按行复制
|
||||||
|
//for (int i = 0; i < height; i++)
|
||||||
|
//{
|
||||||
|
// CopyMemory((IntPtr)(ptrdata + width * i), new IntPtr((long)ptr + width *i), width);
|
||||||
|
//}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
CopyMemory((IntPtr)ptrdata, new IntPtr((long)ptr), width * height);
|
||||||
|
HOperatorSet.GenImage1(out hImage, "byte", width, height, (IntPtr)ptrdata);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return hImage;
|
||||||
|
}
|
||||||
|
else if (matChannels == 3) // 三通道
|
||||||
|
{
|
||||||
|
IntPtr ptrRed; // R通道图
|
||||||
|
IntPtr ptrGreen; // G通道图
|
||||||
|
IntPtr ptrBlue; // B通道图
|
||||||
|
Mat[] mats = mImage.Split();
|
||||||
|
|
||||||
|
ptrRed = mats[0].Data; // 取R通道值
|
||||||
|
ptrGreen = mats[1].Data; // 取G通道值
|
||||||
|
ptrBlue = mats[2].Data; // 取B通道值
|
||||||
|
matType = mImage.GetType(); // 类型
|
||||||
|
height = (uint)mImage.Rows; // 高
|
||||||
|
width = (uint)mImage.Cols; // 宽
|
||||||
|
|
||||||
|
// 改自:hImage = new HObject(new OpenCvSharp.Size(width, height), MatType.CV_8UC1, new Scalar(0));
|
||||||
|
byte[] dataRed = new byte[width * height]; //Mat dataGrayScaleImage = new Mat(new OpenCvSharp.Size(width, height), MatType.CV_8UC1);
|
||||||
|
byte[] dataGreen = new byte[width * height];
|
||||||
|
byte[] dataBlue = new byte[width * height];
|
||||||
|
|
||||||
|
unsafe
|
||||||
|
{
|
||||||
|
fixed (byte* ptrdataRed = dataRed, ptrdataGreen = dataGreen, ptrdataBlue = dataBlue)
|
||||||
|
{
|
||||||
|
|
||||||
|
#region 按行复制
|
||||||
|
//HImage himg = new HImage("byte", width, height, (IntPtr)ptrdataRed);
|
||||||
|
//for (int i = 0; i < height; i++)
|
||||||
|
//{
|
||||||
|
// CopyMemory((IntPtr)(ptrdataRed + width * i), new IntPtr((long)ptrRed +width * i), width);
|
||||||
|
// CopyMemory((IntPtr)(ptrdataGreen + width * i), new IntPtr((long)ptrGreen+ width * i), width);
|
||||||
|
// CopyMemory((IntPtr)(ptrdataBlue + width * i), new IntPtr((long)ptrBlue +width * i), width);
|
||||||
|
//}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
CopyMemory((IntPtr)ptrdataRed, new IntPtr((long)ptrRed), width* height); // 复制R通道
|
||||||
|
CopyMemory((IntPtr)ptrdataGreen, new IntPtr((long)ptrGreen), width * height); // 复制G通道
|
||||||
|
CopyMemory((IntPtr)ptrdataBlue, new IntPtr((long)ptrBlue), width * height); // 复制B通道
|
||||||
|
HOperatorSet.GenImage3(out hImage, "byte", width, height, (IntPtr)ptrdataRed, (IntPtr)ptrdataGreen, (IntPtr)ptrdataBlue); // 合成
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return hImage;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
throw ex;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public static Mat HImageToMat(this HObject hobj)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Mat mImage;
|
||||||
|
HTuple htChannels;
|
||||||
|
HTuple cType = null;
|
||||||
|
HTuple width, height;
|
||||||
|
width = height = 0;
|
||||||
|
|
||||||
|
HOperatorSet.CountChannels(hobj, out htChannels);
|
||||||
|
|
||||||
|
if (htChannels.Length == 0)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (htChannels[0].I == 1)
|
||||||
|
{
|
||||||
|
HTuple ptr;
|
||||||
|
HOperatorSet.GetImagePointer1(hobj, out ptr, out cType, out width, out height);
|
||||||
|
mImage = new Mat(height, width, MatType.CV_8UC1, new Scalar(0));
|
||||||
|
|
||||||
|
unsafe
|
||||||
|
{
|
||||||
|
CopyMemory(mImage.Data, new IntPtr((byte*)ptr.IP), (uint)(width * height));// CopyMemory(要复制到的地址,复制源的地址,复制的长度)
|
||||||
|
}
|
||||||
|
|
||||||
|
return mImage;
|
||||||
|
}
|
||||||
|
else if (htChannels[0].I == 3)
|
||||||
|
{
|
||||||
|
HTuple ptrRed;
|
||||||
|
HTuple ptrGreen;
|
||||||
|
HTuple ptrBlue;
|
||||||
|
|
||||||
|
HOperatorSet.GetImagePointer3(hobj, out ptrRed, out ptrGreen, out ptrBlue, out cType, out width, out height);
|
||||||
|
Mat pImageRed = new Mat(new OpenCvSharp.Size(width, height), MatType.CV_8UC1);
|
||||||
|
Mat pImageGreen = new Mat(new OpenCvSharp.Size(width, height), MatType.CV_8UC1);
|
||||||
|
Mat pImageBlue = new Mat(new OpenCvSharp.Size(width, height), MatType.CV_8UC1);
|
||||||
|
mImage = new Mat(new OpenCvSharp.Size(width, height), MatType.CV_8UC3, new Scalar(0, 0, 0));
|
||||||
|
unsafe
|
||||||
|
{
|
||||||
|
CopyMemory(pImageRed.Data, new IntPtr((byte*)ptrRed.IP), (uint)(width * height)); // CopyMemory(要复制到的地址,复制源的地址,复制的长度)_Red
|
||||||
|
CopyMemory(pImageGreen.Data, new IntPtr((byte*)ptrGreen.IP), (uint)(width * height)); // CopyMemory(要复制到的地址,复制源的地址,复制的长度)_Green
|
||||||
|
CopyMemory(pImageBlue.Data, new IntPtr((byte*)ptrBlue.IP), (uint)(width * height)); // CopyMemory(要复制到的地址,复制源的地址,复制的长度)_Blue
|
||||||
|
|
||||||
|
}
|
||||||
|
Mat[] multi = new Mat[] { pImageBlue, pImageGreen, pImageRed };
|
||||||
|
Cv2.Merge(multi, mImage);
|
||||||
|
pImageRed.Dispose();
|
||||||
|
pImageRed = null;
|
||||||
|
pImageGreen.Dispose();
|
||||||
|
pImageGreen = null;
|
||||||
|
pImageBlue.Dispose();
|
||||||
|
pImageBlue = null;
|
||||||
|
return mImage;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
throw ex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 从内存流中指定位置,读取数据
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="curStream"></param>
|
||||||
|
/// <param name="startPosition"></param>
|
||||||
|
/// <param name="length"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static int ReadData(MemoryStream curStream, int startPosition, int length)
|
||||||
|
{
|
||||||
|
int result = -1;
|
||||||
|
|
||||||
|
byte[] tempData = new byte[length];
|
||||||
|
curStream.Position = startPosition;
|
||||||
|
curStream.Read(tempData, 0, length);
|
||||||
|
result = BitConverter.ToInt32(tempData, 0);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 使用byte[]数据,生成三通道 BMP 位图
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="originalImageData"></param>
|
||||||
|
/// <param name="originalWidth"></param>
|
||||||
|
/// <param name="originalHeight"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static Bitmap CreateColorBitmap(byte[] originalImageData, int originalWidth, int originalHeight, byte[] color_map)
|
||||||
|
{
|
||||||
|
// 指定8位格式,即256色
|
||||||
|
Bitmap resultBitmap = new Bitmap(originalWidth, originalHeight, System.Drawing.Imaging.PixelFormat.Format8bppIndexed);
|
||||||
|
|
||||||
|
// 将该位图存入内存中
|
||||||
|
MemoryStream curImageStream = new MemoryStream();
|
||||||
|
resultBitmap.Save(curImageStream, System.Drawing.Imaging.ImageFormat.Bmp);
|
||||||
|
curImageStream.Flush();
|
||||||
|
|
||||||
|
// 由于位图数据需要DWORD对齐(4byte倍数),计算需要补位的个数
|
||||||
|
int curPadNum = ((originalWidth * 8 + 31) / 32 * 4) - originalWidth;
|
||||||
|
|
||||||
|
// 最终生成的位图数据大小
|
||||||
|
int bitmapDataSize = ((originalWidth * 8 + 31) / 32 * 4) * originalHeight;
|
||||||
|
|
||||||
|
// 数据部分相对文件开始偏移,具体可以参考位图文件格式
|
||||||
|
int dataOffset = ReadData(curImageStream, 10, 4);
|
||||||
|
|
||||||
|
|
||||||
|
// 改变调色板,因为默认的调色板是32位彩色的,需要修改为256色的调色板
|
||||||
|
int paletteStart = 54;
|
||||||
|
int paletteEnd = dataOffset;
|
||||||
|
int color = 0;
|
||||||
|
|
||||||
|
for (int i = paletteStart; i < paletteEnd; i += 4)
|
||||||
|
{
|
||||||
|
byte[] tempColor = new byte[4];
|
||||||
|
tempColor[0] = (byte)color;
|
||||||
|
tempColor[1] = (byte)color;
|
||||||
|
tempColor[2] = (byte)color;
|
||||||
|
tempColor[3] = (byte)0;
|
||||||
|
color++;
|
||||||
|
|
||||||
|
curImageStream.Position = i;
|
||||||
|
curImageStream.Write(tempColor, 0, 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 最终生成的位图数据,以及大小,高度没有变,宽度需要调整
|
||||||
|
byte[] destImageData = new byte[bitmapDataSize];
|
||||||
|
int destWidth = originalWidth + curPadNum;
|
||||||
|
|
||||||
|
// 生成最终的位图数据,注意的是,位图数据 从左到右,从下到上,所以需要颠倒
|
||||||
|
for (int originalRowIndex = originalHeight - 1; originalRowIndex >= 0; originalRowIndex--)
|
||||||
|
{
|
||||||
|
int destRowIndex = originalHeight - originalRowIndex - 1;
|
||||||
|
|
||||||
|
for (int dataIndex = 0; dataIndex < originalWidth; dataIndex++)
|
||||||
|
{
|
||||||
|
// 同时还要注意,新的位图数据的宽度已经变化destWidth,否则会产生错位
|
||||||
|
destImageData[destRowIndex * destWidth + dataIndex] = originalImageData[originalRowIndex * originalWidth + dataIndex];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 将流的Position移到数据段
|
||||||
|
curImageStream.Position = dataOffset;
|
||||||
|
|
||||||
|
// 将新位图数据写入内存中
|
||||||
|
curImageStream.Write(destImageData, 0, bitmapDataSize);
|
||||||
|
|
||||||
|
curImageStream.Flush();
|
||||||
|
|
||||||
|
// 将内存中的位图写入Bitmap对象
|
||||||
|
resultBitmap = new Bitmap(curImageStream);
|
||||||
|
|
||||||
|
resultBitmap = Convert8to24(resultBitmap, color_map); // 转为3通道图像
|
||||||
|
|
||||||
|
return resultBitmap;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 实现单通道到多通道
|
||||||
|
public static Bitmap Convert8to24(this Bitmap bmp, byte[] color_map)
|
||||||
|
{
|
||||||
|
|
||||||
|
Rectangle rect = new System.Drawing.Rectangle(0, 0, bmp.Width, bmp.Height);
|
||||||
|
BitmapData bitmapData = bmp.LockBits(rect, ImageLockMode.ReadOnly, bmp.PixelFormat);
|
||||||
|
|
||||||
|
//计算实际8位图容量
|
||||||
|
int size8 = bitmapData.Stride * bmp.Height;
|
||||||
|
byte[] grayValues = new byte[size8];
|
||||||
|
|
||||||
|
//// 申请目标位图的变量,并将其内存区域锁定
|
||||||
|
Bitmap TempBmp = new Bitmap(bmp.Width, bmp.Height, PixelFormat.Format24bppRgb);
|
||||||
|
BitmapData TempBmpData = TempBmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.WriteOnly, PixelFormat.Format24bppRgb);
|
||||||
|
|
||||||
|
|
||||||
|
//// 获取图像参数以及设置24位图信息
|
||||||
|
int stride = TempBmpData.Stride; // 扫描线的宽度
|
||||||
|
int offset = stride - TempBmp.Width; // 显示宽度与扫描线宽度的间隙
|
||||||
|
IntPtr iptr = TempBmpData.Scan0; // 获取bmpData的内存起始位置
|
||||||
|
int scanBytes = stride * TempBmp.Height;// 用stride宽度,表示这是内存区域的大小
|
||||||
|
|
||||||
|
// 下面把原始的显示大小字节数组转换为内存中实际存放的字节数组
|
||||||
|
byte[] pixelValues = new byte[scanBytes]; //为目标数组分配内存
|
||||||
|
System.Runtime.InteropServices.Marshal.Copy(bitmapData.Scan0, grayValues, 0, size8);
|
||||||
|
|
||||||
|
for (int i = 0; i < bmp.Height; i++)
|
||||||
|
{
|
||||||
|
|
||||||
|
for (int j = 0; j < bitmapData.Stride; j++)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (j >= bmp.Width)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
int indexSrc = i * bitmapData.Stride + j;
|
||||||
|
int realIndex = i * TempBmpData.Stride + j * 3;
|
||||||
|
|
||||||
|
// color_id:就是预测出来的结果
|
||||||
|
int color_id = (int)grayValues[indexSrc] % 256;
|
||||||
|
|
||||||
|
if (color_id == 0) // 分割中类别1对应值1,而背景往往为0,因此这里就将背景置为[0, 0, 0]
|
||||||
|
{
|
||||||
|
// 空白
|
||||||
|
pixelValues[realIndex] = 0;
|
||||||
|
pixelValues[realIndex + 1] = 0;
|
||||||
|
pixelValues[realIndex + 2] = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// 替换为color_map中的颜色值
|
||||||
|
pixelValues[realIndex] = color_map[color_id * 3];
|
||||||
|
pixelValues[realIndex + 1] = color_map[color_id * 3 + 1];
|
||||||
|
pixelValues[realIndex + 2] = color_map[color_id * 3 + 2];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Parallel.For(0, width * height, i =>
|
||||||
|
// {
|
||||||
|
// int index = (i + 1) % width + widthIn4 * ((i + 1) / width) - 1;
|
||||||
|
|
||||||
|
// showBitmapBuffer[index * 6] = bitmapBuffer[index * 6] = data[i * 2];
|
||||||
|
// showBitmapBuffer[index * 6 + 1] = bitmapBuffer[index * 6 + 1] = data[i * 2 + 1];
|
||||||
|
// });
|
||||||
|
|
||||||
|
// 用Marshal的Copy方法,将刚才得到的内存字节数组复制到BitmapData中
|
||||||
|
Marshal.Copy(pixelValues, 0, iptr, scanBytes);
|
||||||
|
TempBmp.UnlockBits(TempBmpData); // 解锁内存区域
|
||||||
|
bmp.UnlockBits(bitmapData);
|
||||||
|
return TempBmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 获取伪彩色图的RGB值 -- 同时也是适用于检测框分类颜色
|
||||||
|
public static byte[] GetColorMap(int num_classes = 256)
|
||||||
|
{
|
||||||
|
num_classes += 1;
|
||||||
|
byte[] color_map = new byte[num_classes * 3];
|
||||||
|
for (int i = 0; i < num_classes; i++)
|
||||||
|
{
|
||||||
|
int j = 0;
|
||||||
|
int lab = i;
|
||||||
|
while (lab != 0)
|
||||||
|
{
|
||||||
|
color_map[i * 3] |= (byte)(((lab >> 0) & 1) << (7 - j));
|
||||||
|
color_map[i * 3 + 1] |= (byte)(((lab >> 1) & 1) << (7 - j));
|
||||||
|
color_map[i * 3 + 2] |= (byte)(((lab >> 2) & 1) << (7 - j));
|
||||||
|
|
||||||
|
j += 1;
|
||||||
|
lab >>= 3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 去掉底色
|
||||||
|
color_map = color_map.Skip(3).ToArray();
|
||||||
|
return color_map;
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetGrayMap
|
||||||
|
public static byte[] GetGrayMap(int num_classes = 256)
|
||||||
|
{
|
||||||
|
byte[] color_map = new byte[num_classes];
|
||||||
|
for (int i = 0; i < num_classes; i++)
|
||||||
|
{
|
||||||
|
if (i <= 100)
|
||||||
|
color_map[i] = 0;
|
||||||
|
if (i > 100 && i <= 200)
|
||||||
|
color_map[i] = 100;
|
||||||
|
if (i > 200)
|
||||||
|
color_map[i] = 255;
|
||||||
|
|
||||||
|
}
|
||||||
|
return color_map;
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// 像素点阵转换为bitmap 二值化图
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="rawValues">byte[]数组</param>
|
||||||
|
/// <param name="width">图片的宽度</param>
|
||||||
|
/// <param name="height">图片的高度</param>
|
||||||
|
/// <returns>bitmap图片</returns>
|
||||||
|
public static Bitmap CreateBinaryBitmap(byte[] rawValues, int width, int height)
|
||||||
|
{
|
||||||
|
Bitmap bmp = new Bitmap(width, height, System.Drawing.Imaging.PixelFormat.Format8bppIndexed);
|
||||||
|
BitmapData bmpData = bmp.LockBits(new System.Drawing.Rectangle(0, 0, width, height), ImageLockMode.WriteOnly, System.Drawing.Imaging.PixelFormat.Format8bppIndexed);
|
||||||
|
//获取图像参数
|
||||||
|
int stride = bmpData.Stride; // 扫描线的宽度
|
||||||
|
int offset = stride - width; // 显示宽度与扫描线宽度的间隙
|
||||||
|
IntPtr iptr = bmpData.Scan0; // 获取bmpData的内存起始位置
|
||||||
|
int scanBytes = stride * height;// 用stride宽度,表示这是内存区域的大小
|
||||||
|
//下面把原始的显示大小字节数组转换为内存中实际存放的字节数组
|
||||||
|
int posScan = 0, posReal = 0;// 分别设置两个位置指针,指向源数组和目标数组
|
||||||
|
byte[] pixelValues = new byte[scanBytes]; //为目标数组分配内存
|
||||||
|
for (int x = 0; x < height; x++)
|
||||||
|
{
|
||||||
|
//下面的循环节是模拟行扫描
|
||||||
|
for (int y = 0; y < width; y++)
|
||||||
|
{
|
||||||
|
pixelValues[posScan++] = rawValues[posReal++] == 0 ? (byte)0 : (byte)255;
|
||||||
|
}
|
||||||
|
posScan += offset; //行扫描结束,要将目标位置指针移过那段“间隙”
|
||||||
|
}
|
||||||
|
//用Marshal的Copy方法,将刚才得到的内存字节数组复制到BitmapData中
|
||||||
|
Marshal.Copy(pixelValues, 0, iptr, scanBytes);
|
||||||
|
bmp.UnlockBits(bmpData); // 解锁内存区域
|
||||||
|
//下面的代码是为了修改生成位图的索引表,从伪彩修改为灰度
|
||||||
|
ColorPalette tempPalette;
|
||||||
|
using (Bitmap tempBmp = new Bitmap(1, 1, System.Drawing.Imaging.PixelFormat.Format8bppIndexed))
|
||||||
|
{
|
||||||
|
tempPalette = tempBmp.Palette;
|
||||||
|
}
|
||||||
|
for (int i = 0; i < 256; i++)
|
||||||
|
{
|
||||||
|
tempPalette.Entries[i] = System.Drawing.Color.FromArgb(i, i, i);
|
||||||
|
}
|
||||||
|
|
||||||
|
bmp.Palette = tempPalette;
|
||||||
|
|
||||||
|
return bmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 像素点阵转换为bitmap灰度图
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="rawValues">byte[]数组</param>
|
||||||
|
/// <param name="width">图片的宽度</param>
|
||||||
|
/// <param name="height">图片的高度</param>
|
||||||
|
/// <returns>bitmap图片</returns>
|
||||||
|
public static Bitmap CreateGrayBitmap(byte[] rawValues, int width, int height)
|
||||||
|
{
|
||||||
|
Bitmap bmp = new Bitmap(width, height, System.Drawing.Imaging.PixelFormat.Format8bppIndexed);
|
||||||
|
BitmapData bmpData = bmp.LockBits(new System.Drawing.Rectangle(0, 0, width, height), ImageLockMode.WriteOnly, System.Drawing.Imaging.PixelFormat.Format8bppIndexed);
|
||||||
|
//获取图像参数
|
||||||
|
int stride = bmpData.Stride; // 扫描线的宽度
|
||||||
|
int offset = stride - width; // 显示宽度与扫描线宽度的间隙
|
||||||
|
IntPtr iptr = bmpData.Scan0; // 获取bmpData的内存起始位置
|
||||||
|
int scanBytes = stride * height;// 用stride宽度,表示这是内存区域的大小
|
||||||
|
//下面把原始的显示大小字节数组转换为内存中实际存放的字节数组
|
||||||
|
int posScan = 0, posReal = 0;// 分别设置两个位置指针,指向源数组和目标数组
|
||||||
|
byte[] pixelValues = new byte[scanBytes]; //为目标数组分配内存
|
||||||
|
for (int x = 0; x < height; x++)
|
||||||
|
{
|
||||||
|
//下面的循环节是模拟行扫描
|
||||||
|
for (int y = 0; y < width; y++)
|
||||||
|
{
|
||||||
|
pixelValues[posScan++] = rawValues[posReal++];
|
||||||
|
}
|
||||||
|
posScan += offset; //行扫描结束,要将目标位置指针移过那段“间隙”
|
||||||
|
}
|
||||||
|
//用Marshal的Copy方法,将刚才得到的内存字节数组复制到BitmapData中
|
||||||
|
Marshal.Copy(pixelValues, 0, iptr, scanBytes);
|
||||||
|
bmp.UnlockBits(bmpData); // 解锁内存区域
|
||||||
|
//下面的代码是为了修改生成位图的索引表,从伪彩修改为灰度
|
||||||
|
ColorPalette tempPalette;
|
||||||
|
using (Bitmap tempBmp = new Bitmap(1, 1, System.Drawing.Imaging.PixelFormat.Format8bppIndexed))
|
||||||
|
{
|
||||||
|
tempPalette = tempBmp.Palette;
|
||||||
|
}
|
||||||
|
for (int i = 0; i < 256; i++)
|
||||||
|
{
|
||||||
|
tempPalette.Entries[i] = System.Drawing.Color.FromArgb(i, i, i);
|
||||||
|
}
|
||||||
|
|
||||||
|
bmp.Palette = tempPalette;
|
||||||
|
|
||||||
|
return bmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//分别基于像素(GetPixel和SetPixel)、基于内存、基于指针这三种方法增强图片对比度。
|
||||||
|
// 第一种方法:像素提取法。速度慢 基于像素:400-600ms
|
||||||
|
public static Bitmap MethodBaseOnPixel(Bitmap bitmap, int degree)
|
||||||
|
{
|
||||||
|
Color curColor;
|
||||||
|
int grayR, grayG, grayB;
|
||||||
|
|
||||||
|
double Deg = (100.0 + degree) / 100.0;
|
||||||
|
for (int i = 0; i < bitmap.Width; i++)
|
||||||
|
{
|
||||||
|
for (int j = 0; j < bitmap.Height; j++)
|
||||||
|
{
|
||||||
|
curColor = bitmap.GetPixel(i, j);
|
||||||
|
grayR = Convert.ToInt32((((curColor.R / 255.0 - 0.5) * Deg + 0.5)) * 255);
|
||||||
|
grayG = Convert.ToInt32((((curColor.G / 255.0 - 0.5) * Deg + 0.5)) * 255);
|
||||||
|
grayB = Convert.ToInt32((((curColor.B / 255.0 - 0.5) * Deg + 0.5)) * 255);
|
||||||
|
if (grayR < 0)
|
||||||
|
grayR = 0;
|
||||||
|
else if (grayR > 255)
|
||||||
|
grayR = 255;
|
||||||
|
|
||||||
|
if (grayB < 0)
|
||||||
|
grayB = 0;
|
||||||
|
else if (grayB > 255)
|
||||||
|
grayB = 255;
|
||||||
|
|
||||||
|
if (grayG < 0)
|
||||||
|
grayG = 0;
|
||||||
|
else if (grayG > 255)
|
||||||
|
grayG = 255;
|
||||||
|
|
||||||
|
bitmap.SetPixel(i, j, Color.FromArgb(grayR, grayG, grayB));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return bitmap;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 第二种方法:基于内存 17-18ms
|
||||||
|
public static unsafe Bitmap MethodBaseOnMemory(Bitmap bitmap, int degree)
|
||||||
|
{
|
||||||
|
if (bitmap == null)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
double Deg = (100.0 + degree) / 100.0;
|
||||||
|
|
||||||
|
int width = bitmap.Width;
|
||||||
|
int height = bitmap.Height;
|
||||||
|
|
||||||
|
int length = height * 3 * width;
|
||||||
|
byte[] RGB = new byte[length];
|
||||||
|
|
||||||
|
BitmapData data = bitmap.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
|
||||||
|
|
||||||
|
System.IntPtr Scan0 = data.Scan0;
|
||||||
|
System.Runtime.InteropServices.Marshal.Copy(Scan0, RGB, 0, length);
|
||||||
|
|
||||||
|
double gray = 0;
|
||||||
|
for (int i = 0; i < RGB.Length; i += 3)
|
||||||
|
{
|
||||||
|
for (int j = 0; j < 3; j++)
|
||||||
|
{
|
||||||
|
gray = (((RGB[i + j] / 255.0 - 0.5) * Deg + 0.5)) * 255.0;
|
||||||
|
if (gray > 255)
|
||||||
|
gray = 255;
|
||||||
|
|
||||||
|
if (gray < 0)
|
||||||
|
gray = 0;
|
||||||
|
RGB[i + j] = (byte)gray;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
System.Runtime.InteropServices.Marshal.Copy(RGB, 0, Scan0, length);// 此处Copy是之前Copy的逆操作
|
||||||
|
bitmap.UnlockBits(data);
|
||||||
|
return bitmap;
|
||||||
|
}
|
||||||
|
|
||||||
|
//第三种方法:基于指针 20-23ms
|
||||||
|
public static unsafe Bitmap MethodBaseOnPtr(Bitmap b, int degree)
|
||||||
|
{
|
||||||
|
if (b == null)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
try
|
||||||
|
{
|
||||||
|
double num = 0.0;
|
||||||
|
double num2 = (100.0 + degree) / 100.0;
|
||||||
|
num2 *= num2;
|
||||||
|
int width = b.Width;
|
||||||
|
int height = b.Height;
|
||||||
|
BitmapData bitmapdata = b.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
|
||||||
|
byte* numPtr = (byte*)bitmapdata.Scan0;
|
||||||
|
|
||||||
|
int offset = bitmapdata.Stride - (width * 3);
|
||||||
|
for (int i = 0; i < height; i++)
|
||||||
|
{
|
||||||
|
for (int j = 0; j < width; j++)
|
||||||
|
{
|
||||||
|
for (int k = 0; k < 3; k++)
|
||||||
|
{
|
||||||
|
num = ((((((double)numPtr[k]) / 255.0) - 0.5) * num2) + 0.5) * 255.0;
|
||||||
|
if (num < 0.0)
|
||||||
|
{
|
||||||
|
num = 0.0;
|
||||||
|
}
|
||||||
|
if (num > 255.0)
|
||||||
|
{
|
||||||
|
num = 255.0;
|
||||||
|
}
|
||||||
|
numPtr[k] = (byte)num;
|
||||||
|
}
|
||||||
|
numPtr += 3;
|
||||||
|
|
||||||
|
}
|
||||||
|
numPtr += offset;
|
||||||
|
}
|
||||||
|
b.UnlockBits(bitmapdata);
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static double GetRoiArae(Mat src, Rect rect)
|
||||||
|
{
|
||||||
|
//初始面积为0
|
||||||
|
double Area = 0;
|
||||||
|
//获取感兴趣区域
|
||||||
|
src = src[rect];
|
||||||
|
//转为单通道
|
||||||
|
Mat gray = src.CvtColor(ColorConversionCodes.BGR2GRAY);
|
||||||
|
//二值化
|
||||||
|
Mat binary = gray.Threshold(0, 255, ThresholdTypes.Otsu | ThresholdTypes.Binary);
|
||||||
|
|
||||||
|
//求轮廓 不连通会有多个闭合区域
|
||||||
|
OpenCvSharp.Point[][] contours;
|
||||||
|
HierarchyIndex[] hierarchy;
|
||||||
|
Cv2.FindContours(binary, out contours, out hierarchy, RetrievalModes.List, ContourApproximationModes.ApproxSimple);
|
||||||
|
for (int i = 0; i < contours.Count(); i++)
|
||||||
|
{
|
||||||
|
//所有面积相加
|
||||||
|
Area += Cv2.ContourArea(contours[i], false);
|
||||||
|
}
|
||||||
|
return Area;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
117
DH.Commons/Helper/SchemeHelper.cs
Normal file
117
DH.Commons/Helper/SchemeHelper.cs
Normal file
@@ -0,0 +1,117 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace DH.Commons.Helper
|
||||||
|
{
|
||||||
|
public static class SchemeHelper
|
||||||
|
{
|
||||||
|
private const string SchemesKey = "Schemes";
|
||||||
|
private const string CurrentSchemeKey = "CurrentScheme";
|
||||||
|
private const char Separator = '|';
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 初始化配置(首次运行时调用)
|
||||||
|
/// </summary>
|
||||||
|
public static void Initialize()
|
||||||
|
{
|
||||||
|
// 如果Schemes不存在,创建空键
|
||||||
|
if (!SystemConfigHelper.KeyExists(SchemesKey))
|
||||||
|
{
|
||||||
|
SystemConfigHelper.SetValue(SchemesKey, "");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果CurrentScheme不存在,创建空键
|
||||||
|
if (!SystemConfigHelper.KeyExists(CurrentSchemeKey))
|
||||||
|
{
|
||||||
|
SystemConfigHelper.SetValue(CurrentSchemeKey, "");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取所有方案(自动处理空值)
|
||||||
|
/// </summary>
|
||||||
|
public static List<string> GetAllSchemes()
|
||||||
|
{
|
||||||
|
var schemeString = SystemConfigHelper.GetValue(SchemesKey, "");
|
||||||
|
return string.IsNullOrEmpty(schemeString)
|
||||||
|
? new List<string>()
|
||||||
|
: new List<string>(schemeString.Split(Separator));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 添加新方案(自动初始化处理)
|
||||||
|
/// </summary>
|
||||||
|
public static void AddScheme(string schemeName)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(schemeName))
|
||||||
|
throw new ArgumentException("方案名称无效");
|
||||||
|
|
||||||
|
var schemes = GetAllSchemes();
|
||||||
|
|
||||||
|
if (schemes.Contains(schemeName))
|
||||||
|
throw new InvalidOperationException($"方案 {schemeName} 已存在");
|
||||||
|
|
||||||
|
schemes.Add(schemeName);
|
||||||
|
SaveSchemes(schemes);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 设置当前方案(空值安全处理)
|
||||||
|
/// </summary>
|
||||||
|
public static void SetCurrentScheme(string schemeName)
|
||||||
|
{
|
||||||
|
var schemes = GetAllSchemes();
|
||||||
|
|
||||||
|
if (!schemes.Contains(schemeName))
|
||||||
|
throw new KeyNotFoundException($"方案 {schemeName} 不存在");
|
||||||
|
|
||||||
|
SystemConfigHelper.SetValue(CurrentSchemeKey, schemeName);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取当前方案(默认值处理)
|
||||||
|
/// </summary>
|
||||||
|
public static string GetCurrentScheme()
|
||||||
|
{
|
||||||
|
var current = SystemConfigHelper.GetValue(CurrentSchemeKey, "");
|
||||||
|
return !string.IsNullOrEmpty(current) ? current : "默认方案";
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void SaveSchemes(List<string> schemes)
|
||||||
|
{
|
||||||
|
var schemeString = schemes.Count > 0
|
||||||
|
? string.Join(Separator.ToString(), schemes)
|
||||||
|
: "";
|
||||||
|
SystemConfigHelper.SetValue(SchemesKey, schemeString);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 删除指定方案(自动同步当前方案状态)
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="schemeName">要删除的方案名称</param>
|
||||||
|
/// <exception cref="ArgumentException">当方案名称为空时抛出</exception>
|
||||||
|
/// <exception cref="KeyNotFoundException">当方案不存在时抛出</exception>
|
||||||
|
public static void DeleteScheme(string schemeName)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(schemeName))
|
||||||
|
throw new ArgumentException("方案名称无效");
|
||||||
|
|
||||||
|
var schemes = GetAllSchemes();
|
||||||
|
|
||||||
|
if (!schemes.Contains(schemeName))
|
||||||
|
throw new KeyNotFoundException($"方案 {schemeName} 不存在");
|
||||||
|
|
||||||
|
// 删除前检查是否是当前方案
|
||||||
|
bool isCurrent = GetCurrentScheme() == schemeName;
|
||||||
|
|
||||||
|
// 执行删除操作
|
||||||
|
schemes.Remove(schemeName);
|
||||||
|
SaveSchemes(schemes);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
680
DH.Commons/Helper/StaticHelper.cs
Normal file
680
DH.Commons/Helper/StaticHelper.cs
Normal file
@@ -0,0 +1,680 @@
|
|||||||
|
using Microsoft.CSharp.RuntimeBinder;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using System.Collections.ObjectModel;
|
||||||
|
using System.Drawing.Imaging;
|
||||||
|
using System.Dynamic;
|
||||||
|
using System.Linq.Expressions;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
using System.Runtime.ExceptionServices;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Runtime.Serialization.Formatters.Binary;
|
||||||
|
|
||||||
|
namespace DH.Commons.Helper
|
||||||
|
{
|
||||||
|
public static class StaticHelper
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 数值转换为byte数组 高位在前,低位在后
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="number"></param>
|
||||||
|
/// <param name="size"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static byte[] IntToBytes(this int number, int size = 2)
|
||||||
|
{
|
||||||
|
byte[] result = new byte[size];
|
||||||
|
|
||||||
|
int temp = size;
|
||||||
|
while (temp > 0)
|
||||||
|
{
|
||||||
|
result[size - temp] = (byte)(number >> ((temp - 1) * 8) & 0xff);
|
||||||
|
|
||||||
|
temp--;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
public static T DeepSerializeClone<T>(this T t)
|
||||||
|
{
|
||||||
|
return JsonConvert.DeserializeObject<T>(JsonConvert.SerializeObject(t));
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// 字节数组转换为整数
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="data">字节数组</param>
|
||||||
|
/// <param name="HtL">true:数组序号低的在高位 false:数组序号低的在低位</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static int BytesToInt(this byte[] data, bool HtL = true)
|
||||||
|
{
|
||||||
|
int res = 0;
|
||||||
|
|
||||||
|
for (int i = 0; i < data.Length; i++)
|
||||||
|
{
|
||||||
|
int index = i;
|
||||||
|
|
||||||
|
if (HtL)
|
||||||
|
{
|
||||||
|
index = data.Length - 1 - i;
|
||||||
|
}
|
||||||
|
|
||||||
|
res += data[index] << (8 * i);
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取一个类指定的属性值
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="info">object对象</param>
|
||||||
|
/// <param name="field">属性名称</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static object GetPropertyValue(object info, string field)
|
||||||
|
{
|
||||||
|
if (info == null) return null;
|
||||||
|
Type t = info.GetType();
|
||||||
|
IEnumerable<System.Reflection.PropertyInfo> property = from pi in t.GetProperties() where pi.Name.ToLower() == field.ToLower() select pi;
|
||||||
|
return property.First().GetValue(info, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 将32位整形拆分为无符号16位整形
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="num">需要拆分的32位整形</param>
|
||||||
|
/// <param name="bitNum">拆分为16位整形的位数 1或者2</param>
|
||||||
|
/// <param name="HtL">true:高位在前,低位在后;false:高位在后,低位在前</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static List<ushort> ParseIntToUnsignShortList(this int num, int bitNum = 2, bool HtL = false)
|
||||||
|
{
|
||||||
|
if (bitNum == 2)
|
||||||
|
{
|
||||||
|
ushort high = (ushort)(num >> 16);
|
||||||
|
ushort low = (ushort)num;
|
||||||
|
|
||||||
|
if (HtL)
|
||||||
|
{
|
||||||
|
return new List<ushort>() { high, low };
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return new List<ushort>() { low, high };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (num < 0)
|
||||||
|
{
|
||||||
|
num = ushort.MaxValue + 1 + num;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new List<ushort>() { (ushort)num };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 将32位整形数组拆分为无符号16位整形数组
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="list">需要拆分的32位整形</param>
|
||||||
|
/// <param name="bitNum">拆分为16位整形的位数 1或者2</param>
|
||||||
|
/// <param name="HtL">true:高位在前,低位在后;false:高位在后,低位在前</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static List<ushort> ParseIntToUnsignShortList(this List<int> list, int bitNum = 2, bool HtL = false)
|
||||||
|
{
|
||||||
|
return list.SelectMany(u => u.ParseIntToUnsignShortList(bitNum, HtL)).ToList();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 将ushort的集合转换为16位带符号整形
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="numList"></param>
|
||||||
|
/// <param name="bitNum">合并的位数 1或者2</param>
|
||||||
|
/// <param name="HtL">true:高位在前,低位在后;false:高位在后,低位在前</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static List<int> ParseUnsignShortListToInt(this List<int> numList, int bitNum = 2, bool HtL = false)
|
||||||
|
{
|
||||||
|
if (bitNum == 1)
|
||||||
|
{
|
||||||
|
return numList.ConvertAll(n =>
|
||||||
|
{
|
||||||
|
int num = n;
|
||||||
|
if (num > short.MaxValue)
|
||||||
|
{
|
||||||
|
num = num - ushort.MaxValue - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return num;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
List<int> list = new List<int>();
|
||||||
|
for (int i = 0; i < numList.Count; i += 2)
|
||||||
|
{
|
||||||
|
int high = HtL ? numList[i] : numList[i + 1];
|
||||||
|
int low = HtL ? numList[i + 1] : numList[i];
|
||||||
|
list.Add((high << 16) | low);
|
||||||
|
}
|
||||||
|
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//public static T DeepSerializeClone<T>(this T t)
|
||||||
|
//{
|
||||||
|
// return JsonConvert.DeserializeObject<T>(JsonConvert.SerializeObject(t));
|
||||||
|
//}
|
||||||
|
|
||||||
|
public static void DataFrom<T1, T2>(this T1 destT, T2 sourceT, List<string> exceptionProps = null) where T1 : class where T2 : class
|
||||||
|
{
|
||||||
|
if (sourceT == null)
|
||||||
|
{
|
||||||
|
destT = null;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
PropertyInfo[] propDest = destT.GetType().GetProperties();//.Where(p => !(p.GetMethod.IsVirtual && !p.GetMethod.IsFinal)).ToArray();
|
||||||
|
PropertyInfo[] propSource = sourceT.GetType().GetProperties();
|
||||||
|
|
||||||
|
Array.ForEach(propDest, prop =>
|
||||||
|
{
|
||||||
|
if (exceptionProps == null || !exceptionProps.Contains(prop.Name))
|
||||||
|
{
|
||||||
|
if (prop.CanWrite)
|
||||||
|
{
|
||||||
|
PropertyInfo propS = propSource.FirstOrDefault(p => p.Name == prop.Name);
|
||||||
|
if (propS != null && propS.CanRead)
|
||||||
|
{
|
||||||
|
prop.SetValue(destT, propS.GetValue(sourceT));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//RtlMoveMemory
|
||||||
|
[DllImport("kernel32.dll", EntryPoint = "RtlMoveMemory", SetLastError = false)]
|
||||||
|
public static extern void CopyMemory(IntPtr dest, IntPtr src, uint count);
|
||||||
|
[HandleProcessCorruptedStateExceptions]
|
||||||
|
//public static Bitmap CopyBitmap(this Bitmap source)
|
||||||
|
//{
|
||||||
|
// Bitmap clone = new Bitmap(source.Width, source.Height, source.PixelFormat);
|
||||||
|
// try
|
||||||
|
// {
|
||||||
|
// int PixelSize = Bitmap.GetPixelFormatSize(source.PixelFormat) / 8;
|
||||||
|
// if (PixelSize == 1)
|
||||||
|
// {
|
||||||
|
// ColorPalette cp = clone.Palette;
|
||||||
|
// for (int i = 0; i < 256; i++)
|
||||||
|
// {
|
||||||
|
// cp.Entries[i] = Color.FromArgb(255, i, i, i);
|
||||||
|
// }
|
||||||
|
// clone.Palette = cp;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// Rectangle rect = new Rectangle(0, 0, source.Width, source.Height);
|
||||||
|
// BitmapData sourceData = source.LockBits(rect, ImageLockMode.ReadWrite, source.PixelFormat);
|
||||||
|
// BitmapData cloneData = clone.LockBits(rect, ImageLockMode.ReadWrite, source.PixelFormat);
|
||||||
|
// if (source.Width % 4 == 0)
|
||||||
|
// {
|
||||||
|
// unsafe
|
||||||
|
// {
|
||||||
|
// CopyMemory(cloneData.Scan0, sourceData.Scan0, (uint)(sourceData.Stride * sourceData.Height));
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
// {
|
||||||
|
// Parallel.For(0, source.Height, h =>
|
||||||
|
// {
|
||||||
|
// unsafe
|
||||||
|
// {
|
||||||
|
// CopyMemory(cloneData.Scan0 + h * sourceData.Stride, sourceData.Scan0 + h * sourceData.Stride, (uint)sourceData.Width);
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
// }
|
||||||
|
|
||||||
|
// clone.UnlockBits(cloneData);
|
||||||
|
// source.UnlockBits(sourceData);
|
||||||
|
|
||||||
|
// }
|
||||||
|
// catch (Exception ex)
|
||||||
|
// {
|
||||||
|
// return clone;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// return clone;
|
||||||
|
//}
|
||||||
|
public static Bitmap CopyBitmap(this Bitmap source)
|
||||||
|
{
|
||||||
|
Bitmap clone = new Bitmap(source.Width, source.Height, source.PixelFormat);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
int pixelSize = Bitmap.GetPixelFormatSize(source.PixelFormat) / 8;
|
||||||
|
if (pixelSize == 1)
|
||||||
|
{
|
||||||
|
ColorPalette cp = clone.Palette;
|
||||||
|
for (int i = 0; i < 256; i++)
|
||||||
|
{
|
||||||
|
cp.Entries[i] = Color.FromArgb(255, i, i, i);
|
||||||
|
}
|
||||||
|
clone.Palette = cp;
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle rect = new Rectangle(0, 0, source.Width, source.Height);
|
||||||
|
BitmapData sourceData = source.LockBits(rect, ImageLockMode.ReadOnly, source.PixelFormat);
|
||||||
|
BitmapData cloneData = clone.LockBits(rect, ImageLockMode.WriteOnly, source.PixelFormat);
|
||||||
|
|
||||||
|
int stride = sourceData.Stride;
|
||||||
|
int height = sourceData.Height;
|
||||||
|
|
||||||
|
if (stride % 4 == 0)
|
||||||
|
{
|
||||||
|
unsafe
|
||||||
|
{
|
||||||
|
CopyMemory(cloneData.Scan0, sourceData.Scan0, (uint)(stride * height));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Parallel.For(0, height, h =>
|
||||||
|
{
|
||||||
|
unsafe
|
||||||
|
{
|
||||||
|
CopyMemory(cloneData.Scan0 + h * stride, sourceData.Scan0 + h * stride, (uint)stride);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
source.UnlockBits(sourceData); clone.UnlockBits(cloneData);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{ // Handle or log exception if needed
|
||||||
|
} return clone; }
|
||||||
|
|
||||||
|
|
||||||
|
public static Bitmap BitmapDeepClone(Bitmap source)
|
||||||
|
{
|
||||||
|
Bitmap clone = new Bitmap(source.Width, source.Height, source.PixelFormat);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
int PixelSize = Bitmap.GetPixelFormatSize(source.PixelFormat) / 8;
|
||||||
|
if (PixelSize == 1)
|
||||||
|
{
|
||||||
|
ColorPalette cp = clone.Palette;
|
||||||
|
for (int i = 0; i < 256; i++)
|
||||||
|
{
|
||||||
|
cp.Entries[i] = Color.FromArgb(255, i, i, i);
|
||||||
|
}
|
||||||
|
clone.Palette = cp;
|
||||||
|
}
|
||||||
|
Rectangle rect = new Rectangle(0, 0, source.Width, source.Height);
|
||||||
|
BitmapData source_bitmap = source.LockBits(rect, ImageLockMode.ReadWrite, source.PixelFormat);
|
||||||
|
BitmapData destination_bitmap = clone.LockBits(rect, ImageLockMode.ReadWrite, clone.PixelFormat);
|
||||||
|
|
||||||
|
int depth_width = source_bitmap.Width * PixelSize;
|
||||||
|
|
||||||
|
unsafe
|
||||||
|
{
|
||||||
|
byte* source_ptr = (byte*)source_bitmap.Scan0;
|
||||||
|
byte* destination_ptr = (byte*)destination_bitmap.Scan0;
|
||||||
|
|
||||||
|
int offset = source_bitmap.Stride - depth_width;
|
||||||
|
|
||||||
|
for (int i = 0; i < source_bitmap.Height; i++)
|
||||||
|
{
|
||||||
|
for (int j = 0; j < depth_width; j++, source_ptr++, destination_ptr++)
|
||||||
|
{
|
||||||
|
*destination_ptr = *source_ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
source_ptr += offset;
|
||||||
|
destination_ptr += offset;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
source.UnlockBits(source_bitmap);
|
||||||
|
clone.UnlockBits(destination_bitmap);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
return clone;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public static Bitmap HConnectBitmap(this Bitmap map1, Bitmap map2)
|
||||||
|
{
|
||||||
|
Bitmap connectImage = null;
|
||||||
|
if (map1 == null || map2 == null)
|
||||||
|
return null;
|
||||||
|
//横向拼接
|
||||||
|
int width = map1.Width + map2.Width;
|
||||||
|
//高度不变
|
||||||
|
int height = Math.Max(map1.Height, map2.Height);
|
||||||
|
connectImage = new Bitmap(width, height);
|
||||||
|
using (Graphics graph = Graphics.FromImage(connectImage))
|
||||||
|
{
|
||||||
|
graph.DrawImage(connectImage, width, height);
|
||||||
|
graph.Clear(System.Drawing.Color.White);
|
||||||
|
graph.DrawImage(map1, 0, 0);
|
||||||
|
graph.DrawImage(map2, map1.Width, 0);
|
||||||
|
}
|
||||||
|
return connectImage;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static IntPtr FloatToIntptr(float[] bytes)
|
||||||
|
{
|
||||||
|
GCHandle hObject = GCHandle.Alloc(bytes, GCHandleType.Pinned);
|
||||||
|
return hObject.AddrOfPinnedObject();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 将Btimap类转换为byte[]类函数
|
||||||
|
public static byte[] GetBGRValues(Bitmap bmp, out int stride)
|
||||||
|
{
|
||||||
|
var rect = new Rectangle(0, 0, bmp.Width, bmp.Height);
|
||||||
|
var bmpData = bmp.LockBits(rect, ImageLockMode.ReadOnly, bmp.PixelFormat);
|
||||||
|
stride = bmpData.Stride;
|
||||||
|
var rowBytes = bmpData.Width * Image.GetPixelFormatSize(bmp.PixelFormat) / 8;
|
||||||
|
var imgBytes = bmp.Height * rowBytes;
|
||||||
|
byte[] rgbValues = new byte[imgBytes];
|
||||||
|
IntPtr ptr = bmpData.Scan0;
|
||||||
|
for (var i = 0; i < bmp.Height; i++)
|
||||||
|
{
|
||||||
|
Marshal.Copy(ptr, rgbValues, i * rowBytes, rowBytes);
|
||||||
|
ptr += bmpData.Stride;
|
||||||
|
}
|
||||||
|
bmp.UnlockBits(bmpData);
|
||||||
|
return rgbValues;
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// 缺陷灰度图转彩色图像函数
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="src">灰度图</param>
|
||||||
|
/// <returns>返回构造的伪彩色图像</returns>
|
||||||
|
public static Bitmap GrayMapToColorMap(this Bitmap src, Dictionary<int, Color> indexColorDict = null)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
//Stopwatch sw = new Stopwatch();
|
||||||
|
//sw.Start();
|
||||||
|
|
||||||
|
Bitmap dest = new Bitmap(src.Width, src.Height, PixelFormat.Format32bppArgb);
|
||||||
|
|
||||||
|
int destHeight = dest.Height;
|
||||||
|
int destWidth = dest.Width;
|
||||||
|
|
||||||
|
Rectangle rect = new Rectangle(0, 0, destWidth, destHeight);
|
||||||
|
BitmapData bmpDataDest = dest.LockBits(rect, ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
|
||||||
|
BitmapData bmpDataSrc = src.LockBits(rect, ImageLockMode.ReadWrite, PixelFormat.Format8bppIndexed);
|
||||||
|
int strideDest = bmpDataDest.Stride;
|
||||||
|
|
||||||
|
int strideSrc = bmpDataSrc.Stride;
|
||||||
|
unsafe
|
||||||
|
{
|
||||||
|
byte* pDest = (byte*)bmpDataDest.Scan0.ToPointer();
|
||||||
|
byte* pSrc = (byte*)bmpDataSrc.Scan0.ToPointer();
|
||||||
|
|
||||||
|
Parallel.For(0, destHeight, y =>
|
||||||
|
{
|
||||||
|
Parallel.For(0, destWidth, x =>
|
||||||
|
{
|
||||||
|
int pixel = pSrc[y * strideSrc + x];
|
||||||
|
int startIndex = y * strideDest + x * 4;
|
||||||
|
if (pixel >= 0 && pixel <= 63)
|
||||||
|
{
|
||||||
|
Color color = Color.Red;
|
||||||
|
if (indexColorDict != null && indexColorDict.ContainsKey(pixel))
|
||||||
|
{
|
||||||
|
color = indexColorDict[pixel];
|
||||||
|
}
|
||||||
|
|
||||||
|
byte R = color.R;
|
||||||
|
byte G = color.G;
|
||||||
|
byte B = color.B;
|
||||||
|
|
||||||
|
pDest[startIndex] = B;
|
||||||
|
pDest[startIndex + 1] = G;
|
||||||
|
pDest[startIndex + 2] = R;
|
||||||
|
pDest[startIndex + 3] = 100;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pDest[startIndex] = 255;
|
||||||
|
pDest[startIndex + 1] = 255;
|
||||||
|
pDest[startIndex + 2] = 255;
|
||||||
|
pDest[startIndex + 3] = 0;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
dest.UnlockBits(bmpDataDest);
|
||||||
|
src.UnlockBits(bmpDataSrc);
|
||||||
|
|
||||||
|
//sw.Stop();
|
||||||
|
//Console.WriteLine($"转换耗时:{sw.ElapsedMilliseconds}");
|
||||||
|
|
||||||
|
return dest;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void Sort<T>(this ObservableCollection<T> collection) where T : IComparable<T>
|
||||||
|
{
|
||||||
|
List<T> sortedList = collection.OrderByDescending(x => x).ToList();//这里用降序
|
||||||
|
for (int i = 0; i < sortedList.Count(); i++)
|
||||||
|
{
|
||||||
|
collection.Move(collection.IndexOf(sortedList[i]), i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获得字符串中开始和结束字符串中间的值
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="sourse"></param>
|
||||||
|
/// <param name="startstr"></param>
|
||||||
|
/// <param name="endstr"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static string GetMidString(string sourse, string startstr, string endstr)
|
||||||
|
{
|
||||||
|
string result = string.Empty;
|
||||||
|
int startindex, endindex;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
startindex = sourse.IndexOf(startstr);
|
||||||
|
if (startindex == -1)
|
||||||
|
return result;
|
||||||
|
string tmpstr = sourse.Substring(startindex + startstr.Length);
|
||||||
|
endindex = tmpstr.IndexOf(endstr);
|
||||||
|
if (endindex == -1)
|
||||||
|
return result;
|
||||||
|
result = tmpstr.Remove(endindex);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获得字符串中开始和结束字符串中间的值
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="t">字符串</param>
|
||||||
|
/// <param name="k">开始</param>
|
||||||
|
/// <param name="j">结束</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
private static string GetMidString2(string sourse, string startstr, string endstr) //截取指定文本,和易语言的取文本中间差不多
|
||||||
|
{
|
||||||
|
try //异常捕捉
|
||||||
|
{
|
||||||
|
var kn = sourse.IndexOf(startstr, StringComparison.Ordinal) + startstr.Length;
|
||||||
|
var jn = sourse.IndexOf(endstr, kn, StringComparison.Ordinal);
|
||||||
|
return sourse.Substring(kn, jn - kn);
|
||||||
|
}
|
||||||
|
catch //如果发现未知的错误,比如上面的代码出错了,就执行下面这句代码
|
||||||
|
{
|
||||||
|
return ""; //返回空
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// 布尔类型转换为整型
|
||||||
|
public static int ToInt(this object obj)
|
||||||
|
{
|
||||||
|
if (Convert.ToBoolean(obj) == true)
|
||||||
|
return 1;
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 整型转换为布尔类型
|
||||||
|
public static bool ToBool(this object obj)
|
||||||
|
{
|
||||||
|
if (Convert.ToInt32(obj) == 1)
|
||||||
|
return true;
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static object GetProperty(this object o, string member)
|
||||||
|
{
|
||||||
|
if (o == null) throw new ArgumentNullException("o");
|
||||||
|
if (member == null) throw new ArgumentNullException("member");
|
||||||
|
Type scope = o.GetType();
|
||||||
|
IDynamicMetaObjectProvider provider = o as IDynamicMetaObjectProvider;
|
||||||
|
if (provider != null)
|
||||||
|
{
|
||||||
|
ParameterExpression param = Expression.Parameter(typeof(object));
|
||||||
|
DynamicMetaObject mobj = provider.GetMetaObject(param);
|
||||||
|
GetMemberBinder binder = (GetMemberBinder)Microsoft.CSharp.RuntimeBinder.Binder.GetMember(0, member, scope, new CSharpArgumentInfo[] { CSharpArgumentInfo.Create(0, null) });
|
||||||
|
DynamicMetaObject ret = mobj.BindGetMember(binder);
|
||||||
|
BlockExpression final = Expression.Block(
|
||||||
|
Expression.Label(CallSiteBinder.UpdateLabel),
|
||||||
|
ret.Expression
|
||||||
|
);
|
||||||
|
LambdaExpression lambda = Expression.Lambda(final, param);
|
||||||
|
Delegate del = lambda.Compile();
|
||||||
|
return del.DynamicInvoke(o);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return o.GetType().GetProperty(member, BindingFlags.Public | BindingFlags.Instance).GetValue(o, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#region 检测文件状态及操作方式选择
|
||||||
|
[DllImport("kernel32.dll")]
|
||||||
|
private static extern IntPtr _lopen(string lpPathName, int iReadWrite);
|
||||||
|
[DllImport("kernel32.dll")]
|
||||||
|
private static extern bool CloseHandle(IntPtr hObject);
|
||||||
|
private const int OF_READWRITE = 2;
|
||||||
|
private const int OF_SHARE_DENY_NONE = 0x40;
|
||||||
|
private static readonly IntPtr HFILE_ERROR = new IntPtr(-1);
|
||||||
|
/// <summary>
|
||||||
|
/// 检测文件是否只读或被使用
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="FileNames">要检测的文件</param>
|
||||||
|
/// <returns>true可用,false在用或只读</returns>
|
||||||
|
public static bool CheckFilesCanUse(string fileName)
|
||||||
|
{
|
||||||
|
if (!File.Exists(fileName))
|
||||||
|
return true;//文件不存在
|
||||||
|
if ((File.GetAttributes(fileName) & FileAttributes.ReadOnly) == FileAttributes.ReadOnly)
|
||||||
|
return false; //文件只读
|
||||||
|
IntPtr vHandle = _lopen(fileName, OF_READWRITE | OF_SHARE_DENY_NONE);
|
||||||
|
if (vHandle == HFILE_ERROR)
|
||||||
|
{
|
||||||
|
CloseHandle(vHandle);
|
||||||
|
return false; //文件被占用
|
||||||
|
}
|
||||||
|
|
||||||
|
CloseHandle(vHandle); //文件没被占用
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取指定文件夹下所有的文件名称
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="folderName">指定文件夹名称,绝对路径</param>
|
||||||
|
/// <param name="fileFilter">文件类型过滤,根据文件后缀名,如:*,*.txt,*.xls</param>
|
||||||
|
/// <param name="isContainSubFolder">是否包含子文件夹</param>
|
||||||
|
/// <returns>ArrayList数组,为所有需要的文件路径名称</returns>
|
||||||
|
public static List<FileInfo> GetAllFilesByFolder(string folderName, string fileFilter, bool isContainSubFolder = false)
|
||||||
|
{
|
||||||
|
List<FileInfo> resList = new List<FileInfo>();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
DirectoryInfo currDir = new DirectoryInfo(folderName);//当前目录
|
||||||
|
FileInfo[] currFiles = currDir.GetFiles(fileFilter);//当前目录文件
|
||||||
|
foreach (FileInfo file in currFiles)
|
||||||
|
{
|
||||||
|
if (fileFilter.ToLower().IndexOf(file.Extension.ToLower()) >= 0)
|
||||||
|
{
|
||||||
|
resList.Add(file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (isContainSubFolder)
|
||||||
|
{
|
||||||
|
string[] subFolders = Directory.GetDirectories(folderName);
|
||||||
|
foreach (string subFolder in subFolders)
|
||||||
|
{
|
||||||
|
resList.AddRange(GetAllFilesByFolder(subFolder, fileFilter));//递归
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
throw ex;
|
||||||
|
}
|
||||||
|
return resList;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取指定文件夹下所有的文件名称,不过滤文件类型
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="folderName">指定文件夹名称,绝对路径</param>
|
||||||
|
/// <param name="isContainSubFolder">是否包含子文件夹</param>
|
||||||
|
/// <returns>ArrayList数组,为所有需要的文件路径名称</returns>
|
||||||
|
public static List<FileInfo> GetAllFilesByFolder(string folderName, bool isContainSubFolder)
|
||||||
|
{
|
||||||
|
return GetAllFilesByFolder(folderName, "*", isContainSubFolder);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class Compare<T, C> : IEqualityComparer<T>
|
||||||
|
{
|
||||||
|
private Func<T, C> _getField;
|
||||||
|
public Compare(Func<T, C> getfield)
|
||||||
|
{
|
||||||
|
_getField = getfield;
|
||||||
|
}
|
||||||
|
public bool Equals(T x, T y)
|
||||||
|
{
|
||||||
|
return EqualityComparer<C>.Default.Equals(_getField(x), _getField(y));
|
||||||
|
}
|
||||||
|
public int GetHashCode(T obj)
|
||||||
|
{
|
||||||
|
return EqualityComparer<C>.Default.GetHashCode(_getField(obj));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class ObjectExtensions
|
||||||
|
{
|
||||||
|
public static IEnumerable<T> DistinctBy<T, C>(this IEnumerable<T> source, Func<T, C> getfield)
|
||||||
|
{
|
||||||
|
return source.Distinct(new Compare<T, C>(getfield));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static IQueryable<T> DistinctBy<T, C>(this IQueryable<T> source, Func<T, C> getfield)
|
||||||
|
{
|
||||||
|
return source.Distinct(new Compare<T, C>(getfield));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
120
DH.Commons/Helper/SystemConfigHelper.cs
Normal file
120
DH.Commons/Helper/SystemConfigHelper.cs
Normal file
@@ -0,0 +1,120 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Configuration;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace DH.Commons.Helper
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 配置文件操作工具类(自动定位主程序配置)
|
||||||
|
/// </summary>
|
||||||
|
public static class SystemConfigHelper
|
||||||
|
{
|
||||||
|
private static Configuration _mainConfig;
|
||||||
|
private static readonly object _lock = new object();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取主程序配置对象
|
||||||
|
/// </summary>
|
||||||
|
private static Configuration MainConfiguration
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (_mainConfig == null)
|
||||||
|
{
|
||||||
|
lock (_lock)
|
||||||
|
{
|
||||||
|
if (_mainConfig == null)
|
||||||
|
{
|
||||||
|
// 获取主程序路径
|
||||||
|
string exePath = Assembly.GetEntryAssembly().Location;
|
||||||
|
var configFile = exePath + ".config";
|
||||||
|
|
||||||
|
// 加载主程序配置
|
||||||
|
var fileMap = new ExeConfigurationFileMap
|
||||||
|
{
|
||||||
|
ExeConfigFilename = configFile
|
||||||
|
};
|
||||||
|
_mainConfig = ConfigurationManager.OpenMappedExeConfiguration(
|
||||||
|
fileMap,
|
||||||
|
ConfigurationUserLevel.None
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return _mainConfig;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 检查配置项是否存在
|
||||||
|
/// </summary>
|
||||||
|
public static bool KeyExists(string key)
|
||||||
|
{
|
||||||
|
return MainConfiguration.AppSettings.Settings[key] != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 读取配置项(带类型自动转换)
|
||||||
|
/// </summary>
|
||||||
|
public static T GetValue<T>(string key, T defaultValue = default)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var setting = MainConfiguration.AppSettings.Settings[key];
|
||||||
|
if (setting == null) return defaultValue;
|
||||||
|
|
||||||
|
return (T)Convert.ChangeType(setting.Value, typeof(T));
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 写入配置项(自动保存)
|
||||||
|
/// </summary>
|
||||||
|
public static void SetValue(string key, object value)
|
||||||
|
{
|
||||||
|
var settings = MainConfiguration.AppSettings.Settings;
|
||||||
|
var stringValue = value?.ToString() ?? string.Empty;
|
||||||
|
|
||||||
|
if (settings[key] == null)
|
||||||
|
{
|
||||||
|
settings.Add(key, stringValue);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
settings[key].Value = stringValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
SaveChanges();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 删除指定配置项
|
||||||
|
/// </summary>
|
||||||
|
public static void RemoveKey(string key)
|
||||||
|
{
|
||||||
|
if (KeyExists(key))
|
||||||
|
{
|
||||||
|
MainConfiguration.AppSettings.Settings.Remove(key);
|
||||||
|
SaveChanges();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 保存配置修改
|
||||||
|
/// </summary>
|
||||||
|
private static void SaveChanges()
|
||||||
|
{
|
||||||
|
MainConfiguration.Save(ConfigurationSaveMode.Modified);
|
||||||
|
ConfigurationManager.RefreshSection("appSettings");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
123
DH.Commons/Helper/UIHelper.cs
Normal file
123
DH.Commons/Helper/UIHelper.cs
Normal file
@@ -0,0 +1,123 @@
|
|||||||
|
using System;
|
||||||
|
using System.Drawing;
|
||||||
|
using System.Windows.Forms;
|
||||||
|
|
||||||
|
namespace DH.Commons.Enums
|
||||||
|
{
|
||||||
|
public static class UIHelper
|
||||||
|
{
|
||||||
|
public static void SetCombo(ComboBox cbo, object dataSource, string display, string value)
|
||||||
|
{
|
||||||
|
cbo.DataSource = dataSource;
|
||||||
|
cbo.DisplayMember = display;
|
||||||
|
if (!string.IsNullOrWhiteSpace(value))
|
||||||
|
{
|
||||||
|
cbo.ValueMember = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void SetCombo(ToolStripComboBox cbo, object dataSource, string display, string value)
|
||||||
|
{
|
||||||
|
cbo.ComboBox.DataSource = dataSource;
|
||||||
|
cbo.ComboBox.DisplayMember = display;
|
||||||
|
if (!string.IsNullOrWhiteSpace(value))
|
||||||
|
{
|
||||||
|
cbo.ComboBox.ValueMember = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void SetCombo(DataGridViewComboBoxColumn cbo, object dataSource, string display, string value)
|
||||||
|
{
|
||||||
|
cbo.DataSource = dataSource;
|
||||||
|
cbo.DisplayMember = display;
|
||||||
|
if (!string.IsNullOrWhiteSpace(value))
|
||||||
|
{
|
||||||
|
cbo.ValueMember = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#region DataGridView设置列头为复选框
|
||||||
|
public class DataGridViewCheckboxHeaderEventArgs : EventArgs
|
||||||
|
{
|
||||||
|
private bool checkedState = false;
|
||||||
|
|
||||||
|
public bool CheckedState
|
||||||
|
{
|
||||||
|
get { return checkedState; }
|
||||||
|
set { checkedState = value; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public delegate void DataGridViewCheckboxHeaderEventHander(object sender, DataGridViewCheckboxHeaderEventArgs e);
|
||||||
|
public class DataGridViewCheckboxHeaderCell : DataGridViewColumnHeaderCell
|
||||||
|
{
|
||||||
|
Point checkBoxLocation;
|
||||||
|
Size checkBoxSize;
|
||||||
|
bool _checked = false;
|
||||||
|
Point _cellLocation = new Point();
|
||||||
|
System.Windows.Forms.VisualStyles.CheckBoxState _cbState = System.Windows.Forms.VisualStyles.CheckBoxState.UncheckedNormal;
|
||||||
|
|
||||||
|
public event DataGridViewCheckboxHeaderEventHander OnCheckBoxClicked;
|
||||||
|
|
||||||
|
//绘制列头checkbox
|
||||||
|
protected override void Paint(System.Drawing.Graphics graphics,
|
||||||
|
System.Drawing.Rectangle clipBounds,
|
||||||
|
System.Drawing.Rectangle cellBounds,
|
||||||
|
int rowIndex,
|
||||||
|
DataGridViewElementStates dataGridViewElementState,
|
||||||
|
object value,
|
||||||
|
object formattedValue,
|
||||||
|
string errorText,
|
||||||
|
DataGridViewCellStyle cellStyle,
|
||||||
|
DataGridViewAdvancedBorderStyle advancedBorderStyle,
|
||||||
|
DataGridViewPaintParts paintParts)
|
||||||
|
{
|
||||||
|
base.Paint(graphics, clipBounds, cellBounds, rowIndex,
|
||||||
|
dataGridViewElementState, value,
|
||||||
|
formattedValue, errorText, cellStyle,
|
||||||
|
advancedBorderStyle, paintParts);
|
||||||
|
|
||||||
|
Point p = new Point();
|
||||||
|
Size s = CheckBoxRenderer.GetGlyphSize(graphics, System.Windows.Forms.VisualStyles.CheckBoxState.UncheckedNormal);
|
||||||
|
p.X = cellBounds.Location.X + (cellBounds.Width / 2) - (s.Width / 2) - 1; //列头checkbox的X坐标
|
||||||
|
p.Y = cellBounds.Location.Y + (cellBounds.Height / 2) - (s.Height / 2); //列头checkbox的Y坐标
|
||||||
|
_cellLocation = cellBounds.Location;
|
||||||
|
checkBoxLocation = p;
|
||||||
|
checkBoxSize = s;
|
||||||
|
if (_checked)
|
||||||
|
_cbState = System.Windows.Forms.VisualStyles.CheckBoxState.CheckedNormal;
|
||||||
|
else
|
||||||
|
_cbState = System.Windows.Forms.VisualStyles.CheckBoxState.UncheckedNormal;
|
||||||
|
|
||||||
|
CheckBoxRenderer.DrawCheckBox(graphics, checkBoxLocation, _cbState);
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// 点击列头checkbox单击事件
|
||||||
|
///
|
||||||
|
protected override void OnMouseClick(DataGridViewCellMouseEventArgs e)
|
||||||
|
{
|
||||||
|
Point p = new Point(e.X + _cellLocation.X, e.Y + _cellLocation.Y);
|
||||||
|
if (p.X >= checkBoxLocation.X && p.X <= checkBoxLocation.X + checkBoxSize.Width
|
||||||
|
&& p.Y >= checkBoxLocation.Y && p.Y <= checkBoxLocation.Y + checkBoxSize.Height)
|
||||||
|
{
|
||||||
|
_checked = !_checked;
|
||||||
|
|
||||||
|
//获取列头checkbox的选择状态
|
||||||
|
DataGridViewCheckboxHeaderEventArgs ex = new DataGridViewCheckboxHeaderEventArgs();
|
||||||
|
ex.CheckedState = _checked;
|
||||||
|
|
||||||
|
object sender = new object();//此处不代表选择的列头checkbox,只是作为参数传递。因为列头checkbox是绘制出来的,无法获得它的实例
|
||||||
|
|
||||||
|
if (OnCheckBoxClicked != null)
|
||||||
|
{
|
||||||
|
OnCheckBoxClicked(sender, ex);//触发单击事件
|
||||||
|
DataGridView.InvalidateCell(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
base.OnMouseClick(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
39
DH.Commons/Interface/IShapeElement.cs
Normal file
39
DH.Commons/Interface/IShapeElement.cs
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
using System;
|
||||||
|
using System.ComponentModel;
|
||||||
|
using System.Drawing;
|
||||||
|
using static DH.Commons.Enums.EnumHelper;
|
||||||
|
|
||||||
|
|
||||||
|
namespace DH.Commons.Enums
|
||||||
|
{
|
||||||
|
public interface IShapeElement : INotifyPropertyChanged, ICloneable
|
||||||
|
{
|
||||||
|
string ID { get; set; }
|
||||||
|
|
||||||
|
int Index { get; set; }
|
||||||
|
int GroupIndex { get; set; }
|
||||||
|
|
||||||
|
string Name { get; set; }
|
||||||
|
|
||||||
|
void OnMouseDown(PointF point);
|
||||||
|
void OnMouseUp(PointF point);
|
||||||
|
void OnMouseMove(PointF point);
|
||||||
|
void OnMouseDoubleClick(PointF point);
|
||||||
|
bool IsIntersect(RectangleF rect);
|
||||||
|
|
||||||
|
bool IsEnabled { get; set; }
|
||||||
|
void Draw(Graphics g);
|
||||||
|
|
||||||
|
void Translate(float x, float y);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// WPF中标识该对象是否已经加入渲染,需要显示
|
||||||
|
/// </summary>
|
||||||
|
bool IsShowing { get; set; }
|
||||||
|
|
||||||
|
void Initial();
|
||||||
|
bool IsCreatedDone();
|
||||||
|
|
||||||
|
ElementState State { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
109
DH.Commons/Interface/Spec.cs
Normal file
109
DH.Commons/Interface/Spec.cs
Normal file
@@ -0,0 +1,109 @@
|
|||||||
|
|
||||||
|
using System;
|
||||||
|
using System.ComponentModel;
|
||||||
|
using System.Drawing.Design;
|
||||||
|
|
||||||
|
namespace DH.Commons.Enums
|
||||||
|
{
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 标准配置
|
||||||
|
/// </summary>
|
||||||
|
public class Spec
|
||||||
|
{
|
||||||
|
[Category("通用配置")]
|
||||||
|
[Description("标准代码")]
|
||||||
|
public virtual string Code { get; set; }
|
||||||
|
|
||||||
|
[Category("通用配置")]
|
||||||
|
[Description("启用状态,true:启用;false:禁用")]
|
||||||
|
[DisplayName("启用状态")]
|
||||||
|
public bool IsEnabled { get; set; }
|
||||||
|
|
||||||
|
[Category("标准配置")]
|
||||||
|
[Description("标准值")]
|
||||||
|
[DisplayName("标准值")]
|
||||||
|
public double StandardValue { get; set; }
|
||||||
|
|
||||||
|
[Category("标准配置")]
|
||||||
|
[Description("正公差")]
|
||||||
|
[DisplayName("正公差")]
|
||||||
|
public double Tolrenance_Positive { get; set; }
|
||||||
|
|
||||||
|
[Category("标准配置")]
|
||||||
|
[Description("负公差")]
|
||||||
|
[DisplayName("负公差")]
|
||||||
|
public double Tolrenance_Negative { get; set; }
|
||||||
|
|
||||||
|
protected double? actualValue = null;
|
||||||
|
[Browsable(false)]
|
||||||
|
|
||||||
|
public virtual double? ActualValue
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return actualValue;
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
//if (actualValue != value && value != null)
|
||||||
|
if (value != null)
|
||||||
|
{
|
||||||
|
if (value.Value >= (StandardValue - Tolrenance_Negative) && value.Value <= (StandardValue + Tolrenance_Positive))
|
||||||
|
{
|
||||||
|
MeasureResult = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
MeasureResult = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
actualValue = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Browsable(false)]
|
||||||
|
|
||||||
|
public bool? MeasureResult { get; set; } = null;
|
||||||
|
|
||||||
|
|
||||||
|
public Spec Copy()
|
||||||
|
{
|
||||||
|
Spec spec = new Spec();
|
||||||
|
|
||||||
|
spec.Code = this.Code;
|
||||||
|
spec.IsEnabled = this.IsEnabled;
|
||||||
|
spec.StandardValue = this.StandardValue;
|
||||||
|
spec.Tolrenance_Positive = this.Tolrenance_Positive;
|
||||||
|
spec.Tolrenance_Negative = this.Tolrenance_Negative;
|
||||||
|
|
||||||
|
return spec;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public class IndexedSpec : Spec
|
||||||
|
{
|
||||||
|
[Category("数据源配置")]
|
||||||
|
[Description("数据源输出索引")]
|
||||||
|
[DisplayName("数据源输出索引")]
|
||||||
|
public int OutputIndex { get; set; }
|
||||||
|
|
||||||
|
public new IndexedSpec Copy()
|
||||||
|
{
|
||||||
|
IndexedSpec spec = new IndexedSpec();
|
||||||
|
|
||||||
|
spec.Code = this.Code;
|
||||||
|
spec.IsEnabled = this.IsEnabled;
|
||||||
|
spec.StandardValue = this.StandardValue;
|
||||||
|
spec.Tolrenance_Positive = this.Tolrenance_Positive;
|
||||||
|
spec.Tolrenance_Negative = this.Tolrenance_Negative;
|
||||||
|
|
||||||
|
spec.OutputIndex = this.OutputIndex;
|
||||||
|
|
||||||
|
return spec;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
26
DH.Commons/Models/ProductSummary.cs
Normal file
26
DH.Commons/Models/ProductSummary.cs
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace DH.Commons.Models
|
||||||
|
{
|
||||||
|
public class CameraSummary
|
||||||
|
{
|
||||||
|
public string CameraName { get; set; } // 相机名称
|
||||||
|
public int TiggerCount { get; set; } //触发数
|
||||||
|
public int OKCount { get; set; } // OK 数
|
||||||
|
public int NGCount { get; set; } // NG 数
|
||||||
|
public int TotalCount => OKCount + NGCount; // 总检测数量
|
||||||
|
public string YieldStr => $"{Yield:f2} %"; // 良率(字符串形式)
|
||||||
|
public double Yield => OKCount + NGCount > 0 ? (double)OKCount / (OKCount + NGCount) * 100 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public class ProductSummary
|
||||||
|
{
|
||||||
|
public int ProductAmount { get; set; }
|
||||||
|
public string ResultDesc { get; set; }
|
||||||
|
public string PercentStr { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
34
DH.Commons/Models/SystemModel.cs
Normal file
34
DH.Commons/Models/SystemModel.cs
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using DH.Commons.Base;
|
||||||
|
using DH.Commons.Enums;
|
||||||
|
|
||||||
|
namespace DH.Commons.Models
|
||||||
|
{
|
||||||
|
public static class SystemModel
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 当前方案
|
||||||
|
/// </summary>
|
||||||
|
public static string CurrentScheme=string.Empty;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 当前状态
|
||||||
|
/// </summary>
|
||||||
|
public static EnumStatus CurrentStatus =EnumStatus.未运行;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 配置集合
|
||||||
|
/// </summary>
|
||||||
|
public static class ConfigModel
|
||||||
|
{
|
||||||
|
public static List<CameraBase> CameraBaseList = new List<CameraBase>();
|
||||||
|
public static List<PLCBase> PLCBaseList = new List<PLCBase>();
|
||||||
|
public static List<DetectionConfig> DetectionList = new List<DetectionConfig>();
|
||||||
|
public static List<GlobalConfig> GlobalList = new List<GlobalConfig>();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -13,7 +13,6 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Compile Include="CameraBase.cs" />
|
|
||||||
<Compile Include="Do3ThinkCamera.cs" />
|
<Compile Include="Do3ThinkCamera.cs" />
|
||||||
<Compile Include="HikVisionCamera.cs" />
|
<Compile Include="HikVisionCamera.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|||||||
@@ -1,16 +1,21 @@
|
|||||||
using System.Diagnostics;
|
using System.Collections.Concurrent;
|
||||||
|
using System.Diagnostics;
|
||||||
using System.Reflection.Metadata;
|
using System.Reflection.Metadata;
|
||||||
using System.Xml.Linq;
|
using System.Xml.Linq;
|
||||||
|
using DH.Commons.Base;
|
||||||
|
using DH.Commons.Enums;
|
||||||
|
using DH.Commons.Helper;
|
||||||
using DVPCameraType;
|
using DVPCameraType;
|
||||||
using OpenCvSharp;
|
using OpenCvSharp;
|
||||||
|
using OpenCvSharp.Extensions;
|
||||||
using static System.Net.Mime.MediaTypeNames;
|
using static System.Net.Mime.MediaTypeNames;
|
||||||
|
using LogLevel = DH.Commons.Enums.EnumHelper.LogLevel;
|
||||||
|
|
||||||
|
|
||||||
namespace DH.Devices.Camera
|
namespace DH.Devices.Camera
|
||||||
{
|
{
|
||||||
|
|
||||||
public class Do3ThinkCamera : CameraBase
|
public class Do3ThinkCamera : CameraBase, ILogger
|
||||||
{
|
{
|
||||||
|
|
||||||
private dvpCameraInfo stDevInfo = new dvpCameraInfo();
|
private dvpCameraInfo stDevInfo = new dvpCameraInfo();
|
||||||
@@ -20,10 +25,19 @@ namespace DH.Devices.Camera
|
|||||||
|
|
||||||
public int m_n_dev_count = 0;
|
public int m_n_dev_count = 0;
|
||||||
private DVPCamera.dvpStreamCallback ImageCallback;
|
private DVPCamera.dvpStreamCallback ImageCallback;
|
||||||
|
public dvpStreamFormat dvpStreamFormat = dvpStreamFormat.S_RGB24;
|
||||||
public int m_CamCount = 0;
|
public int m_CamCount = 0;
|
||||||
public Double m_dfDisplayCount = 0;
|
public Double m_dfDisplayCount = 0;
|
||||||
|
|
||||||
|
public LoggerHelper LoggerHelper { get; set; } = new LoggerHelper();
|
||||||
|
public event Action<LogMsg> OnLog;
|
||||||
|
public ConcurrentDictionary<string, MatSet> _imageSetList = new ConcurrentDictionary<string, MatSet>();
|
||||||
|
|
||||||
|
|
||||||
public Do3ThinkCamera()
|
public Do3ThinkCamera()
|
||||||
{
|
{
|
||||||
|
LoggerHelper.LogPath = "D://";
|
||||||
|
LoggerHelper.LogPrefix = CameraName;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -66,7 +80,7 @@ namespace DH.Devices.Camera
|
|||||||
dvpCameraInfo camerainfo = new dvpCameraInfo();
|
dvpCameraInfo camerainfo = new dvpCameraInfo();
|
||||||
nRet = DVPCamera.dvpGetCameraInfo(m_handle, ref camerainfo);
|
nRet = DVPCamera.dvpGetCameraInfo(m_handle, ref camerainfo);
|
||||||
|
|
||||||
SerialNumber= camerainfo.SerialNumber;
|
SerialNumber = camerainfo.SerialNumber;
|
||||||
// ch:注册异常回调函数 | en:Register Exception Callback
|
// ch:注册异常回调函数 | en:Register Exception Callback
|
||||||
//nRet = DVPCamera.dvpRegisterEventCallback(m_handle, pCallBackFunc, dvpEvent.EVENT_DISCONNECTED, IntPtr.Zero);
|
//nRet = DVPCamera.dvpRegisterEventCallback(m_handle, pCallBackFunc, dvpEvent.EVENT_DISCONNECTED, IntPtr.Zero);
|
||||||
//if (nRet != dvpStatus.DVP_STATUS_OK)
|
//if (nRet != dvpStatus.DVP_STATUS_OK)
|
||||||
@@ -76,17 +90,17 @@ namespace DH.Devices.Camera
|
|||||||
//GC.KeepAlive(pCallBackFunc);
|
//GC.KeepAlive(pCallBackFunc);
|
||||||
|
|
||||||
//// ch:设置采集连续模式 | en:Set Continues Aquisition Mode
|
//// ch:设置采集连续模式 | en:Set Continues Aquisition Mode
|
||||||
//if (IIConfig.IsContinueMode)
|
if (IsContinueMode)
|
||||||
//{
|
{
|
||||||
// // ch:设置触发模式为off || en:set trigger mode as off
|
// ch:设置触发模式为off || en:set trigger mode as off
|
||||||
// nRet = DVPCamera.dvpSetTriggerState(m_handle, false);
|
nRet = DVPCamera.dvpSetTriggerState(m_handle, false);
|
||||||
// if (dvpStatus.DVP_STATUS_OK != nRet)
|
if (dvpStatus.DVP_STATUS_OK != nRet)
|
||||||
// {
|
{
|
||||||
// throw new Exception("Set TriggerMode failed!");
|
throw new Exception("Set TriggerMode failed!");
|
||||||
// }
|
}
|
||||||
//}
|
}
|
||||||
//else
|
else
|
||||||
//{
|
{
|
||||||
// ch:设置触发模式为on || en:set trigger mode as on
|
// ch:设置触发模式为on || en:set trigger mode as on
|
||||||
nRet = DVPCamera.dvpSetTriggerState(m_handle, true);
|
nRet = DVPCamera.dvpSetTriggerState(m_handle, true);
|
||||||
if (dvpStatus.DVP_STATUS_OK != nRet)
|
if (dvpStatus.DVP_STATUS_OK != nRet)
|
||||||
@@ -95,8 +109,8 @@ namespace DH.Devices.Camera
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 硬触发
|
// 硬触发
|
||||||
//if (IIConfig.IsHardwareTrigger)
|
if (IsHardwareTrigger)
|
||||||
//{
|
{
|
||||||
// ch:触发源选择:1 - Line1; | en:Trigger source select:1 - Line1;
|
// ch:触发源选择:1 - Line1; | en:Trigger source select:1 - Line1;
|
||||||
nRet = DVPCamera.dvpSetTriggerSource(m_handle, dvpTriggerSource.TRIGGER_SOURCE_LINE1);
|
nRet = DVPCamera.dvpSetTriggerSource(m_handle, dvpTriggerSource.TRIGGER_SOURCE_LINE1);
|
||||||
if (dvpStatus.DVP_STATUS_OK != nRet)
|
if (dvpStatus.DVP_STATUS_OK != nRet)
|
||||||
@@ -111,15 +125,15 @@ namespace DH.Devices.Camera
|
|||||||
{
|
{
|
||||||
throw new Exception("Register image callback failed!");
|
throw new Exception("Register image callback failed!");
|
||||||
}
|
}
|
||||||
//}
|
}
|
||||||
//else // 软触发
|
else // 软触发
|
||||||
//{
|
{
|
||||||
// nRet = DVPCamera.dvpSetTriggerSource(m_handle, dvpTriggerSource.TRIGGER_SOURCE_SOFTWARE);
|
nRet = DVPCamera.dvpSetTriggerSource(m_handle, dvpTriggerSource.TRIGGER_SOURCE_SOFTWARE);
|
||||||
// if (dvpStatus.DVP_STATUS_OK != nRet)
|
if (dvpStatus.DVP_STATUS_OK != nRet)
|
||||||
// {
|
{
|
||||||
// throw new Exception("Set Software Trigger failed!");
|
throw new Exception("Set Software Trigger failed!");
|
||||||
// }
|
}
|
||||||
//}
|
}
|
||||||
|
|
||||||
// ch:开启抓图 || en: start grab image
|
// ch:开启抓图 || en: start grab image
|
||||||
nRet = DVPCamera.dvpStart(m_handle);
|
nRet = DVPCamera.dvpStart(m_handle);
|
||||||
@@ -128,40 +142,44 @@ namespace DH.Devices.Camera
|
|||||||
throw new Exception($"Start grabbing failed:{nRet:x8}");
|
throw new Exception($"Start grabbing failed:{nRet:x8}");
|
||||||
}
|
}
|
||||||
//// 曝光
|
//// 曝光
|
||||||
//if (IIConfig.DefaultExposure != 0)
|
if (Exposure != 0)
|
||||||
//{
|
{
|
||||||
// SetExposure(IIConfig.DefaultExposure);
|
SetExposure(Exposure);
|
||||||
//}
|
}
|
||||||
//// 增益
|
//// 增益
|
||||||
//if (IIConfig.Gain >= 0)
|
if (Gain >= 0)
|
||||||
//{
|
{
|
||||||
// SetGain(IIConfig.Gain);
|
SetGain(Gain);
|
||||||
//}
|
}
|
||||||
//SetPictureRoi(IIConfig.VelocityPara.A_Pic_X, IIConfig.VelocityPara.A_Pic_Y, IIConfig.VelocityPara.Width, IIConfig.VelocityPara.Hight);
|
//全画幅
|
||||||
|
if(!IsAllPicEnabled)
|
||||||
|
SetPictureRoi((int)ROIX, (int)ROIY, (int)ROIW, (int)ROIH);
|
||||||
|
|
||||||
//// 设置 触发延迟
|
//// 设置 触发延迟
|
||||||
//if (IIConfig.TriggerDelay > 0)
|
if (TriggerDelay > 0)
|
||||||
//{
|
{
|
||||||
// nRet = DVPCamera.dvpSetTriggerDelay(m_handle, IIConfig.TriggerDelay);
|
nRet = DVPCamera.dvpSetTriggerDelay(m_handle, TriggerDelay);
|
||||||
// if (nRet != dvpStatus.DVP_STATUS_OK)
|
if (nRet != dvpStatus.DVP_STATUS_OK)
|
||||||
// {
|
{
|
||||||
// throw new Exception("Set TriggerDelay failed!");
|
throw new Exception("Set TriggerDelay failed!");
|
||||||
// }
|
}
|
||||||
//}
|
}
|
||||||
|
|
||||||
//// 信号消抖
|
//// 信号消抖
|
||||||
//if (IIConfig.LineDebouncerTime > 0)
|
if (LineDebouncerTime > 0)
|
||||||
//{
|
{
|
||||||
// nRet = DVPCamera.dvpSetTriggerJitterFilter(m_handle, IIConfig.LineDebouncerTime);
|
nRet = DVPCamera.dvpSetTriggerJitterFilter(m_handle, LineDebouncerTime);
|
||||||
// if (nRet != dvpStatus.DVP_STATUS_OK)
|
if (nRet != dvpStatus.DVP_STATUS_OK)
|
||||||
// {
|
{
|
||||||
// throw new Exception($"LineDebouncerTime set failed:{nRet}");
|
throw new Exception($"LineDebouncerTime set failed:{nRet}");
|
||||||
// }
|
}
|
||||||
//}
|
}
|
||||||
|
|
||||||
//IIConfig.PropertyChanged -= IIConfig_PropertyChanged;
|
//IIConfig.PropertyChanged -= IIConfig_PropertyChanged;
|
||||||
//IIConfig.PropertyChanged += IIConfig_PropertyChanged;
|
//IIConfig.PropertyChanged += IIConfig_PropertyChanged;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
@@ -309,7 +327,14 @@ namespace DH.Devices.Camera
|
|||||||
public int ImageCallbackFunc(uint handle, dvpStreamEvent _event, IntPtr pContext, ref dvpFrame refFrame, IntPtr pBuffer)
|
public int ImageCallbackFunc(uint handle, dvpStreamEvent _event, IntPtr pContext, ref dvpFrame refFrame, IntPtr pBuffer)
|
||||||
{
|
{
|
||||||
Mat cvImage = new Mat();
|
Mat cvImage = new Mat();
|
||||||
|
if (this.CameraName.Equals("Cam1"))
|
||||||
|
{
|
||||||
|
Console.WriteLine( );
|
||||||
|
}
|
||||||
|
if (this.CameraName.Equals("Cam2"))
|
||||||
|
{
|
||||||
|
Console.WriteLine();
|
||||||
|
}
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|
||||||
@@ -336,12 +361,21 @@ namespace DH.Devices.Camera
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
throw new NotSupportedException($"Unsupported format: {refFrame.format}");
|
cvImage = Mat.FromPixelData(nHeight, nWidth, MatType.CV_8UC1, pBuffer);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
Mat smat = cvImage.Clone();
|
Mat smat = cvImage.Clone();
|
||||||
|
var imageSet = new MatSet
|
||||||
|
{
|
||||||
|
|
||||||
|
_mat = smat,
|
||||||
|
|
||||||
|
};
|
||||||
|
InitialImageSet(imageSet);
|
||||||
OnHImageOutput?.Invoke(DateTime.Now, this, smat);
|
OnHImageOutput?.Invoke(DateTime.Now, this, smat);
|
||||||
|
|
||||||
|
//存图
|
||||||
|
DisplayAndSaveOriginImage(imageSet.Id,SnapshotCount);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -357,14 +391,93 @@ namespace DH.Devices.Camera
|
|||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
public void InitialImageSet(MatSet set)
|
||||||
|
{
|
||||||
|
//if (saveOption != null)
|
||||||
|
//{
|
||||||
|
// set.ImageSaveOption = saveOption.Copy();
|
||||||
|
//}
|
||||||
|
|
||||||
|
//set.IsOriginSaved = !set.ImageSaveOption.IsSaveOriginImage;
|
||||||
|
//set.IsFitSaved = !set.ImageSaveOption.IsSaveFitImage;
|
||||||
|
//set.IsAddtionalSaved = string.IsNullOrWhiteSpace(set.ImageSaveOption.AddtionalSaveType);
|
||||||
|
set.CameraId = this.CameraName;
|
||||||
|
|
||||||
|
set.ImageTime = DateTime.Now;
|
||||||
|
_imageSetList[set.Id] = set;
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual async void DisplayAndSaveOriginImage(string imgSetId, int _counter)
|
||||||
|
{
|
||||||
|
MatSet set = _imageSetList.Values.FirstOrDefault(u => u.Id == imgSetId);
|
||||||
|
|
||||||
|
if (set != null && set._mat != null)
|
||||||
|
{
|
||||||
|
await Task.Run(() =>
|
||||||
|
{
|
||||||
|
Bitmap showImage = set._mat.ToBitmap();
|
||||||
|
// showImage.Save("D:/test333.bmp");
|
||||||
|
// Marshal.Copy(pbyteImageBuffer, 0, (IntPtr)lAddrImage, (int)dwBufferSize);
|
||||||
|
// Bitmap saveImage = showImage?.CopyBitmap();
|
||||||
|
// saveImage.Save("d://TEST444.BMP");
|
||||||
|
// OnShowImageUpdated?.Invoke(this, showImage, imgSetId);
|
||||||
|
if (IsSavePicEnabled)
|
||||||
|
{
|
||||||
|
string fullname = Path.Combine(ImageSaveDirectory, $"{CameraName}_{_counter:D7}_{set.Id}.{set._imageFormat.ToString().ToLower()}");
|
||||||
|
ImageSaveAsync(fullname, showImage);
|
||||||
|
}
|
||||||
|
|
||||||
|
//释放 himage
|
||||||
|
ClearImageSet(set);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
static object _imageSetLock = new object();
|
||||||
|
public void ClearImageSet(MatSet set)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
bool flag = false;
|
||||||
|
lock (_imageSetLock)
|
||||||
|
{
|
||||||
|
flag = _imageSetList.TryRemove(set.Id, out set);
|
||||||
|
if (flag)
|
||||||
|
{
|
||||||
|
set.Dispose();
|
||||||
|
}
|
||||||
|
//LogAsync(DateTime.Now, $"{Name}移除图片信息{(flag ? "成功" : "失败")},当前缓存数量:{_imageSetList.Count}", "");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
LogAsync(DateTime.Now, LogLevel.Exception, $"清理图片缓存异常,当前缓存数量{_imageSetList.Count},{ex.GetExceptionMessage()}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public ImageSaveHelper ImageSaveHelper { get; set; } = new ImageSaveHelper();
|
||||||
|
public virtual void ImageSaveAsync(string fullName, Bitmap map)
|
||||||
|
{
|
||||||
|
if (!IsSavePicEnabled)
|
||||||
|
{
|
||||||
|
map?.Dispose();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ImageSaveSet imageSaveSet = new ImageSaveSet()
|
||||||
|
{
|
||||||
|
FullName = fullName,
|
||||||
|
SaveImage = map,
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
ImageSaveHelper.ImageSaveAsync(imageSaveSet);
|
||||||
|
}
|
||||||
public override bool CameraDisConnect()
|
public override bool CameraDisConnect()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
dvpStreamState StreamState = new dvpStreamState();
|
dvpStreamState StreamState = new dvpStreamState();
|
||||||
nRet = DVPCamera.dvpGetStreamState(m_handle, ref StreamState);
|
nRet = DVPCamera.dvpGetStreamState(m_handle, ref StreamState);
|
||||||
Debug.Assert(nRet == dvpStatus.DVP_STATUS_OK);
|
//Debug.Assert(nRet == dvpStatus.DVP_STATUS_OK);
|
||||||
if (StreamState == dvpStreamState.STATE_STARTED)
|
if (StreamState == dvpStreamState.STATE_STARTED)
|
||||||
{
|
{
|
||||||
// stop camera
|
// stop camera
|
||||||
@@ -399,6 +512,22 @@ namespace DH.Devices.Camera
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void LogAsync(LogMsg msg)
|
||||||
|
{
|
||||||
|
msg.MsgSource = CameraName;
|
||||||
|
msg.ThreadId = Thread.CurrentThread.ManagedThreadId;
|
||||||
|
|
||||||
|
//OnLog?.BeginInvoke(msg, null, null);
|
||||||
|
OnLog?.Invoke(msg);
|
||||||
|
|
||||||
|
//if (InitialConfig.IsEnableLog)
|
||||||
|
{
|
||||||
|
LoggerHelper.LogAsync(msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public void LogAsync(DateTime dt, LogLevel logLevel, string msg)
|
||||||
|
{
|
||||||
|
LogAsync(new LogMsg(dt, logLevel, msg));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ using System.Runtime.InteropServices;
|
|||||||
using System.Xml.Linq;
|
using System.Xml.Linq;
|
||||||
using DH.Commons.Enums;
|
using DH.Commons.Enums;
|
||||||
using static MvCamCtrl.NET.MyCamera;
|
using static MvCamCtrl.NET.MyCamera;
|
||||||
|
using DH.Commons.Base;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -4,7 +4,7 @@ using System.Linq;
|
|||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace XKRS.Device.SolidMotionCard
|
namespace DH.Devices.Motion
|
||||||
{
|
{
|
||||||
|
|
||||||
public enum FuncRet
|
public enum FuncRet
|
||||||
|
|||||||
@@ -73,7 +73,7 @@ namespace DH.Devices.Motion
|
|||||||
[Category("机台配置")]
|
[Category("机台配置")]
|
||||||
[DisplayName("机台类型")]
|
[DisplayName("机台类型")]
|
||||||
[Description("机台类型")]
|
[Description("机台类型")]
|
||||||
public MachineDiskType MachineDiskType { get; set; } = MachineDiskType.DoubleDisk;
|
public MachineDiskType MachineDiskType { get; set; } = MachineDiskType.SingleDisk;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -111,12 +111,12 @@ namespace DH.Devices.Motion
|
|||||||
[DisplayName("输出IO总数")]
|
[DisplayName("输出IO总数")]
|
||||||
public int OutputNums { get; set; } = 16;
|
public int OutputNums { get; set; } = 16;
|
||||||
|
|
||||||
//[Category("IO配置")]
|
[Category("IO配置")]
|
||||||
//[DisplayName("IO定义集合")]
|
[DisplayName("IO定义集合")]
|
||||||
//[Description("IO定义集合")]
|
[Description("IO定义集合")]
|
||||||
//[TypeConverter(typeof(CollectionCountConvert))]
|
//[TypeConverter(typeof(CollectionCountConvert))]
|
||||||
//[Editor(typeof(ComplexCollectionEditor<IODefinition>), typeof(UITypeEditor))]
|
// [Editor(typeof(ComplexCollectionEditor<IODefinition>), typeof(UITypeEditor))]
|
||||||
//public List<IODefinition> IODefinitionCollection { get; set; } = new List<IODefinition>();
|
public List<IODefinition> IODefinitionCollection { get; set; } = new List<IODefinition>();
|
||||||
|
|
||||||
[Category("IO配置")]
|
[Category("IO配置")]
|
||||||
[DisplayName("是否信号模式")]
|
[DisplayName("是否信号模式")]
|
||||||
@@ -194,35 +194,35 @@ namespace DH.Devices.Motion
|
|||||||
public List<BlowSetting> BlowSettings { get; set; } = new List<BlowSetting>();
|
public List<BlowSetting> BlowSettings { get; set; } = new List<BlowSetting>();
|
||||||
|
|
||||||
|
|
||||||
//[Category("筛选配置")]
|
[Category("筛选配置")]
|
||||||
//[DisplayName("转盘运转方向")]
|
[DisplayName("转盘运转方向")]
|
||||||
//[Description("转盘运转方向,顺时针或逆时针")]
|
[Description("转盘运转方向,顺时针或逆时针")]
|
||||||
//[TypeConverter(typeof(EnumDescriptionConverter<RotationDirectionEnum>))]
|
//[TypeConverter(typeof(EnumDescriptionConverter<RotationDirectionEnum>))]
|
||||||
//public RotationDirectionEnum MotionDir { get; set; } = RotationDirectionEnum.Clockwise;
|
public RotationDirectionEnum MotionDir { get; set; } = RotationDirectionEnum.Clockwise;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
[Category("筛选配置")]
|
[Category("筛选配置")]
|
||||||
[DisplayName("物料尺寸最大值")]
|
[DisplayName("物料尺寸最大值")]
|
||||||
[Description("物料尺寸最大值,单位:脉冲")]
|
[Description("物料尺寸最大值,单位:脉冲")]
|
||||||
public uint PieceMaxSize { get; set; } = 2000;
|
public uint PieceMaxSize { get; set; } = 20000;
|
||||||
|
|
||||||
|
|
||||||
[Category("筛选配置")]
|
[Category("筛选配置")]
|
||||||
[DisplayName("物料尺寸最小值")]
|
[DisplayName("物料尺寸最小值")]
|
||||||
[Description("物料尺寸最小值,单位:脉冲")]
|
[Description("物料尺寸最小值,单位:脉冲")]
|
||||||
public uint PieceMinSize { get; set; } = 1500;
|
public uint PieceMinSize { get; set; } = 10;
|
||||||
|
|
||||||
|
|
||||||
[Category("筛选配置")]
|
[Category("筛选配置")]
|
||||||
[DisplayName("物料最小间隔")]
|
[DisplayName("物料最小间隔")]
|
||||||
[Description("物料最小间隔,单位:脉冲")]
|
[Description("物料最小间隔,单位:脉冲")]
|
||||||
public uint MinDistance { get; set; } = 2000;
|
public uint MinDistance { get; set; } = 10;
|
||||||
|
|
||||||
[Category("筛选配置")]
|
[Category("筛选配置")]
|
||||||
[DisplayName("两个物料之间触发最小间隔时间")]
|
[DisplayName("两个物料之间触发最小间隔时间")]
|
||||||
[Description("两个物料之间触发最小间隔时间,单位:ms")]
|
[Description("两个物料之间触发最小间隔时间,单位:ms")]
|
||||||
public uint MinTimeInterval { get; set; } = 10;
|
public uint MinTimeInterval { get; set; } = 1;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -550,7 +550,7 @@ namespace DH.Devices.Motion
|
|||||||
[Category("回原点参数")]
|
[Category("回原点参数")]
|
||||||
[DisplayName("回原点方式")]
|
[DisplayName("回原点方式")]
|
||||||
[Description("HomeMode:回原点方式")]
|
[Description("HomeMode:回原点方式")]
|
||||||
public GoHomeMode HomeMode { get; set; } = GoHomeMode.Negative_Ne_Center_H_Positive_N_Stop_HNeO_Offset_Po;
|
public GoHomeMode HomeMode { get; set; } = GoHomeMode.Negative_Ne_Center_H_Positive_N_Index_HPoO_Offset_Po;
|
||||||
|
|
||||||
|
|
||||||
[Category("回原点参数")]
|
[Category("回原点参数")]
|
||||||
|
|||||||
@@ -1,10 +1,12 @@
|
|||||||
using DH.Commons.Enums;
|
using DH.Commons.Enums;
|
||||||
using DH.Devices.Motion;
|
using DH.Devices.Motion;
|
||||||
using MCDLL_NET;
|
using MCDLL_NET;
|
||||||
|
using OpenCvSharp;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
|
using static System.Collections.Specialized.BitVector32;
|
||||||
|
|
||||||
|
|
||||||
namespace XKRS.Device.SolidMotionCard
|
namespace DH.Devices.Motion
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
@@ -150,20 +152,30 @@ namespace XKRS.Device.SolidMotionCard
|
|||||||
.ToDictionary(a => a.AxisIndex, a => new ManualResetEvent(true));
|
.ToDictionary(a => a.AxisIndex, a => new ManualResetEvent(true));
|
||||||
|
|
||||||
// 初始化时关闭所有轴,停止筛选 begin =======
|
// 初始化时关闭所有轴,停止筛选 begin =======
|
||||||
AllMoveStop();
|
//AllMoveStop();
|
||||||
AllAxisOff();
|
|
||||||
|
// CMCDLL_NET.MCF_Axis_Stop_Net(0, AxisStopMode.AxisStopIMD, 0);
|
||||||
|
|
||||||
|
//CMCDLL_NET.MCF_Set_Axis_Stop_Profile_Net(0, 50000, 0, 0, 0);
|
||||||
|
// CMCDLL_NET.MCF_Axis_Stop_Net(0, AxisStopMode.AxisStopDEC, 0);
|
||||||
|
AxisStop();
|
||||||
|
//AllAxisOff();
|
||||||
|
var ret = CMCDLL_NET.MCF_Set_Servo_Enable_Net(0, (ushort)ServoLogic.Servo_Open, 0);
|
||||||
|
|
||||||
StopSorting();
|
StopSorting();
|
||||||
|
|
||||||
// 初始化时关闭所有轴,停止筛选 end =======
|
// 初始化时关闭所有轴,停止筛选 end =======
|
||||||
|
|
||||||
AllAxisOn();
|
//AllAxisOn();
|
||||||
Start();
|
Start();
|
||||||
MonitorPosition();
|
MonitorPosition();
|
||||||
MonitorAxisStatus();
|
MonitorAxisStatus();
|
||||||
MonitorPieces();
|
|
||||||
|
|
||||||
CustomStart();
|
CustomStart();
|
||||||
|
|
||||||
|
|
||||||
|
MonitorPieces();
|
||||||
isconnected = true;
|
isconnected = true;
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -276,53 +288,56 @@ namespace XKRS.Device.SolidMotionCard
|
|||||||
for (ushort station = 0; station < BoardCount; station++)
|
for (ushort station = 0; station < BoardCount; station++)
|
||||||
{
|
{
|
||||||
// 关闭调试测试后的位置比较
|
// 关闭调试测试后的位置比较
|
||||||
|
//关闭调试测试后的位置比较
|
||||||
for (int i = 0; i < 16; i++)
|
for (int i = 0; i < 16; i++)
|
||||||
{
|
{
|
||||||
rtn = CMCDLL_NET.MCF_Set_Compare_Config_Net((ushort)i, 0, 0, station);
|
rtn = CMCDLL_NET.MCF_Set_Compare_Config_Net((ushort)i, 0, 0, station);
|
||||||
|
Console.WriteLine($"MCF_Set_Compare_Config_Net {i}::{rtn}");
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2.配置物件设置
|
//2.配置物件设置
|
||||||
rtn = CMCDLL_NET_Sorting.MCF_Sorting_Set_Piece_Size_Net(PieceMaxSize, PieceMinSize, station);
|
rtn = CMCDLL_NET.MCF_Sorting_Set_Piece_Size_Net(PieceMaxSize, PieceMinSize, station);
|
||||||
|
Console.WriteLine($"MCF_Sorting_Set_Piece_Size_Net::{rtn}");
|
||||||
|
|
||||||
|
rtn = CMCDLL_NET.MCF_Sorting_Set_Piece_Place_Net(MinDistance, MinTimeInterval, station);
|
||||||
rtn = CMCDLL_NET_Sorting.MCF_Sorting_Set_Piece_Place_Net(MinDistance, MinTimeInterval, station);
|
Console.WriteLine($"MCF_Sorting_Set_Piece_Place_Net::{rtn}");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (BoardCount < 2)
|
//if (BoardCount < 2)
|
||||||
{
|
//{
|
||||||
|
// // rtn = CMCDLL_NET_Sorting.MCF_Sorting_Camera_Blow_Config_Net(10, 6, 0);
|
||||||
|
// // 3.配置相机设置
|
||||||
// rtn = CMCDLL_NET_Sorting.MCF_Sorting_Camera_Blow_Config_Net(10, 6, 0);
|
// rtn = CMCDLL_NET_Sorting.MCF_Sorting_Camera_Blow_Config_Net(10, 6, 0);
|
||||||
// 3.配置相机设置
|
// //设置来料使能 0 是默认 1是开始
|
||||||
rtn = CMCDLL_NET_Sorting.MCF_Sorting_Camera_Blow_Config_Net(10, 6, 0);
|
// //
|
||||||
//设置来料使能 0 是默认 1是开始
|
// rtn = CMCDLL_NET.MCF_Sorting_Set_Input_Enable_Net((ushort)SortingInputSetting.BitInputNumber, 1);
|
||||||
//
|
// //设置物件检测有效电平 0是低电平 1是高电平
|
||||||
rtn = CMCDLL_NET_Sorting.MCF_Sorting_Set_Input_Enable_Net((ushort)SortingInputSetting.BitInputNumber, 1);
|
// rtn = CMCDLL_NET_Sorting.MCF_Sorting_Set_Input_Logic_Net((ushort)SortingInputSetting.BitInputNumber, 0);
|
||||||
//设置物件检测有效电平 0是低电平 1是高电平
|
// //设置来料检测编码器 双转盘要设置两个轴
|
||||||
rtn = CMCDLL_NET_Sorting.MCF_Sorting_Set_Input_Logic_Net((ushort)SortingInputSetting.BitInputNumber, 0);
|
// /*Bit_Input_Number:设置位号。
|
||||||
//设置来料检测编码器 双转盘要设置两个轴
|
// 取值: Bit_Input_0, Bit_Input_1。
|
||||||
/*Bit_Input_Number:设置位号。
|
// Axis: 轴号。
|
||||||
取值: Bit_Input_0, Bit_Input_1。
|
// Source:跟随方式
|
||||||
Axis: 轴号。
|
// 取值:0:命令
|
||||||
Source:跟随方式
|
// 1:编码器(默认)
|
||||||
取值:0:命令
|
// StationNumber: 站点号;*/
|
||||||
1:编码器(默认)
|
// // rtn = CMCDLL_NET_Sorting.MCF_Sorting_Set_Input_Source_Net((ushort)IIConfig.SortingInputSetting.BitInputNumber, 0, 1);
|
||||||
StationNumber: 站点号;*/
|
// rtn = CMCDLL_NET_Sorting.MCF_Sorting_Set_Input_Source_Net((ushort)SortingInputSetting.BitInputNumber, 1, 1);
|
||||||
// rtn = CMCDLL_NET_Sorting.MCF_Sorting_Set_Input_Source_Net((ushort)IIConfig.SortingInputSetting.BitInputNumber, 0, 1);
|
|
||||||
rtn = CMCDLL_NET_Sorting.MCF_Sorting_Set_Input_Source_Net((ushort)SortingInputSetting.BitInputNumber, 1, 1);
|
|
||||||
|
|
||||||
|
|
||||||
//rtn = CMCDLL_NET_Sorting.MCF_Sorting_Camera_Blow_Config_Net(
|
// //rtn = CMCDLL_NET_Sorting.MCF_Sorting_Camera_Blow_Config_Net(
|
||||||
// (ushort)IIConfig.SnapshotSettings.Count,
|
// // (ushort)IIConfig.SnapshotSettings.Count,
|
||||||
// (ushort)IIConfig.BlowSettings.Count,
|
// // (ushort)IIConfig.BlowSettings.Count,
|
||||||
// 0);
|
// // 0);
|
||||||
// rtn = CMCDLL_NET_Sorting.MCF_Set_Config_Camera_Net();
|
// // rtn = CMCDLL_NET_Sorting.MCF_Set_Config_Camera_Net();
|
||||||
//为防止转盘第二个盘不触发拍照 设置一键取反功能
|
// //为防止转盘第二个盘不触发拍照 设置一键取反功能
|
||||||
}
|
//}
|
||||||
// 3.配置相机设置
|
// 3.配置相机设置
|
||||||
|
|
||||||
ConfigCamera();
|
ConfigCamera();
|
||||||
|
|
||||||
// 4.配置气阀
|
// 4.配置气阀
|
||||||
ConfigBlow();
|
// ConfigBlow();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -334,54 +349,33 @@ namespace XKRS.Device.SolidMotionCard
|
|||||||
|
|
||||||
for (ushort card = 0; card < cardCount; card++)
|
for (ushort card = 0; card < cardCount; card++)
|
||||||
{
|
{
|
||||||
//IIConfig.SortingInputSettings.ForEach(sortingInputSetting =>
|
//5.开启筛选
|
||||||
|
rtn = CMCDLL_NET.MCF_Sorting_Start_Net(0, card);
|
||||||
|
if (rtn != (short)0)
|
||||||
|
{
|
||||||
|
// LogAsync(DateTime.Now, LogLevel.Warning, $"卡{station}开启筛选异常,ret:{rtn}");
|
||||||
|
}
|
||||||
|
//if (cardCount < 2)
|
||||||
//{
|
//{
|
||||||
// var camStart = 0;
|
// // 最小值 1 2 2
|
||||||
// if (sortingInputSetting.EnableBindCamera)
|
// var ret = CMCDLL_NET_Sorting.MCF_Sorting_Set_Input_Bind_Net(
|
||||||
// {
|
// (ushort)SortingInputSetting.BitInputNumber, // 1
|
||||||
// camStart = sortingInputSetting.CameraStartNumber;
|
// SortingInputSetting.CameraStartNumber, // 7,
|
||||||
// }
|
// SortingInputSetting.BlowStartNumber, // 2,
|
||||||
|
|
||||||
// var blowStart = 0;
|
|
||||||
// if (sortingInputSetting.EnableBindBlow)
|
|
||||||
// {
|
|
||||||
// blowStart = sortingInputSetting.BlowStartNumber;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// var b = (ushort)sortingInputSetting.BitInputNumber;
|
|
||||||
// //var ret = CMCDLL_NET_Sorting.MCF_Sorting_Set_Input_Bind_Net(b,
|
|
||||||
// // (ushort)camStart,
|
|
||||||
// // (ushort)blowStart,
|
|
||||||
// // card);
|
|
||||||
|
|
||||||
// var ret = CMCDLL_NET_Sorting.MCF_Sorting_Set_Input_Bind_Net(1,
|
|
||||||
// 1,
|
|
||||||
// 2,
|
|
||||||
// card);
|
// card);
|
||||||
|
|
||||||
//});
|
//}
|
||||||
// CMCDLL_NET_Sorting.MCF_Sorting_Set_Input_Source_Net();
|
|
||||||
if (cardCount < 2)
|
|
||||||
{
|
|
||||||
// 最小值 1 2 2
|
|
||||||
var ret = CMCDLL_NET_Sorting.MCF_Sorting_Set_Input_Bind_Net(
|
|
||||||
(ushort)SortingInputSetting.BitInputNumber, // 1
|
|
||||||
SortingInputSetting.CameraStartNumber, // 7,
|
|
||||||
SortingInputSetting.BlowStartNumber, // 2,
|
|
||||||
card);
|
|
||||||
|
|
||||||
}
|
//for (ushort station = 0; station < cardCount; station++)
|
||||||
|
//{
|
||||||
for (ushort station = 0; station < cardCount; station++)
|
// // 5.开启筛选
|
||||||
{
|
// //开启自动筛选功能
|
||||||
// 5.开启筛选
|
// rtn = CMCDLL_NET_Sorting.MCF_Sorting_Start_Net(0, station);
|
||||||
//开启自动筛选功能
|
// if (rtn != (short)FuncRet.Function_Success)
|
||||||
rtn = CMCDLL_NET_Sorting.MCF_Sorting_Start_Net(0, station);
|
// {
|
||||||
if (rtn != (short)FuncRet.Function_Success)
|
// //LogAsync(DateTime.Now, LogLevel.Warning, $"卡{card}开启筛选异常,ret:{rtn}");
|
||||||
{
|
// }
|
||||||
//LogAsync(DateTime.Now, LogLevel.Warning, $"卡{card}开启筛选异常,ret:{rtn}");
|
//}
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -408,9 +402,12 @@ namespace XKRS.Device.SolidMotionCard
|
|||||||
|
|
||||||
public override void Stop()
|
public override void Stop()
|
||||||
{
|
{
|
||||||
|
isconnected = false;
|
||||||
//base.Stop();
|
//base.Stop();
|
||||||
AllMoveStop();
|
AxisStop();
|
||||||
AllAxisOff();
|
int ret = CMCDLL_NET.MCF_Set_Servo_Enable_Net(0, (ushort)ServoLogic.Servo_Open, 0);
|
||||||
|
|
||||||
|
// AllAxisOff();
|
||||||
|
|
||||||
for (ushort station = 0; station < BoardCount; station++)
|
for (ushort station = 0; station < BoardCount; station++)
|
||||||
{
|
{
|
||||||
@@ -623,7 +620,7 @@ namespace XKRS.Device.SolidMotionCard
|
|||||||
// 初始化
|
// 初始化
|
||||||
for (ushort station = 0; station < BoardCount; station++)
|
for (ushort station = 0; station < BoardCount; station++)
|
||||||
{
|
{
|
||||||
ret = CMCDLL_NET_Sorting.MCF_Sorting_Init_Net(station);
|
ret = CMCDLL_NET.MCF_Sorting_Init_Net(station);
|
||||||
stations.Add(station);
|
stations.Add(station);
|
||||||
cardTypes.Add(2);
|
cardTypes.Add(2);
|
||||||
}
|
}
|
||||||
@@ -645,8 +642,8 @@ namespace XKRS.Device.SolidMotionCard
|
|||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
MCF_Screen_Set_Trigger1();
|
//MCF_Screen_Set_Trigger1();
|
||||||
MCF_Screen_Set_Trigger1(1);
|
// MCF_Screen_Set_Trigger1(1);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -849,7 +846,14 @@ namespace XKRS.Device.SolidMotionCard
|
|||||||
return ret == (short)FuncRet.Function_Success;
|
return ret == (short)FuncRet.Function_Success;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
//方案2:不使用外部文本框输入参数,直接写入参数
|
||||||
|
|
||||||
|
public void JOGRun(double MaxV,double MaxA)
|
||||||
|
{
|
||||||
|
int ret = CMCDLL_NET.MCF_Set_Pulse_Mode_Net(0, (ushort)PulseMode.Pulse_Dir_H, 0);
|
||||||
|
ret = CMCDLL_NET.MCF_Set_Servo_Enable_Net(0, (ushort)ServoLogic.Servo_Close, 0);
|
||||||
|
ret=CMCDLL_NET.MCF_JOG_Net(0, MaxV, MaxA, 0);
|
||||||
|
}
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 点位到点位运动
|
/// 点位到点位运动
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -1381,6 +1385,31 @@ namespace XKRS.Device.SolidMotionCard
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public void AxisStop()
|
||||||
|
{
|
||||||
|
short rtn;
|
||||||
|
ushort StationNumber = 0;
|
||||||
|
for (ushort a = 0; a < 4; a++)
|
||||||
|
{
|
||||||
|
rtn = CMCDLL_NET.MCF_Set_Axis_Stop_Profile_Net(a, 10000, 100000, 1, StationNumber);//设置轴S型停止曲线参数
|
||||||
|
rtn = CMCDLL_NET.MCF_Axis_Stop_Net(a, 1, StationNumber);//设置轴为平滑停止模式
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public bool CArdReset()
|
||||||
|
{
|
||||||
|
|
||||||
|
// ConvertFromAxis(startAxisIndex, out ushort station, out ushort axis);
|
||||||
|
|
||||||
|
var ret = CMCDLL_NET.MCF_Set_Position_Net(0, 0, 0);
|
||||||
|
var ret2 = CMCDLL_NET.MCF_Set_Encoder_Net(0, 0, 0);
|
||||||
|
|
||||||
|
return ret2 == 0 ? true : false;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 某个轴运动停止
|
/// 某个轴运动停止
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -1814,7 +1843,7 @@ namespace XKRS.Device.SolidMotionCard
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
var rtn = CMCDLL_NET_Sorting.MCF_Sorting_Set_Trig_Camera_Delay_Count_Net(i,
|
var rtn = CMCDLL_NET.MCF_Sorting_Set_Trig_Camera_Delay_Count_Net(i,
|
||||||
camSetting.CameraDelayCountMS, camSetting.StationNumber);
|
camSetting.CameraDelayCountMS, camSetting.StationNumber);
|
||||||
|
|
||||||
|
|
||||||
@@ -1849,7 +1878,7 @@ namespace XKRS.Device.SolidMotionCard
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
rtn = CMCDLL_NET_Sorting.MCF_Sorting_Set_Camera_Net(
|
rtn = CMCDLL_NET.MCF_Sorting_Set_Camera_Net(
|
||||||
i, // CCD0
|
i, // CCD0
|
||||||
CameraPositionReal,
|
CameraPositionReal,
|
||||||
RotationDirectionReal,
|
RotationDirectionReal,
|
||||||
@@ -1959,23 +1988,31 @@ namespace XKRS.Device.SolidMotionCard
|
|||||||
switch (blowSetting.BlowType)
|
switch (blowSetting.BlowType)
|
||||||
{
|
{
|
||||||
case BlowType.OK:
|
case BlowType.OK:
|
||||||
CMCDLL_NET_Sorting.MCF_Sorting_Set_Blow_OK_Net(CameraPositionReal, (ushort)rotationDirectionEnum, (ushort)blowSetting.ActionMode, (ushort)ioIndex, blowSetting.StationNumber);
|
CMCDLL_NET.MCF_Sorting_Set_Blow_OK_Net(CameraPositionReal, (ushort)rotationDirectionEnum, (ushort)blowSetting.ActionMode, (ushort)ioIndex, blowSetting.StationNumber);
|
||||||
break;
|
break;
|
||||||
case BlowType.NG:
|
case BlowType.NG:
|
||||||
CMCDLL_NET_Sorting.MCF_Sorting_Set_Blow_NG_Net(CameraPositionReal, (ushort)rotationDirectionEnum, (ushort)blowSetting.ActionMode, (ushort)ioIndex, blowSetting.StationNumber);
|
CMCDLL_NET.MCF_Sorting_Set_Blow_NG_Net(CameraPositionReal, (ushort)rotationDirectionEnum, (ushort)blowSetting.ActionMode, (ushort)ioIndex, blowSetting.StationNumber);
|
||||||
break;
|
break;
|
||||||
case BlowType.Blow1:
|
case BlowType.Blow1:
|
||||||
CMCDLL_NET_Sorting.MCF_Sorting_Set_Blow_Net(1, CameraPositionReal, (ushort)rotationDirectionEnum, (ushort)blowSetting.ActionMode, (ushort)ioIndex, blowSetting.StationNumber);
|
CMCDLL_NET.MCF_Sorting_Set_Blow_1_Net(blowSetting.BlowPosition, (ushort)rotationDirectionEnum, (ushort)blowSetting.ActionMode, (ushort)blowSetting.BlowIO.IOIndex, blowSetting.StationNumber);
|
||||||
break;
|
break;
|
||||||
///第一路绑定OK NG 吹起口1
|
///第一路绑定OK NG 吹起口1
|
||||||
case BlowType.Blow2:
|
case BlowType.Blow2:
|
||||||
CMCDLL_NET_Sorting.MCF_Sorting_Set_Blow_Net(2, CameraPositionReal, (ushort)rotationDirectionEnum, (ushort)blowSetting.ActionMode, (ushort)ioIndex, blowSetting.StationNumber);
|
CMCDLL_NET.MCF_Sorting_Set_Blow_2_Net(blowSetting.BlowPosition, (ushort)rotationDirectionEnum, (ushort)blowSetting.ActionMode, (ushort)blowSetting.BlowIO.IOIndex, blowSetting.StationNumber);
|
||||||
break;
|
break;
|
||||||
case BlowType.Blow3:
|
case BlowType.Blow3:
|
||||||
CMCDLL_NET_Sorting.MCF_Sorting_Set_Blow_Net(3, CameraPositionReal, (ushort)rotationDirectionEnum, (ushort)blowSetting.ActionMode, (ushort)ioIndex, blowSetting.StationNumber);
|
CMCDLL_NET.MCF_Sorting_Set_Blow_3_Net(blowSetting.BlowPosition, (ushort)rotationDirectionEnum, (ushort)blowSetting.ActionMode, (ushort)blowSetting.BlowIO.IOIndex, blowSetting.StationNumber);
|
||||||
break;
|
break;
|
||||||
case BlowType.Blow4:
|
case BlowType.Blow4:
|
||||||
CMCDLL_NET_Sorting.MCF_Sorting_Set_Blow_Net(4, CameraPositionReal, (ushort)rotationDirectionEnum, (ushort)blowSetting.ActionMode, (ushort)ioIndex, blowSetting.StationNumber);
|
CMCDLL_NET.MCF_Sorting_Set_Blow_4_Net(blowSetting.BlowPosition, (ushort)rotationDirectionEnum, (ushort)blowSetting.ActionMode, (ushort)blowSetting.BlowIO.IOIndex, blowSetting.StationNumber);
|
||||||
|
break;
|
||||||
|
case BlowType.Blow5:
|
||||||
|
CMCDLL_NET.MCF_Sorting_Set_Blow_5_Net(blowSetting.BlowPosition, (ushort)rotationDirectionEnum, (ushort)blowSetting.ActionMode, (ushort)blowSetting.BlowIO.IOIndex, blowSetting.StationNumber);
|
||||||
|
break;
|
||||||
|
case BlowType.Blow6:
|
||||||
|
CMCDLL_NET.MCF_Sorting_Set_Blow_6_Net(blowSetting.BlowPosition, (ushort)rotationDirectionEnum, (ushort)blowSetting.ActionMode, (ushort)blowSetting.BlowIO.IOIndex, blowSetting.StationNumber);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
break;
|
break;
|
||||||
//case BlowType.OK:
|
//case BlowType.OK:
|
||||||
// CMCDLL_NET_Sorting.MCF_Sorting_Set_Blow_OK_Net(setting.BlowPosition, (ushort)IIConfig.MotionDir, (ushort)setting.ActionMode, (ushort)setting.BlowIO.IOIndex, setting.StationNumber);
|
// CMCDLL_NET_Sorting.MCF_Sorting_Set_Blow_OK_Net(setting.BlowPosition, (ushort)IIConfig.MotionDir, (ushort)setting.ActionMode, (ushort)setting.BlowIO.IOIndex, setting.StationNumber);
|
||||||
@@ -2002,8 +2039,7 @@ namespace XKRS.Device.SolidMotionCard
|
|||||||
//case BlowType.Blow6:
|
//case BlowType.Blow6:
|
||||||
// CMCDLL_NET_Sorting.MCF_Sorting_Set_Blow_6_Net(setting.BlowPosition, (ushort)IIConfig.MotionDir, (ushort)setting.ActionMode, (ushort)setting.BlowIO.IOIndex, setting.StationNumber);
|
// CMCDLL_NET_Sorting.MCF_Sorting_Set_Blow_6_Net(setting.BlowPosition, (ushort)IIConfig.MotionDir, (ushort)setting.ActionMode, (ushort)setting.BlowIO.IOIndex, setting.StationNumber);
|
||||||
// break;
|
// break;
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -12,10 +12,6 @@
|
|||||||
<Platforms>AnyCPU;x64</Platforms>
|
<Platforms>AnyCPU;x64</Platforms>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<PackageReference Include="System.IO.Ports" Version="9.0.2" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\DH.Commons\DH.Commons.csproj" />
|
<ProjectReference Include="..\DH.Commons\DH.Commons.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|||||||
@@ -1,81 +0,0 @@
|
|||||||
using System.IO.Ports;
|
|
||||||
using DH.Commons.Enums;
|
|
||||||
using HslCommunication;
|
|
||||||
|
|
||||||
namespace DH.Devices.PLC
|
|
||||||
{
|
|
||||||
public class PLCBase
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// 连接状态
|
|
||||||
/// </summary>
|
|
||||||
public bool connected = false;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 类型
|
|
||||||
/// </summary>
|
|
||||||
public EnumPLCType PLCType=EnumPLCType.信捷XD_网口;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 串口号
|
|
||||||
/// </summary>
|
|
||||||
public string portName="COM1";
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 波特率
|
|
||||||
/// </summary>
|
|
||||||
public int baudRate = 9600;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 数据位
|
|
||||||
/// </summary>
|
|
||||||
public int dataBit = 8;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 停止位
|
|
||||||
/// </summary>
|
|
||||||
public StopBits stopBit = (StopBits)Enum.Parse(typeof(StopBits), "One");
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 奇偶效验位
|
|
||||||
/// </summary>
|
|
||||||
public Parity parity = (Parity)Enum.Parse(typeof(Parity), "None");
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// IP地址
|
|
||||||
/// </summary>
|
|
||||||
public string IP = "192.168.6.6";
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 端口号
|
|
||||||
/// </summary>
|
|
||||||
public int Port = 502;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 初始化
|
|
||||||
/// </summary>
|
|
||||||
/// <returns></returns>
|
|
||||||
public virtual bool PLCConnect() { return false; }
|
|
||||||
|
|
||||||
public virtual bool PLCDisConnect() { return false; }
|
|
||||||
|
|
||||||
public virtual ushort ReadShort(string address) { return 0; }
|
|
||||||
|
|
||||||
public virtual int ReadInt(string address) { return 0; }
|
|
||||||
|
|
||||||
|
|
||||||
public virtual float ReadFloat(string address) { return 0; }
|
|
||||||
|
|
||||||
public virtual bool ReadBool(string address) { return false; }
|
|
||||||
|
|
||||||
public virtual bool WriteShort(string address, short value, bool waitForReply = true) { return false; }
|
|
||||||
|
|
||||||
public virtual bool WriteInt(string address, int value, bool waitForReply = true) { return false; }
|
|
||||||
|
|
||||||
public virtual bool WriteDInt(string address, int value, bool waitForReply = true) { return false; }
|
|
||||||
|
|
||||||
public virtual bool WriteFloat(string address, float value, bool waitForReply = true) { return false; }
|
|
||||||
|
|
||||||
public virtual bool WriteBool(string address, bool value, bool waitForReply = true) { return false; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -1,4 +1,4 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk.WindowsDesktop">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net8.0-windows</TargetFramework>
|
<TargetFramework>net8.0-windows</TargetFramework>
|
||||||
@@ -11,14 +11,43 @@
|
|||||||
<Platforms>AnyCPU;x64</Platforms>
|
<Platforms>AnyCPU;x64</Platforms>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
|
||||||
|
<Optimize>False</Optimize>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
|
<Optimize>False</Optimize>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<PackageReference Include="AntdUI" Version="1.8.9" />
|
||||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
||||||
<PackageReference Include="OpenCvSharp4" Version="4.10.0.20241108" />
|
<PackageReference Include="OpenCvSharp4" Version="4.10.0.20241108" />
|
||||||
<PackageReference Include="OpenCvSharp4.Extensions" Version="4.10.0.20241108" />
|
<PackageReference Include="OpenCvSharp4.Extensions" Version="4.10.0.20241108" />
|
||||||
<PackageReference Include="OpenCvSharp4.runtime.win" Version="4.10.0.20241108" />
|
<PackageReference Include="OpenCvSharp4.runtime.win" Version="4.10.0.20241108" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\DH.Commons\DH.Commons.csproj" />
|
||||||
|
<ProjectReference Include="..\DH.UI.Model.Winform\DH.UI.Model.Winform.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<Reference Include="halcondotnet">
|
||||||
|
<HintPath>..\x64\Debug\halcondotnet.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
@@ -1,666 +0,0 @@
|
|||||||
using OpenCvSharp;
|
|
||||||
using System.ComponentModel;
|
|
||||||
using System.Drawing;
|
|
||||||
using static OpenCvSharp.AgastFeatureDetector;
|
|
||||||
using System.Text.RegularExpressions;
|
|
||||||
using System.Text;
|
|
||||||
using System.Drawing.Design;
|
|
||||||
|
|
||||||
namespace DH.Devices.Vision
|
|
||||||
{
|
|
||||||
public enum MLModelType
|
|
||||||
{
|
|
||||||
[Description("图像分类")]
|
|
||||||
ImageClassification = 1,
|
|
||||||
[Description("目标检测")]
|
|
||||||
ObjectDetection = 2,
|
|
||||||
//[Description("图像分割")]
|
|
||||||
//ImageSegmentation = 3
|
|
||||||
[Description("语义分割")]
|
|
||||||
SemanticSegmentation = 3,
|
|
||||||
[Description("实例分割")]
|
|
||||||
InstanceSegmentation = 4,
|
|
||||||
[Description("目标检测GPU")]
|
|
||||||
ObjectGPUDetection = 5
|
|
||||||
}
|
|
||||||
public class ModelLabel
|
|
||||||
{
|
|
||||||
public string LabelId { get; set; }
|
|
||||||
|
|
||||||
|
|
||||||
[Category("模型标签")]
|
|
||||||
[DisplayName("模型标签索引")]
|
|
||||||
[Description("模型识别的标签索引")]
|
|
||||||
public int LabelIndex { get; set; }
|
|
||||||
|
|
||||||
|
|
||||||
[Category("模型标签")]
|
|
||||||
[DisplayName("模型标签")]
|
|
||||||
[Description("模型识别的标签名称")]
|
|
||||||
public string LabelName { get; set; }
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//[Category("模型配置")]
|
|
||||||
//[DisplayName("模型参数配置")]
|
|
||||||
//[Description("模型参数配置集合")]
|
|
||||||
|
|
||||||
//public ModelParamSetting ModelParamSetting { get; set; } = new ModelParamSetting();
|
|
||||||
|
|
||||||
|
|
||||||
public string GetDisplayText()
|
|
||||||
{
|
|
||||||
return $"{LabelId}-{LabelName}";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public class MLRequest
|
|
||||||
{
|
|
||||||
public int ImageChannels = 3;
|
|
||||||
public Mat mImage;
|
|
||||||
public int ResizeWidth;
|
|
||||||
public int ResizeHeight;
|
|
||||||
|
|
||||||
public float confThreshold;
|
|
||||||
|
|
||||||
public float iouThreshold;
|
|
||||||
|
|
||||||
//public int ImageResizeCount;
|
|
||||||
public bool IsCLDetection;
|
|
||||||
public int ProCount;
|
|
||||||
public string in_node_name;
|
|
||||||
|
|
||||||
public string out_node_name;
|
|
||||||
|
|
||||||
public string in_lable_path;
|
|
||||||
|
|
||||||
public int ResizeImageSize;
|
|
||||||
public int segmentWidth;
|
|
||||||
public int ImageWidth;
|
|
||||||
|
|
||||||
// public List<labelStringBase> OkClassTxtList;
|
|
||||||
|
|
||||||
|
|
||||||
public List<ModelLabel> LabelNames;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
public enum ResultState
|
|
||||||
{
|
|
||||||
|
|
||||||
[Description("检测NG")]
|
|
||||||
DetectNG = -3,
|
|
||||||
|
|
||||||
//[Description("检测不足TBD")]
|
|
||||||
// ShortageTBD = -2,
|
|
||||||
[Description("检测结果TBD")]
|
|
||||||
ResultTBD = -1,
|
|
||||||
[Description("OK")]
|
|
||||||
OK = 1,
|
|
||||||
// [Description("NG")]
|
|
||||||
// NG = 2,
|
|
||||||
//统计结果
|
|
||||||
[Description("A类NG")]
|
|
||||||
A_NG = 25,
|
|
||||||
[Description("B类NG")]
|
|
||||||
B_NG = 26,
|
|
||||||
[Description("C类NG")]
|
|
||||||
C_NG = 27,
|
|
||||||
}
|
|
||||||
/// <summary>
|
|
||||||
/// 深度学习 识别结果明细 面向业务:detect 面向深度学习:Recongnition、Inference
|
|
||||||
/// </summary>
|
|
||||||
public class DetectionResultDetail
|
|
||||||
{
|
|
||||||
public string LabelBGR { get; set; }//识别到对象的标签BGR
|
|
||||||
|
|
||||||
|
|
||||||
public int LabelNo { get; set; } // 识别到对象的标签索引
|
|
||||||
|
|
||||||
public string LabelName { get; set; }//识别到对象的标签名称
|
|
||||||
|
|
||||||
public double Score { get; set; }//识别目标结果的可能性、得分
|
|
||||||
|
|
||||||
public string LabelDisplay { get; set; }//识别到对象的 显示信息
|
|
||||||
|
|
||||||
public double Area { get; set; }//识别目标的区域面积
|
|
||||||
|
|
||||||
public Rectangle Rect { get; set; }//识别目标的外接矩形
|
|
||||||
|
|
||||||
public RotatedRect MinRect { get; set; }//识别目标的最小外接矩形(带角度)
|
|
||||||
|
|
||||||
public ResultState InferenceResult { get; set; }//只是模型推理 label的结果
|
|
||||||
|
|
||||||
public double DistanceToImageCenter { get; set; } //计算矩形框到图像中心的距离
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public ResultState FinalResult { get; set; }//模型推理+其他视觉、逻辑判断后 label结果
|
|
||||||
}
|
|
||||||
public class MLResult
|
|
||||||
{
|
|
||||||
public bool IsSuccess = false;
|
|
||||||
public string ResultMessage;
|
|
||||||
public Bitmap ResultMap;
|
|
||||||
public List<DetectionResultDetail> ResultDetails = new List<DetectionResultDetail>();
|
|
||||||
}
|
|
||||||
public class MLInit
|
|
||||||
{
|
|
||||||
public string ModelFile;
|
|
||||||
public string InferenceDevice;
|
|
||||||
|
|
||||||
|
|
||||||
public int InferenceWidth;
|
|
||||||
public int InferenceHeight;
|
|
||||||
|
|
||||||
public string InputNodeName;
|
|
||||||
|
|
||||||
|
|
||||||
public int SizeModel;
|
|
||||||
|
|
||||||
public bool bReverse;//尺寸测量正反面
|
|
||||||
//目标检测Gpu
|
|
||||||
public bool IsGPU;
|
|
||||||
public int GPUId;
|
|
||||||
public float Score_thre;
|
|
||||||
public MLInit(string modelFile, bool isGPU, int gpuId, float score_thre)
|
|
||||||
{
|
|
||||||
ModelFile = modelFile;
|
|
||||||
IsGPU = isGPU;
|
|
||||||
GPUId = gpuId;
|
|
||||||
Score_thre = score_thre;
|
|
||||||
}
|
|
||||||
|
|
||||||
public MLInit(string modelFile, string inputNodeName, string inferenceDevice, int inferenceWidth, int inferenceHeight)
|
|
||||||
{
|
|
||||||
ModelFile = modelFile;
|
|
||||||
InferenceDevice = inferenceDevice;
|
|
||||||
|
|
||||||
InferenceWidth = inferenceWidth;
|
|
||||||
InferenceHeight = inferenceHeight;
|
|
||||||
InputNodeName = inputNodeName;
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public class DetectStationResult
|
|
||||||
{
|
|
||||||
public string Pid { get; set; }
|
|
||||||
|
|
||||||
public string TempPid { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 检测工位名称
|
|
||||||
/// </summary>
|
|
||||||
public string DetectName { get; set; }
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 深度学习 检测结果
|
|
||||||
/// </summary>
|
|
||||||
public List<DetectionResultDetail> DetectDetails = new List<DetectionResultDetail>();
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 工位检测结果
|
|
||||||
/// </summary>
|
|
||||||
public ResultState ResultState { get; set; } = ResultState.ResultTBD;
|
|
||||||
|
|
||||||
|
|
||||||
public double FinalResultfScore { get; set; } = 0.0;
|
|
||||||
|
|
||||||
|
|
||||||
public string ResultLabel { get; set; } = "";// 多个ng时,根据label优先级,设定当前检测项的label
|
|
||||||
|
|
||||||
public string ResultLabelCategoryId { get; set; } = "";// 多个ng时,根据label优先级,设定当前检测项的label
|
|
||||||
|
|
||||||
public int PreTreatState { get; set; }
|
|
||||||
public bool IsPreTreatDone { get; set; } = true;
|
|
||||||
|
|
||||||
public bool IsAfterTreatDone { get; set; } = true;
|
|
||||||
|
|
||||||
public bool IsMLDetectDone { get; set; } = true;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 预处理阶段已经NG
|
|
||||||
/// </summary>
|
|
||||||
public bool IsPreTreatNG { get; set; } = false;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 目标检测NG
|
|
||||||
/// </summary>
|
|
||||||
public bool IsObjectDetectNG { get; set; } = false;
|
|
||||||
|
|
||||||
public DateTime EndTime { get; set; }
|
|
||||||
|
|
||||||
public int StationDetectElapsed { get; set; }
|
|
||||||
public static string NormalizeAndClean(string input)
|
|
||||||
{
|
|
||||||
if (input == null) return null;
|
|
||||||
|
|
||||||
// Step 1: 标准化字符编码为 Form C (规范组合)
|
|
||||||
string normalizedString = input.Normalize(NormalizationForm.FormC);
|
|
||||||
|
|
||||||
// Step 2: 移除所有空白字符,包括制表符和换行符
|
|
||||||
string withoutWhitespace = Regex.Replace(normalizedString, @"\s+", "");
|
|
||||||
|
|
||||||
// Step 3: 移除控制字符 (Unicode 控制字符,范围 \u0000 - \u001F 和 \u007F)
|
|
||||||
string withoutControlChars = Regex.Replace(withoutWhitespace, @"[\u0000-\u001F\u007F]+", "");
|
|
||||||
|
|
||||||
// Step 4: 移除特殊的不可见字符(如零宽度空格等)
|
|
||||||
string cleanedString = Regex.Replace(withoutControlChars, @"[\u200B\u200C\u200D\uFEFF]+", "");
|
|
||||||
|
|
||||||
return cleanedString;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
public class RelatedCamera
|
|
||||||
{
|
|
||||||
|
|
||||||
[Category("关联相机")]
|
|
||||||
[DisplayName("关联相机")]
|
|
||||||
[Description("关联相机描述")]
|
|
||||||
|
|
||||||
//[TypeConverter(typeof(CollectionCountConvert))]
|
|
||||||
public string CameraSourceId { get; set; } = "";
|
|
||||||
|
|
||||||
public RelatedCamera()
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
public RelatedCamera(string cameraSourceId)
|
|
||||||
{
|
|
||||||
CameraSourceId = cameraSourceId;
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public class DetectionConfig
|
|
||||||
{
|
|
||||||
[ReadOnly(true)]
|
|
||||||
public string Id { get; set; } = Guid.NewGuid().ToString();
|
|
||||||
|
|
||||||
|
|
||||||
[Category("检测配置")]
|
|
||||||
[DisplayName("检测配置名称")]
|
|
||||||
[Description("检测配置名称")]
|
|
||||||
public string Name { get; set; }
|
|
||||||
|
|
||||||
[Category("关联相机")]
|
|
||||||
[DisplayName("关联相机")]
|
|
||||||
[Description("关联相机描述")]
|
|
||||||
|
|
||||||
|
|
||||||
public string CameraSourceId { get; set; } = "";
|
|
||||||
|
|
||||||
|
|
||||||
[Category("关联相机集合")]
|
|
||||||
[DisplayName("关联相机集合")]
|
|
||||||
[Description("关联相机描述")]
|
|
||||||
//[TypeConverter(typeof(DeviceIdSelectorConverter<CameraBase>))]
|
|
||||||
|
|
||||||
public List<RelatedCamera> CameraCollects { get; set; } = new List<RelatedCamera>();
|
|
||||||
|
|
||||||
|
|
||||||
[Category("启用配置")]
|
|
||||||
[DisplayName("是否启用GPU检测")]
|
|
||||||
[Description("是否启用GPU检测")]
|
|
||||||
public bool IsEnableGPU { get; set; } = false;
|
|
||||||
|
|
||||||
[Category("启用配置")]
|
|
||||||
[DisplayName("是否混料模型")]
|
|
||||||
[Description("是否混料模型")]
|
|
||||||
public bool IsMixModel { get; set; } = false;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
[Category("启用配置")]
|
|
||||||
[DisplayName("是否启用该检测")]
|
|
||||||
[Description("是否启用该检测")]
|
|
||||||
public bool IsEnabled { get; set; }
|
|
||||||
|
|
||||||
[Category("启用配置")]
|
|
||||||
[DisplayName("是否加入检测工位")]
|
|
||||||
[Description("是否加入检测工位")]
|
|
||||||
public bool IsAddStation { get; set; } = true;
|
|
||||||
|
|
||||||
[Category("2.中检测(深度学习)")]
|
|
||||||
[DisplayName("中检测-模型类型")]
|
|
||||||
[Description("模型类型:ImageClassification-图片分类;ObjectDetection:目标检测;Segmentation-图像分割")]
|
|
||||||
//[TypeConverter(typeof(EnumDescriptionConverter<MLModelType>))]
|
|
||||||
public MLModelType ModelType { get; set; } = MLModelType.ObjectDetection;
|
|
||||||
|
|
||||||
//[Category("2.中检测(深度学习)")]
|
|
||||||
//[DisplayName("中检测-GPU索引")]
|
|
||||||
//[Description("GPU索引")]
|
|
||||||
//public int GPUIndex { get; set; } = 0;
|
|
||||||
|
|
||||||
[Category("2.中检测(深度学习)")]
|
|
||||||
[DisplayName("中检测-模型文件路径")]
|
|
||||||
[Description("中处理 深度学习模型文件路径,路径中不可含有中文字符,一般情况可以只配置中检测模型,当需要先用预检测过滤一次时,请先配置好与预检测相关配置")]
|
|
||||||
|
|
||||||
public string ModelPath { get; set; }
|
|
||||||
|
|
||||||
[Category("2.中检测(深度学习)")]
|
|
||||||
[DisplayName("中检测-模型宽度")]
|
|
||||||
[Description("中处理-模型宽度")]
|
|
||||||
|
|
||||||
public int ModelWidth { get; set; } = 640;
|
|
||||||
|
|
||||||
[Category("2.中检测(深度学习)")]
|
|
||||||
[DisplayName("中检测-模型高度")]
|
|
||||||
[Description("中处理-模型高度")]
|
|
||||||
|
|
||||||
public int ModelHeight { get; set; } = 640;
|
|
||||||
|
|
||||||
[Category("2.中检测(深度学习)")]
|
|
||||||
[DisplayName("中检测-模型节点名称")]
|
|
||||||
[Description("中处理-模型节点名称")]
|
|
||||||
|
|
||||||
public string ModeloutNodeName { get; set; } = "output0";
|
|
||||||
|
|
||||||
[Category("2.中检测(深度学习)")]
|
|
||||||
[DisplayName("中检测-模型置信度")]
|
|
||||||
[Description("中处理-模型置信度")]
|
|
||||||
|
|
||||||
public float ModelconfThreshold { get; set; } = 0.5f;
|
|
||||||
|
|
||||||
[Category("2.中检测(深度学习)")]
|
|
||||||
[DisplayName("中检测-模型标签路径")]
|
|
||||||
[Description("中处理-模型标签路径")]
|
|
||||||
|
|
||||||
public string in_lable_path { get; set; }
|
|
||||||
|
|
||||||
[Category("4.最终过滤(逻辑过滤)")]
|
|
||||||
[DisplayName("过滤器集合")]
|
|
||||||
[Description("最后的逻辑过滤:可根据 识别出对象的 宽度、高度、面积、得分来设置最终检测结果,同一识别目标同一判定,多项过滤器之间为“或”关系")]
|
|
||||||
|
|
||||||
public List<DetectionFilter> DetectionFilterList { get; set; } = new List<DetectionFilter>();
|
|
||||||
|
|
||||||
//[Category("深度学习配置")]
|
|
||||||
//[DisplayName("检测配置标签")]
|
|
||||||
//[Description("检测配置标签关联")]
|
|
||||||
|
|
||||||
//public List<DetectConfigLabel> DetectConfigLabelList { get; set; } = new List<DetectConfigLabel>();
|
|
||||||
|
|
||||||
|
|
||||||
public DetectionConfig()
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public DetectionConfig(string name, MLModelType modelType, string modelPath, bool isEnableGPU,string sCameraSourceId)
|
|
||||||
{
|
|
||||||
ModelPath = modelPath ?? string.Empty;
|
|
||||||
Name = name;
|
|
||||||
ModelType = modelType;
|
|
||||||
IsEnableGPU = isEnableGPU;
|
|
||||||
Id = Guid.NewGuid().ToString();
|
|
||||||
CameraSourceId = sCameraSourceId;
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/// <summary>
|
|
||||||
/// 识别目标定义 class:分类信息 Detection Segmentation:要识别的对象
|
|
||||||
/// </summary>
|
|
||||||
public class RecongnitionLabel //: IComplexDisplay
|
|
||||||
{
|
|
||||||
[Category("检测标签定义")]
|
|
||||||
[Description("检测标签编码")]
|
|
||||||
[ReadOnly(true)]
|
|
||||||
public string Id { get; set; } = Guid.NewGuid().ToString();
|
|
||||||
|
|
||||||
[Category("检测标签定义")]
|
|
||||||
[DisplayName("检测标签名称")]
|
|
||||||
[Description("检测标签名称")]
|
|
||||||
public string LabelName { get; set; } = "";
|
|
||||||
|
|
||||||
[Category("检测标签定义")]
|
|
||||||
[DisplayName("检测标签描述")]
|
|
||||||
[Description("检测标签描述,中文描述")]
|
|
||||||
public string LabelDescription { get; set; } = "";
|
|
||||||
|
|
||||||
[Category("检测标签定义")]
|
|
||||||
[DisplayName("检测标签分类")]
|
|
||||||
[Description("检测标签分类id")]
|
|
||||||
//[TypeConverter(typeof(LabelCategoryConverter))]
|
|
||||||
public string LabelCategory { get; set; } = "";
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 检测项识别对象
|
|
||||||
/// </summary>
|
|
||||||
public class DetectConfigLabel //: IComplexDisplay
|
|
||||||
{
|
|
||||||
[Category("检测项标签")]
|
|
||||||
[DisplayName("检测项标签")]
|
|
||||||
[Description("检测标签Id")]
|
|
||||||
//[TypeConverter(typeof(DetectionLabelConverter))]
|
|
||||||
public string LabelId { get; set; }
|
|
||||||
|
|
||||||
[Browsable(false)]
|
|
||||||
//public string LabelName { get => GetLabelName(); }
|
|
||||||
|
|
||||||
[Category("检测项标签")]
|
|
||||||
[DisplayName("检测标签优先级")]
|
|
||||||
[Description("检测标签优先级,值越小,优先级越高")]
|
|
||||||
public int LabelPriority { get; set; } = 0;
|
|
||||||
|
|
||||||
//[Category("检测项标签")]
|
|
||||||
//[DisplayName("标签BGR值")]
|
|
||||||
//[Description("检测标签BGR值,例如:0,128,0")]
|
|
||||||
//public string LabelBGR { get; set; }
|
|
||||||
|
|
||||||
//[Category("模型配置")]
|
|
||||||
//[DisplayName("模型参数配置")]
|
|
||||||
//[Description("模型参数配置集合")]
|
|
||||||
//[TypeConverter(typeof(ComplexObjectConvert))]
|
|
||||||
//[Editor(typeof(PropertyObjectEditor), typeof(UITypeEditor))]
|
|
||||||
//public ModelParamSetting ModelParamSetting { get; set; } = new ModelParamSetting();
|
|
||||||
|
|
||||||
//public string GetDisplayText()
|
|
||||||
//{
|
|
||||||
// string dName = "";
|
|
||||||
// if (!string.IsNullOrWhiteSpace(LabelId))
|
|
||||||
// {
|
|
||||||
// using (var scope = GlobalVar.Container.BeginLifetimeScope())
|
|
||||||
// {
|
|
||||||
// IProcessConfig config = scope.Resolve<IProcessConfig>();
|
|
||||||
|
|
||||||
// var mlBase = config.DeviceConfigs.FirstOrDefault(c => c is VisionEngineInitialConfigBase) as VisionEngineInitialConfigBase;
|
|
||||||
// if (mlBase != null)
|
|
||||||
// {
|
|
||||||
// var targetLabel = mlBase.RecongnitionLabelList.FirstOrDefault(u => u.Id == LabelId);
|
|
||||||
// if (targetLabel != null)
|
|
||||||
// {
|
|
||||||
// dName = targetLabel.GetDisplayText();
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// return dName;
|
|
||||||
//}
|
|
||||||
//public string GetLabelName()
|
|
||||||
//{
|
|
||||||
// var name = "";
|
|
||||||
|
|
||||||
|
|
||||||
// var mlBase = iConfig.DeviceConfigs.FirstOrDefault(c => c is VisionEngineInitialConfigBase) as VisionEngineInitialConfigBase;
|
|
||||||
// if (mlBase != null)
|
|
||||||
// {
|
|
||||||
// var label = mlBase.RecongnitionLabelList.FirstOrDefault(u => u.Id == LabelId);
|
|
||||||
// if (label != null)
|
|
||||||
// {
|
|
||||||
// name = label.LabelName;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
|
|
||||||
// return name;
|
|
||||||
//}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 识别对象定义分类信息 A类B类
|
|
||||||
/// </summary>
|
|
||||||
public class RecongnitionLabelCategory //: IComplexDisplay
|
|
||||||
{
|
|
||||||
[Category("检测标签分类")]
|
|
||||||
[Description("检测标签分类")]
|
|
||||||
[ReadOnly(true)]
|
|
||||||
public string Id { get; set; } = Guid.NewGuid().ToString();
|
|
||||||
|
|
||||||
[Category("检测标签分类")]
|
|
||||||
[DisplayName("检测标签分类名称")]
|
|
||||||
[Description("检测标签分类名称")]
|
|
||||||
public string CategoryName { get; set; } = "A-NG";
|
|
||||||
|
|
||||||
[Category("检测标签分类")]
|
|
||||||
[DisplayName("检测标签分类优先级")]
|
|
||||||
[Description("检测标签分类优先级,值越小,优先级越高")]
|
|
||||||
public int CategoryPriority { get; set; } = 0;
|
|
||||||
|
|
||||||
public string GetDisplayText()
|
|
||||||
{
|
|
||||||
return CategoryPriority + ":" + CategoryName;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 检测过滤
|
|
||||||
/// </summary>
|
|
||||||
public class DetectionFilter ///: IComplexDisplay
|
|
||||||
{
|
|
||||||
[Category("过滤器基础信息")]
|
|
||||||
[DisplayName("检测标签")]
|
|
||||||
[Description("检测标签信息")]
|
|
||||||
//[TypeConverter(typeof(DetectionLabelConverter))]
|
|
||||||
public string LabelId { get; set; }
|
|
||||||
|
|
||||||
// [Browsable(false)]
|
|
||||||
public string LabelName { get; set; }
|
|
||||||
|
|
||||||
[Category("过滤器基础信息")]
|
|
||||||
[DisplayName("是否启用过滤器")]
|
|
||||||
[Description("是否启用过滤器")]
|
|
||||||
public bool IsEnabled { get; set; }
|
|
||||||
|
|
||||||
[Category("过滤器判定信息")]
|
|
||||||
[DisplayName("判定结果")]
|
|
||||||
[Description("过滤器默认判定结果")]
|
|
||||||
public ResultState ResultState { get; set; } = ResultState.ResultTBD;
|
|
||||||
|
|
||||||
[Category("过滤条件")]
|
|
||||||
[DisplayName("过滤条件集合")]
|
|
||||||
[Description("过滤条件集合,集合之间为“且”关系")]
|
|
||||||
//[TypeConverter(typeof(CollectionCountConvert))]
|
|
||||||
// [Editor(typeof(ComplexCollectionEditor<FilterConditions>), typeof(UITypeEditor))]
|
|
||||||
public List<FilterConditions> FilterConditionsCollection { get; set; } = new List<FilterConditions>();
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public bool FilterOperation(DetectionResultDetail recongnitionResult)
|
|
||||||
{
|
|
||||||
return FilterConditionsCollection.All(u =>
|
|
||||||
{
|
|
||||||
return u.FilterConditionCollection.Any(c =>
|
|
||||||
{
|
|
||||||
double compareValue = 0;
|
|
||||||
|
|
||||||
switch (c.FilterPropperty)
|
|
||||||
{
|
|
||||||
case DetectionFilterProperty.Width:
|
|
||||||
compareValue = recongnitionResult.Rect.Width;
|
|
||||||
break;
|
|
||||||
case DetectionFilterProperty.Height:
|
|
||||||
compareValue = recongnitionResult.Rect.Height;
|
|
||||||
break;
|
|
||||||
case DetectionFilterProperty.Area:
|
|
||||||
compareValue = recongnitionResult.Area;
|
|
||||||
break;
|
|
||||||
case DetectionFilterProperty.Score:
|
|
||||||
compareValue = recongnitionResult.Score;
|
|
||||||
break;
|
|
||||||
//case RecongnitionTargetFilterProperty.Uncertainty:
|
|
||||||
// compareValue = 0;
|
|
||||||
// //defect.Uncertainty;
|
|
||||||
// break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return compareValue >= c.MinValue && compareValue <= c.MaxValue;
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class FilterConditions //: IComplexDisplay
|
|
||||||
{
|
|
||||||
[Category("过滤条件")]
|
|
||||||
[DisplayName("过滤条件集合")]
|
|
||||||
[Description("过滤条件集合,集合之间为“或”关系")]
|
|
||||||
//[TypeConverter(typeof(CollectionCountConvert))]
|
|
||||||
//[Editor(typeof(ComplexCollectionEditor<FilterCondition>), typeof(UITypeEditor))]
|
|
||||||
public List<FilterCondition> FilterConditionCollection { get; set; } = new List<FilterCondition>();
|
|
||||||
|
|
||||||
//public string GetDisplayText()
|
|
||||||
//{
|
|
||||||
// if (FilterConditionCollection.Count == 0)
|
|
||||||
// {
|
|
||||||
// return "空";
|
|
||||||
// }
|
|
||||||
// else
|
|
||||||
// {
|
|
||||||
// var desc = string.Join(" OR ", FilterConditionCollection.Select(u => u.GetDisplayText()));
|
|
||||||
|
|
||||||
// if (FilterConditionCollection.Count > 1)
|
|
||||||
// {
|
|
||||||
// desc = $"({desc})";
|
|
||||||
// }
|
|
||||||
|
|
||||||
// return desc;
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class FilterCondition //: IComplexDisplay
|
|
||||||
{
|
|
||||||
[Category("识别目标属性")]
|
|
||||||
[DisplayName("过滤属性")]
|
|
||||||
[Description("识别目标过滤针对的属性")]
|
|
||||||
//[TypeConverter(typeof(EnumDescriptionConverter<DetectionFilterProperty>))]
|
|
||||||
public DetectionFilterProperty FilterPropperty { get; set; } = DetectionFilterProperty.Width;
|
|
||||||
|
|
||||||
[Category("过滤值")]
|
|
||||||
[DisplayName("最小值")]
|
|
||||||
[Description("最小值")]
|
|
||||||
public double MinValue { get; set; } = 1;
|
|
||||||
|
|
||||||
[Category("过滤值")]
|
|
||||||
[DisplayName("最大值")]
|
|
||||||
[Description("最大值")]
|
|
||||||
public double MaxValue { get; set; } = 99999999;
|
|
||||||
|
|
||||||
//public string GetDisplayText()
|
|
||||||
//{
|
|
||||||
// return $"{FilterPropperty.GetEnumDescription()}:{MinValue}-{MaxValue}";
|
|
||||||
//}
|
|
||||||
}
|
|
||||||
|
|
||||||
public enum DetectionFilterProperty
|
|
||||||
{
|
|
||||||
[Description("宽度")]
|
|
||||||
Width = 1,
|
|
||||||
[Description("高度")]
|
|
||||||
Height = 2,
|
|
||||||
[Description("面积")]
|
|
||||||
Area = 3,
|
|
||||||
[Description("得分")]
|
|
||||||
Score = 4,
|
|
||||||
//[Description("不确定性")]
|
|
||||||
//Uncertainty = 5,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
10
DH.Devices.Vision/GlobalSuppressions.cs
Normal file
10
DH.Devices.Vision/GlobalSuppressions.cs
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
// This file is used by Code Analysis to maintain SuppressMessage
|
||||||
|
// attributes that are applied to this project.
|
||||||
|
// Project-level suppressions either have no target or are given
|
||||||
|
// a specific target and scoped to a namespace, type, member, etc.
|
||||||
|
|
||||||
|
using System.Diagnostics.CodeAnalysis;
|
||||||
|
|
||||||
|
[assembly: SuppressMessage("Usage", "CA2200:再次引发以保留堆栈详细信息", Justification = "<挂起>", Scope = "member", Target = "~M:DH.Devices.Vision.SimboDetection.Load(DH.Devices.Vision.MLInit)~System.Boolean")]
|
||||||
|
[assembly: SuppressMessage("Usage", "CA2200:再次引发以保留堆栈详细信息", Justification = "<挂起>", Scope = "member", Target = "~M:DH.Devices.Vision.SimboInstanceSegmentation.Load(DH.Devices.Vision.MLInit)~System.Boolean")]
|
||||||
|
[assembly: SuppressMessage("Usage", "CA2200:再次引发以保留堆栈详细信息", Justification = "<挂起>", Scope = "member", Target = "~M:DH.Devices.Vision.SimboObjectDetection.Load(DH.Devices.Vision.MLInit)~System.Boolean")]
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
#define USE_MULTI_THREAD
|
//#define USE_MULTI_THREAD
|
||||||
|
|
||||||
using OpenCvSharp;
|
using OpenCvSharp;
|
||||||
using OpenCvSharp.Extensions;
|
using OpenCvSharp.Extensions;
|
||||||
@@ -13,6 +13,7 @@ using System.Threading.Tasks;
|
|||||||
using System.Security.Cryptography.Xml;
|
using System.Security.Cryptography.Xml;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
|
using DH.Commons.Base;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -103,14 +104,18 @@ namespace DH.Devices.Vision
|
|||||||
// json = "{\"FastDetResult\":[{\"cls_id\":0,\"cls\":\"liewen\",\"fScore\":0.654843,\"rect\":[175,99,110,594]},{\"cls_id\":0,\"cls\":\"liewen\",\"fScore\":0.654589,\"rect\":[2608,19,104,661]},{\"cls_id\":0,\"cls\":\"liewen\",\"fScore\":0.654285,\"rect\":[1275,19,104,662]},{\"cls_id\":0,\"cls\":\"liewen\",\"fScore\":0.620762,\"rect\":[1510,95,107,600]},{\"cls_id\":0,\"cls\":\"liewen\",\"fScore\":0.617812,\"rect\":[2844,93,106,602]}]}";
|
// json = "{\"FastDetResult\":[{\"cls_id\":0,\"cls\":\"liewen\",\"fScore\":0.654843,\"rect\":[175,99,110,594]},{\"cls_id\":0,\"cls\":\"liewen\",\"fScore\":0.654589,\"rect\":[2608,19,104,661]},{\"cls_id\":0,\"cls\":\"liewen\",\"fScore\":0.654285,\"rect\":[1275,19,104,662]},{\"cls_id\":0,\"cls\":\"liewen\",\"fScore\":0.620762,\"rect\":[1510,95,107,600]},{\"cls_id\":0,\"cls\":\"liewen\",\"fScore\":0.617812,\"rect\":[2844,93,106,602]}]}";
|
||||||
//
|
//
|
||||||
Console.WriteLine("检测结果JSON:" + json);
|
Console.WriteLine("检测结果JSON:" + json);
|
||||||
|
|
||||||
HYoloResult detResult = JsonConvert.DeserializeObject<HYoloResult>(json);
|
HYoloResult detResult = JsonConvert.DeserializeObject<HYoloResult>(json);
|
||||||
|
|
||||||
if (detResult == null)
|
if (detResult == null)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int iNum = detResult.HYolo.Count;
|
int iNum = detResult.HYolo.Count;
|
||||||
|
|
||||||
int IokNum = 0;
|
int IokNum = 0;
|
||||||
|
|
||||||
for (int ix = 0; ix < iNum; ix++)
|
for (int ix = 0; ix < iNum; ix++)
|
||||||
{
|
{
|
||||||
var det = detResult.HYolo[ix];
|
var det = detResult.HYolo[ix];
|
||||||
@@ -228,15 +233,20 @@ namespace DH.Devices.Vision
|
|||||||
{
|
{
|
||||||
|
|
||||||
originMat?.Dispose();
|
originMat?.Dispose();
|
||||||
|
#pragma warning disable CS8600 // 将 null 字面量或可能为 null 的值转换为非 null 类型。
|
||||||
originMat = null;
|
originMat = null;
|
||||||
|
#pragma warning restore CS8600 // 将 null 字面量或可能为 null 的值转换为非 null 类型。
|
||||||
//maskMat?.Dispose();
|
//maskMat?.Dispose();
|
||||||
// maskMat = null;
|
// maskMat = null;
|
||||||
detectMat?.Dispose();
|
detectMat?.Dispose();
|
||||||
|
#pragma warning disable CS8600 // 将 null 字面量或可能为 null 的值转换为非 null 类型。
|
||||||
detectMat = null;
|
detectMat = null;
|
||||||
|
#pragma warning restore CS8600 // 将 null 字面量或可能为 null 的值转换为非 null 类型。
|
||||||
// maskWeighted?.Dispose();
|
// maskWeighted?.Dispose();
|
||||||
// maskWeighted = null;
|
// maskWeighted = null;
|
||||||
// GC.Collect();
|
// GC.Collect();
|
||||||
}
|
}
|
||||||
|
#pragma warning restore CS0168 // 声明了变量,但从未使用过
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ using System.Threading;
|
|||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
|
using DH.Commons.Base;
|
||||||
|
|
||||||
|
|
||||||
namespace DH.Devices.Vision
|
namespace DH.Devices.Vision
|
||||||
@@ -126,14 +127,18 @@ namespace DH.Devices.Vision
|
|||||||
// json = "{\"FastDetResult\":[{\"cls_id\":0,\"cls\":\"liewen\",\"fScore\":0.654843,\"rect\":[175,99,110,594]},{\"cls_id\":0,\"cls\":\"liewen\",\"fScore\":0.654589,\"rect\":[2608,19,104,661]},{\"cls_id\":0,\"cls\":\"liewen\",\"fScore\":0.654285,\"rect\":[1275,19,104,662]},{\"cls_id\":0,\"cls\":\"liewen\",\"fScore\":0.620762,\"rect\":[1510,95,107,600]},{\"cls_id\":0,\"cls\":\"liewen\",\"fScore\":0.617812,\"rect\":[2844,93,106,602]}]}";
|
// json = "{\"FastDetResult\":[{\"cls_id\":0,\"cls\":\"liewen\",\"fScore\":0.654843,\"rect\":[175,99,110,594]},{\"cls_id\":0,\"cls\":\"liewen\",\"fScore\":0.654589,\"rect\":[2608,19,104,661]},{\"cls_id\":0,\"cls\":\"liewen\",\"fScore\":0.654285,\"rect\":[1275,19,104,662]},{\"cls_id\":0,\"cls\":\"liewen\",\"fScore\":0.620762,\"rect\":[1510,95,107,600]},{\"cls_id\":0,\"cls\":\"liewen\",\"fScore\":0.617812,\"rect\":[2844,93,106,602]}]}";
|
||||||
//
|
//
|
||||||
Console.WriteLine("检测结果JSON:" + json);
|
Console.WriteLine("检测结果JSON:" + json);
|
||||||
|
#pragma warning disable CS8600 // 将 null 字面量或可能为 null 的值转换为非 null 类型。
|
||||||
SegResult detResult = JsonConvert.DeserializeObject<SegResult>(json);
|
SegResult detResult = JsonConvert.DeserializeObject<SegResult>(json);
|
||||||
|
#pragma warning restore CS8600 // 将 null 字面量或可能为 null 的值转换为非 null 类型。
|
||||||
if (detResult == null)
|
if (detResult == null)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int iNum = detResult.SegmentResult.Count;
|
int iNum = detResult.SegmentResult.Count;
|
||||||
|
#pragma warning disable CS0219 // 变量已被赋值,但从未使用过它的值
|
||||||
int IokNum = 0;
|
int IokNum = 0;
|
||||||
|
#pragma warning restore CS0219 // 变量已被赋值,但从未使用过它的值
|
||||||
for (int ix = 0; ix < iNum; ix++)
|
for (int ix = 0; ix < iNum; ix++)
|
||||||
{
|
{
|
||||||
var det = detResult.SegmentResult[ix];
|
var det = detResult.SegmentResult[ix];
|
||||||
@@ -166,6 +171,7 @@ namespace DH.Devices.Vision
|
|||||||
Mat originMat = new Mat();
|
Mat originMat = new Mat();
|
||||||
Mat detectMat = new Mat();
|
Mat detectMat = new Mat();
|
||||||
|
|
||||||
|
#pragma warning disable CS0168 // 声明了变量,但从未使用过
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (req.mImage == null)
|
if (req.mImage == null)
|
||||||
@@ -253,11 +259,14 @@ namespace DH.Devices.Vision
|
|||||||
{
|
{
|
||||||
|
|
||||||
originMat?.Dispose();
|
originMat?.Dispose();
|
||||||
|
#pragma warning disable CS8600 // 将 null 字面量或可能为 null 的值转换为非 null 类型。
|
||||||
originMat = null;
|
originMat = null;
|
||||||
|
#pragma warning restore CS8600 // 将 null 字面量或可能为 null 的值转换为非 null 类型。
|
||||||
|
|
||||||
|
|
||||||
// GC.Collect();
|
// GC.Collect();
|
||||||
}
|
}
|
||||||
|
#pragma warning restore CS0168 // 声明了变量,但从未使用过
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ using System.Threading.Tasks;
|
|||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using System.Xml;
|
using System.Xml;
|
||||||
|
using DH.Commons.Base;
|
||||||
|
|
||||||
|
|
||||||
namespace DH.Devices.Vision
|
namespace DH.Devices.Vision
|
||||||
@@ -135,6 +136,7 @@ namespace DH.Devices.Vision
|
|||||||
// json = "{\"FastDetResult\":[{\"cls_id\":0,\"cls\":\"liewen\",\"fScore\":0.654843,\"rect\":[175,99,110,594]},{\"cls_id\":0,\"cls\":\"liewen\",\"fScore\":0.654589,\"rect\":[2608,19,104,661]},{\"cls_id\":0,\"cls\":\"liewen\",\"fScore\":0.654285,\"rect\":[1275,19,104,662]},{\"cls_id\":0,\"cls\":\"liewen\",\"fScore\":0.620762,\"rect\":[1510,95,107,600]},{\"cls_id\":0,\"cls\":\"liewen\",\"fScore\":0.617812,\"rect\":[2844,93,106,602]}]}";
|
// json = "{\"FastDetResult\":[{\"cls_id\":0,\"cls\":\"liewen\",\"fScore\":0.654843,\"rect\":[175,99,110,594]},{\"cls_id\":0,\"cls\":\"liewen\",\"fScore\":0.654589,\"rect\":[2608,19,104,661]},{\"cls_id\":0,\"cls\":\"liewen\",\"fScore\":0.654285,\"rect\":[1275,19,104,662]},{\"cls_id\":0,\"cls\":\"liewen\",\"fScore\":0.620762,\"rect\":[1510,95,107,600]},{\"cls_id\":0,\"cls\":\"liewen\",\"fScore\":0.617812,\"rect\":[2844,93,106,602]}]}";
|
||||||
//
|
//
|
||||||
Console.WriteLine("检测结果JSON:" + json);
|
Console.WriteLine("检测结果JSON:" + json);
|
||||||
|
|
||||||
SegResult detResult = JsonConvert.DeserializeObject<SegResult>(json);
|
SegResult detResult = JsonConvert.DeserializeObject<SegResult>(json);
|
||||||
if (detResult == null)
|
if (detResult == null)
|
||||||
{
|
{
|
||||||
@@ -262,20 +264,24 @@ namespace DH.Devices.Vision
|
|||||||
// 释放 Mat 资源
|
// 释放 Mat 资源
|
||||||
if (detectMat != null)
|
if (detectMat != null)
|
||||||
{
|
{
|
||||||
detectMat.Dispose();
|
|
||||||
detectMat = null;
|
detectMat = null;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (originMat != null)
|
if (originMat != null)
|
||||||
{
|
{
|
||||||
originMat.Dispose();
|
originMat.Dispose();
|
||||||
|
|
||||||
originMat = null;
|
originMat = null;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// GC.Collect();
|
// GC.Collect();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -1,9 +1,14 @@
|
|||||||
|
using AntdUI;
|
||||||
|
using DH.Commons.Base;
|
||||||
|
using DH.Commons.Enums;
|
||||||
using OpenCvSharp;
|
using OpenCvSharp;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.ComponentModel;
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Xml.Linq;
|
||||||
|
using static System.ComponentModel.Design.ObjectSelectorEditor;
|
||||||
|
|
||||||
namespace DH.Devices.Vision
|
namespace DH.Devices.Vision
|
||||||
{
|
{
|
||||||
@@ -12,7 +17,7 @@ namespace DH.Devices.Vision
|
|||||||
public Mat ColorLut { get; set; }
|
public Mat ColorLut { get; set; }
|
||||||
public byte[] ColorMap { get; set; }
|
public byte[] ColorMap { get; set; }
|
||||||
|
|
||||||
public MLModelType ModelType { get; set; }
|
public ModelType ModelType { get; set; }
|
||||||
|
|
||||||
public IntPtr Model { get; set; }
|
public IntPtr Model { get; set; }
|
||||||
|
|
||||||
@@ -40,7 +45,7 @@ namespace DH.Devices.Vision
|
|||||||
}
|
}
|
||||||
public SimboVisionMLBase()
|
public SimboVisionMLBase()
|
||||||
{
|
{
|
||||||
// ColorMap = OpenCVHelper.GetColorMap(256);//使用3个通道
|
ColorMap = OpenCVHelper.GetColorMap(256);//使用3个通道
|
||||||
// ColorLut = new Mat(1, 256, MatType.CV_8UC3, ColorMap);
|
// ColorLut = new Mat(1, 256, MatType.CV_8UC3, ColorMap);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -54,38 +59,52 @@ namespace DH.Devices.Vision
|
|||||||
// "rect": [421, 823, 6, 8]
|
// "rect": [421, 823, 6, 8]
|
||||||
// }]
|
// }]
|
||||||
//}
|
//}
|
||||||
|
#pragma warning disable CS8618 // 在退出构造函数时,不可为 null 的字段必须包含非 null 值。请考虑声明为可以为 null。
|
||||||
public List<Result> HYolo;
|
public List<Result> HYolo;
|
||||||
|
|
||||||
public class Result
|
public class Result
|
||||||
{
|
{
|
||||||
|
|
||||||
public double fScore;
|
public double fScore;
|
||||||
public int classId;
|
public int classId;
|
||||||
|
#pragma warning disable CS8618 // 在退出构造函数时,不可为 null 的字段必须包含非 null 值。请考虑声明为可以为 null。
|
||||||
public string classname;
|
public string classname;
|
||||||
|
|
||||||
|
|
||||||
//public double area;
|
//public double area;
|
||||||
|
#pragma warning disable CS8618 // 在退出构造函数时,不可为 null 的字段必须包含非 null 值。请考虑声明为可以为 null。
|
||||||
public List<int> rect;
|
public List<int> rect;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
public class SegResult
|
public class SegResult
|
||||||
{
|
{
|
||||||
|
#pragma warning disable CS8618 // 在退出构造函数时,不可为 null 的字段必须包含非 null 值。请考虑声明为可以为 null。
|
||||||
public List<Result> SegmentResult;
|
public List<Result> SegmentResult;
|
||||||
|
|
||||||
public class Result
|
public class Result
|
||||||
{
|
{
|
||||||
|
|
||||||
public double fScore;
|
public double fScore;
|
||||||
public int classId;
|
public int classId;
|
||||||
|
#pragma warning disable CS8618 // 在退出构造函数时,不可为 null 的字段必须包含非 null 值。请考虑声明为可以为 null。
|
||||||
public string classname;
|
public string classname;
|
||||||
|
|
||||||
|
|
||||||
public double area;
|
public double area;
|
||||||
|
#pragma warning disable CS8618 // 在退出构造函数时,不可为 null 的字段必须包含非 null 值。请考虑声明为可以为 null。
|
||||||
public List<int> rect;
|
public List<int> rect;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static class MLGPUEngine
|
public static class MLGPUEngine
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|||||||
41
DH.Devices.Vision/SimboVisionModel.cs
Normal file
41
DH.Devices.Vision/SimboVisionModel.cs
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace DH.Devices.Vision
|
||||||
|
{
|
||||||
|
//工站 模型检测引擎
|
||||||
|
public class SimboStationMLEngineSet
|
||||||
|
{
|
||||||
|
public bool IsUseGPU { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// GPU设备号
|
||||||
|
/// </summary>
|
||||||
|
public int GPUNo { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// CPU线程号
|
||||||
|
/// </summary>
|
||||||
|
public int CPUNo { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// 检测配置ID
|
||||||
|
/// </summary>
|
||||||
|
#pragma warning disable CS8618 // 在退出构造函数时,不可为 null 的字段必须包含非 null 值。请考虑声明为可以为 null。
|
||||||
|
public string DetectionId { get; set; }
|
||||||
|
|
||||||
|
|
||||||
|
#pragma warning disable CS8618 // 在退出构造函数时,不可为 null 的字段必须包含非 null 值。请考虑声明为可以为 null。
|
||||||
|
public string DetectionName { get; set; }
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 深度学习模型
|
||||||
|
/// </summary>
|
||||||
|
#pragma warning disable CS8618 // 在退出构造函数时,不可为 null 的字段必须包含非 null 值。请考虑声明为可以为 null。
|
||||||
|
public SimboVisionMLBase StationMLEngine { get; set; }
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
599
DH.UI.Model.Winform/Canvas.Designer.cs
generated
Normal file
599
DH.UI.Model.Winform/Canvas.Designer.cs
generated
Normal file
@@ -0,0 +1,599 @@
|
|||||||
|
namespace DH.UI.Model.Winform
|
||||||
|
{
|
||||||
|
partial class Canvas
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 必需的设计器变量。
|
||||||
|
/// </summary>
|
||||||
|
private System.ComponentModel.IContainer components = null;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 清理所有正在使用的资源。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="disposing">如果应释放托管资源,为 true;否则为 false。</param>
|
||||||
|
protected override void Dispose(bool disposing)
|
||||||
|
{
|
||||||
|
if (disposing && (components != null))
|
||||||
|
{
|
||||||
|
components.Dispose();
|
||||||
|
}
|
||||||
|
base.Dispose(disposing);
|
||||||
|
}
|
||||||
|
|
||||||
|
#region 组件设计器生成的代码
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 设计器支持所需的方法 - 不要修改
|
||||||
|
/// 使用代码编辑器修改此方法的内容。
|
||||||
|
/// </summary>
|
||||||
|
private void InitializeComponent()
|
||||||
|
{
|
||||||
|
this.components = new System.ComponentModel.Container();
|
||||||
|
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(Canvas));
|
||||||
|
this.ctmsElements = new System.Windows.Forms.ContextMenuStrip(this.components);
|
||||||
|
this.tsmiResort = new System.Windows.Forms.ToolStripMenuItem();
|
||||||
|
this.tsmiInitialState = new System.Windows.Forms.ToolStripMenuItem();
|
||||||
|
this.tsmiClearStandardValue = new System.Windows.Forms.ToolStripMenuItem();
|
||||||
|
this.tsmiClearActualValue = new System.Windows.Forms.ToolStripMenuItem();
|
||||||
|
this.ctmsKeepElements = new System.Windows.Forms.ContextMenuStrip(this.components);
|
||||||
|
this.tsmiUnselectElements = new System.Windows.Forms.ToolStripMenuItem();
|
||||||
|
this.tsmiKeepSelected = new System.Windows.Forms.ToolStripMenuItem();
|
||||||
|
this.tsmiKeepUnselected = new System.Windows.Forms.ToolStripMenuItem();
|
||||||
|
this.BottomToolStripPanel = new System.Windows.Forms.ToolStripPanel();
|
||||||
|
this.TopToolStripPanel = new System.Windows.Forms.ToolStripPanel();
|
||||||
|
this.RightToolStripPanel = new System.Windows.Forms.ToolStripPanel();
|
||||||
|
this.LeftToolStripPanel = new System.Windows.Forms.ToolStripPanel();
|
||||||
|
this.ContentPanel = new System.Windows.Forms.ToolStripContentPanel();
|
||||||
|
this.scMain = new System.Windows.Forms.SplitContainer();
|
||||||
|
this.tsROIs = new System.Windows.Forms.ToolStrip();
|
||||||
|
this.tsTool = new System.Windows.Forms.ToolStrip();
|
||||||
|
this.tsBtnLoadImage = new System.Windows.Forms.ToolStripButton();
|
||||||
|
this.tsBtnSaveImage = new System.Windows.Forms.ToolStripButton();
|
||||||
|
this.tsBtnSaveImageWithElements = new System.Windows.Forms.ToolStripButton();
|
||||||
|
this.toolStripSeparator4 = new System.Windows.Forms.ToolStripSeparator();
|
||||||
|
this.tsBtnMapSize = new System.Windows.Forms.ToolStripButton();
|
||||||
|
this.tsBtnScreenSize = new System.Windows.Forms.ToolStripButton();
|
||||||
|
this.toolStripSeparator1 = new System.Windows.Forms.ToolStripSeparator();
|
||||||
|
this.tsBtnModeNormal = new System.Windows.Forms.ToolStripButton();
|
||||||
|
this.tsBtnModeSelection = new System.Windows.Forms.ToolStripButton();
|
||||||
|
this.toolStripSeparator2 = new System.Windows.Forms.ToolStripSeparator();
|
||||||
|
this.splitContainer1 = new System.Windows.Forms.SplitContainer();
|
||||||
|
this.chkShowChecked = new System.Windows.Forms.CheckBox();
|
||||||
|
this.dgElements = new System.Windows.Forms.DataGridView();
|
||||||
|
this.colEnableState = new System.Windows.Forms.DataGridViewCheckBoxColumn();
|
||||||
|
this.colId = new System.Windows.Forms.DataGridViewTextBoxColumn();
|
||||||
|
this.colIndex = new System.Windows.Forms.DataGridViewTextBoxColumn();
|
||||||
|
this.colName = new System.Windows.Forms.DataGridViewTextBoxColumn();
|
||||||
|
this.propGridElement = new System.Windows.Forms.PropertyGrid();
|
||||||
|
this.miniToolStrip = new System.Windows.Forms.ToolStrip();
|
||||||
|
this.stsStatus = new System.Windows.Forms.StatusStrip();
|
||||||
|
this.tsslLocation = new System.Windows.Forms.ToolStripStatusLabel();
|
||||||
|
this.tsslMouseState = new System.Windows.Forms.ToolStripStatusLabel();
|
||||||
|
this.dataGridViewCheckBoxColumn1 = new System.Windows.Forms.DataGridViewCheckBoxColumn();
|
||||||
|
this.dataGridViewTextBoxColumn1 = new System.Windows.Forms.DataGridViewTextBoxColumn();
|
||||||
|
this.dataGridViewTextBoxColumn2 = new System.Windows.Forms.DataGridViewTextBoxColumn();
|
||||||
|
this.dataGridViewTextBoxColumn3 = new System.Windows.Forms.DataGridViewTextBoxColumn();
|
||||||
|
this.ctmsElements.SuspendLayout();
|
||||||
|
this.ctmsKeepElements.SuspendLayout();
|
||||||
|
((System.ComponentModel.ISupportInitialize)(this.scMain)).BeginInit();
|
||||||
|
this.scMain.Panel1.SuspendLayout();
|
||||||
|
this.scMain.Panel2.SuspendLayout();
|
||||||
|
this.scMain.SuspendLayout();
|
||||||
|
this.tsTool.SuspendLayout();
|
||||||
|
((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).BeginInit();
|
||||||
|
this.splitContainer1.Panel1.SuspendLayout();
|
||||||
|
this.splitContainer1.Panel2.SuspendLayout();
|
||||||
|
this.splitContainer1.SuspendLayout();
|
||||||
|
((System.ComponentModel.ISupportInitialize)(this.dgElements)).BeginInit();
|
||||||
|
this.stsStatus.SuspendLayout();
|
||||||
|
this.SuspendLayout();
|
||||||
|
//
|
||||||
|
// ctmsElements
|
||||||
|
//
|
||||||
|
this.ctmsElements.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
|
||||||
|
this.tsmiResort,
|
||||||
|
this.tsmiInitialState,
|
||||||
|
this.tsmiClearStandardValue,
|
||||||
|
this.tsmiClearActualValue});
|
||||||
|
this.ctmsElements.Name = "ctmsElements";
|
||||||
|
this.ctmsElements.Size = new System.Drawing.Size(137, 92);
|
||||||
|
//
|
||||||
|
// tsmiResort
|
||||||
|
//
|
||||||
|
this.tsmiResort.Name = "tsmiResort";
|
||||||
|
this.tsmiResort.Size = new System.Drawing.Size(136, 22);
|
||||||
|
this.tsmiResort.Text = "重新排序";
|
||||||
|
this.tsmiResort.Click += new System.EventHandler(this.tsmiResort_Click);
|
||||||
|
//
|
||||||
|
// tsmiInitialState
|
||||||
|
//
|
||||||
|
this.tsmiInitialState.Name = "tsmiInitialState";
|
||||||
|
this.tsmiInitialState.Size = new System.Drawing.Size(136, 22);
|
||||||
|
this.tsmiInitialState.Text = "初始化";
|
||||||
|
this.tsmiInitialState.Click += new System.EventHandler(this.tsmiInitialState_Click);
|
||||||
|
//
|
||||||
|
// tsmiClearStandardValue
|
||||||
|
//
|
||||||
|
this.tsmiClearStandardValue.Name = "tsmiClearStandardValue";
|
||||||
|
this.tsmiClearStandardValue.Size = new System.Drawing.Size(136, 22);
|
||||||
|
this.tsmiClearStandardValue.Text = "清空标准值";
|
||||||
|
this.tsmiClearStandardValue.Click += new System.EventHandler(this.tsmiClearStandardValue_Click);
|
||||||
|
//
|
||||||
|
// tsmiClearActualValue
|
||||||
|
//
|
||||||
|
this.tsmiClearActualValue.Name = "tsmiClearActualValue";
|
||||||
|
this.tsmiClearActualValue.Size = new System.Drawing.Size(136, 22);
|
||||||
|
this.tsmiClearActualValue.Text = "清空测量值";
|
||||||
|
this.tsmiClearActualValue.Click += new System.EventHandler(this.tsmiClearActualValue_Click);
|
||||||
|
//
|
||||||
|
// ctmsKeepElements
|
||||||
|
//
|
||||||
|
this.ctmsKeepElements.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
|
||||||
|
this.tsmiUnselectElements,
|
||||||
|
this.tsmiKeepSelected,
|
||||||
|
this.tsmiKeepUnselected});
|
||||||
|
this.ctmsKeepElements.Name = "ctmsKeepElements";
|
||||||
|
this.ctmsKeepElements.Size = new System.Drawing.Size(173, 70);
|
||||||
|
//
|
||||||
|
// tsmiUnselectElements
|
||||||
|
//
|
||||||
|
this.tsmiUnselectElements.Name = "tsmiUnselectElements";
|
||||||
|
this.tsmiUnselectElements.Size = new System.Drawing.Size(172, 22);
|
||||||
|
this.tsmiUnselectElements.Text = "取消全部基元选择";
|
||||||
|
this.tsmiUnselectElements.Click += new System.EventHandler(this.tsmiUnselectElements_Click);
|
||||||
|
//
|
||||||
|
// tsmiKeepSelected
|
||||||
|
//
|
||||||
|
this.tsmiKeepSelected.Name = "tsmiKeepSelected";
|
||||||
|
this.tsmiKeepSelected.Size = new System.Drawing.Size(172, 22);
|
||||||
|
this.tsmiKeepSelected.Text = "保留选中的基元";
|
||||||
|
this.tsmiKeepSelected.Click += new System.EventHandler(this.tsmiKeepSelected_Click);
|
||||||
|
//
|
||||||
|
// tsmiKeepUnselected
|
||||||
|
//
|
||||||
|
this.tsmiKeepUnselected.Name = "tsmiKeepUnselected";
|
||||||
|
this.tsmiKeepUnselected.Size = new System.Drawing.Size(172, 22);
|
||||||
|
this.tsmiKeepUnselected.Text = "保留未选中的基元";
|
||||||
|
this.tsmiKeepUnselected.Click += new System.EventHandler(this.tsmiKeepUnselected_Click);
|
||||||
|
//
|
||||||
|
// BottomToolStripPanel
|
||||||
|
//
|
||||||
|
this.BottomToolStripPanel.Location = new System.Drawing.Point(0, 0);
|
||||||
|
this.BottomToolStripPanel.Name = "BottomToolStripPanel";
|
||||||
|
this.BottomToolStripPanel.Orientation = System.Windows.Forms.Orientation.Horizontal;
|
||||||
|
this.BottomToolStripPanel.RowMargin = new System.Windows.Forms.Padding(3, 0, 0, 0);
|
||||||
|
this.BottomToolStripPanel.Size = new System.Drawing.Size(0, 0);
|
||||||
|
//
|
||||||
|
// TopToolStripPanel
|
||||||
|
//
|
||||||
|
this.TopToolStripPanel.Location = new System.Drawing.Point(0, 0);
|
||||||
|
this.TopToolStripPanel.Name = "TopToolStripPanel";
|
||||||
|
this.TopToolStripPanel.Orientation = System.Windows.Forms.Orientation.Horizontal;
|
||||||
|
this.TopToolStripPanel.RowMargin = new System.Windows.Forms.Padding(3, 0, 0, 0);
|
||||||
|
this.TopToolStripPanel.Size = new System.Drawing.Size(0, 0);
|
||||||
|
//
|
||||||
|
// RightToolStripPanel
|
||||||
|
//
|
||||||
|
this.RightToolStripPanel.Location = new System.Drawing.Point(0, 0);
|
||||||
|
this.RightToolStripPanel.Name = "RightToolStripPanel";
|
||||||
|
this.RightToolStripPanel.Orientation = System.Windows.Forms.Orientation.Horizontal;
|
||||||
|
this.RightToolStripPanel.RowMargin = new System.Windows.Forms.Padding(3, 0, 0, 0);
|
||||||
|
this.RightToolStripPanel.Size = new System.Drawing.Size(0, 0);
|
||||||
|
//
|
||||||
|
// LeftToolStripPanel
|
||||||
|
//
|
||||||
|
this.LeftToolStripPanel.Location = new System.Drawing.Point(0, 0);
|
||||||
|
this.LeftToolStripPanel.Name = "LeftToolStripPanel";
|
||||||
|
this.LeftToolStripPanel.Orientation = System.Windows.Forms.Orientation.Horizontal;
|
||||||
|
this.LeftToolStripPanel.RowMargin = new System.Windows.Forms.Padding(3, 0, 0, 0);
|
||||||
|
this.LeftToolStripPanel.Size = new System.Drawing.Size(0, 0);
|
||||||
|
//
|
||||||
|
// ContentPanel
|
||||||
|
//
|
||||||
|
this.ContentPanel.Size = new System.Drawing.Size(610, 417);
|
||||||
|
//
|
||||||
|
// scMain
|
||||||
|
//
|
||||||
|
this.scMain.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||||
|
this.scMain.FixedPanel = System.Windows.Forms.FixedPanel.Panel2;
|
||||||
|
this.scMain.Location = new System.Drawing.Point(0, 0);
|
||||||
|
this.scMain.Name = "scMain";
|
||||||
|
//
|
||||||
|
// scMain.Panel1
|
||||||
|
//
|
||||||
|
this.scMain.Panel1.Controls.Add(this.tsROIs);
|
||||||
|
this.scMain.Panel1.Controls.Add(this.tsTool);
|
||||||
|
//
|
||||||
|
// scMain.Panel2
|
||||||
|
//
|
||||||
|
this.scMain.Panel2.Controls.Add(this.splitContainer1);
|
||||||
|
this.scMain.Size = new System.Drawing.Size(635, 467);
|
||||||
|
this.scMain.SplitterDistance = 399;
|
||||||
|
this.scMain.TabIndex = 4;
|
||||||
|
//
|
||||||
|
// tsROIs
|
||||||
|
//
|
||||||
|
this.tsROIs.Location = new System.Drawing.Point(29, 0);
|
||||||
|
this.tsROIs.Name = "tsROIs";
|
||||||
|
this.tsROIs.Size = new System.Drawing.Size(370, 25);
|
||||||
|
this.tsROIs.TabIndex = 2;
|
||||||
|
this.tsROIs.Text = "toolStrip1";
|
||||||
|
this.tsROIs.Visible = false;
|
||||||
|
//
|
||||||
|
// tsTool
|
||||||
|
//
|
||||||
|
this.tsTool.Dock = System.Windows.Forms.DockStyle.Left;
|
||||||
|
this.tsTool.GripStyle = System.Windows.Forms.ToolStripGripStyle.Hidden;
|
||||||
|
this.tsTool.ImageScalingSize = new System.Drawing.Size(24, 24);
|
||||||
|
this.tsTool.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
|
||||||
|
this.tsBtnLoadImage,
|
||||||
|
this.tsBtnSaveImage,
|
||||||
|
this.tsBtnSaveImageWithElements,
|
||||||
|
this.toolStripSeparator4,
|
||||||
|
this.tsBtnMapSize,
|
||||||
|
this.tsBtnScreenSize,
|
||||||
|
this.toolStripSeparator1,
|
||||||
|
this.tsBtnModeNormal,
|
||||||
|
this.tsBtnModeSelection,
|
||||||
|
this.toolStripSeparator2});
|
||||||
|
this.tsTool.LayoutStyle = System.Windows.Forms.ToolStripLayoutStyle.VerticalStackWithOverflow;
|
||||||
|
this.tsTool.Location = new System.Drawing.Point(0, 0);
|
||||||
|
this.tsTool.Margin = new System.Windows.Forms.Padding(10, 0, 0, 0);
|
||||||
|
this.tsTool.Name = "tsTool";
|
||||||
|
this.tsTool.Size = new System.Drawing.Size(29, 467);
|
||||||
|
this.tsTool.TabIndex = 1;
|
||||||
|
this.tsTool.Text = "toolStrip1";
|
||||||
|
//
|
||||||
|
// tsBtnLoadImage
|
||||||
|
//
|
||||||
|
this.tsBtnLoadImage.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
|
||||||
|
this.tsBtnLoadImage.Image = ((System.Drawing.Image)(resources.GetObject("tsBtnLoadImage.Image")));
|
||||||
|
this.tsBtnLoadImage.ImageTransparentColor = System.Drawing.Color.Magenta;
|
||||||
|
this.tsBtnLoadImage.Name = "tsBtnLoadImage";
|
||||||
|
this.tsBtnLoadImage.Size = new System.Drawing.Size(26, 28);
|
||||||
|
this.tsBtnLoadImage.Text = "LoadImage";
|
||||||
|
this.tsBtnLoadImage.ToolTipText = "Load Image";
|
||||||
|
this.tsBtnLoadImage.Click += new System.EventHandler(this.tsBtnLoadImage_Click);
|
||||||
|
//
|
||||||
|
// tsBtnSaveImage
|
||||||
|
//
|
||||||
|
this.tsBtnSaveImage.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
|
||||||
|
this.tsBtnSaveImage.Image = ((System.Drawing.Image)(resources.GetObject("tsBtnSaveImage.Image")));
|
||||||
|
this.tsBtnSaveImage.ImageTransparentColor = System.Drawing.Color.Magenta;
|
||||||
|
this.tsBtnSaveImage.Name = "tsBtnSaveImage";
|
||||||
|
this.tsBtnSaveImage.Size = new System.Drawing.Size(26, 28);
|
||||||
|
this.tsBtnSaveImage.Text = "SaveImage";
|
||||||
|
this.tsBtnSaveImage.Click += new System.EventHandler(this.tsBtnSaveImage_Click);
|
||||||
|
//
|
||||||
|
// tsBtnSaveImageWithElements
|
||||||
|
//
|
||||||
|
this.tsBtnSaveImageWithElements.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
|
||||||
|
this.tsBtnSaveImageWithElements.Image = ((System.Drawing.Image)(resources.GetObject("tsBtnSaveImageWithElements.Image")));
|
||||||
|
this.tsBtnSaveImageWithElements.ImageTransparentColor = System.Drawing.Color.Magenta;
|
||||||
|
this.tsBtnSaveImageWithElements.Name = "tsBtnSaveImageWithElements";
|
||||||
|
this.tsBtnSaveImageWithElements.Size = new System.Drawing.Size(26, 28);
|
||||||
|
this.tsBtnSaveImageWithElements.Text = "SaveImageWithElements";
|
||||||
|
this.tsBtnSaveImageWithElements.Click += new System.EventHandler(this.tsBtnSaveImageWithElements_Click);
|
||||||
|
//
|
||||||
|
// toolStripSeparator4
|
||||||
|
//
|
||||||
|
this.toolStripSeparator4.Name = "toolStripSeparator4";
|
||||||
|
this.toolStripSeparator4.Size = new System.Drawing.Size(26, 6);
|
||||||
|
//
|
||||||
|
// tsBtnMapSize
|
||||||
|
//
|
||||||
|
this.tsBtnMapSize.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
|
||||||
|
this.tsBtnMapSize.Image = ((System.Drawing.Image)(resources.GetObject("tsBtnMapSize.Image")));
|
||||||
|
this.tsBtnMapSize.ImageTransparentColor = System.Drawing.Color.Magenta;
|
||||||
|
this.tsBtnMapSize.Name = "tsBtnMapSize";
|
||||||
|
this.tsBtnMapSize.Size = new System.Drawing.Size(26, 28);
|
||||||
|
this.tsBtnMapSize.Text = "Original";
|
||||||
|
this.tsBtnMapSize.ToolTipText = "Map Size";
|
||||||
|
this.tsBtnMapSize.Click += new System.EventHandler(this.tsBtnMapSize_Click);
|
||||||
|
//
|
||||||
|
// tsBtnScreenSize
|
||||||
|
//
|
||||||
|
this.tsBtnScreenSize.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
|
||||||
|
this.tsBtnScreenSize.Image = ((System.Drawing.Image)(resources.GetObject("tsBtnScreenSize.Image")));
|
||||||
|
this.tsBtnScreenSize.ImageTransparentColor = System.Drawing.Color.Magenta;
|
||||||
|
this.tsBtnScreenSize.Name = "tsBtnScreenSize";
|
||||||
|
this.tsBtnScreenSize.Size = new System.Drawing.Size(26, 28);
|
||||||
|
this.tsBtnScreenSize.Text = "toolStripButton2";
|
||||||
|
this.tsBtnScreenSize.ToolTipText = "Screen Size";
|
||||||
|
this.tsBtnScreenSize.Click += new System.EventHandler(this.tsBtnScreenSize_Click);
|
||||||
|
//
|
||||||
|
// toolStripSeparator1
|
||||||
|
//
|
||||||
|
this.toolStripSeparator1.Name = "toolStripSeparator1";
|
||||||
|
this.toolStripSeparator1.Size = new System.Drawing.Size(26, 6);
|
||||||
|
//
|
||||||
|
// tsBtnModeNormal
|
||||||
|
//
|
||||||
|
this.tsBtnModeNormal.CheckOnClick = true;
|
||||||
|
this.tsBtnModeNormal.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
|
||||||
|
this.tsBtnModeNormal.Image = ((System.Drawing.Image)(resources.GetObject("tsBtnModeNormal.Image")));
|
||||||
|
this.tsBtnModeNormal.ImageTransparentColor = System.Drawing.SystemColors.Control;
|
||||||
|
this.tsBtnModeNormal.Name = "tsBtnModeNormal";
|
||||||
|
this.tsBtnModeNormal.Size = new System.Drawing.Size(26, 28);
|
||||||
|
this.tsBtnModeNormal.Text = "Normal Mode";
|
||||||
|
this.tsBtnModeNormal.ToolTipText = "Normal Mode";
|
||||||
|
this.tsBtnModeNormal.CheckedChanged += new System.EventHandler(this.tsBtnModeNormal_CheckedChanged);
|
||||||
|
//
|
||||||
|
// tsBtnModeSelection
|
||||||
|
//
|
||||||
|
this.tsBtnModeSelection.CheckOnClick = true;
|
||||||
|
this.tsBtnModeSelection.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
|
||||||
|
this.tsBtnModeSelection.Image = ((System.Drawing.Image)(resources.GetObject("tsBtnModeSelection.Image")));
|
||||||
|
this.tsBtnModeSelection.ImageTransparentColor = System.Drawing.Color.Magenta;
|
||||||
|
this.tsBtnModeSelection.Name = "tsBtnModeSelection";
|
||||||
|
this.tsBtnModeSelection.Size = new System.Drawing.Size(26, 28);
|
||||||
|
this.tsBtnModeSelection.Text = "Selection Mode";
|
||||||
|
this.tsBtnModeSelection.CheckedChanged += new System.EventHandler(this.tsBtnModeNormal_CheckedChanged);
|
||||||
|
//
|
||||||
|
// toolStripSeparator2
|
||||||
|
//
|
||||||
|
this.toolStripSeparator2.Name = "toolStripSeparator2";
|
||||||
|
this.toolStripSeparator2.Size = new System.Drawing.Size(26, 6);
|
||||||
|
//
|
||||||
|
// splitContainer1
|
||||||
|
//
|
||||||
|
this.splitContainer1.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||||
|
this.splitContainer1.Location = new System.Drawing.Point(0, 0);
|
||||||
|
this.splitContainer1.Name = "splitContainer1";
|
||||||
|
this.splitContainer1.Orientation = System.Windows.Forms.Orientation.Horizontal;
|
||||||
|
//
|
||||||
|
// splitContainer1.Panel1
|
||||||
|
//
|
||||||
|
this.splitContainer1.Panel1.Controls.Add(this.chkShowChecked);
|
||||||
|
this.splitContainer1.Panel1.Controls.Add(this.dgElements);
|
||||||
|
//
|
||||||
|
// splitContainer1.Panel2
|
||||||
|
//
|
||||||
|
this.splitContainer1.Panel2.Controls.Add(this.propGridElement);
|
||||||
|
this.splitContainer1.Size = new System.Drawing.Size(232, 467);
|
||||||
|
this.splitContainer1.SplitterDistance = 215;
|
||||||
|
this.splitContainer1.TabIndex = 2;
|
||||||
|
//
|
||||||
|
// chkShowChecked
|
||||||
|
//
|
||||||
|
this.chkShowChecked.AutoSize = true;
|
||||||
|
this.chkShowChecked.Location = new System.Drawing.Point(14, 8);
|
||||||
|
this.chkShowChecked.Name = "chkShowChecked";
|
||||||
|
this.chkShowChecked.Size = new System.Drawing.Size(110, 17);
|
||||||
|
this.chkShowChecked.TabIndex = 1;
|
||||||
|
this.chkShowChecked.Text = "仅显示选中项目";
|
||||||
|
this.chkShowChecked.UseVisualStyleBackColor = true;
|
||||||
|
this.chkShowChecked.CheckedChanged += new System.EventHandler(this.chkShowChecked_CheckedChanged);
|
||||||
|
//
|
||||||
|
// dgElements
|
||||||
|
//
|
||||||
|
this.dgElements.AllowUserToAddRows = false;
|
||||||
|
this.dgElements.AllowUserToDeleteRows = false;
|
||||||
|
this.dgElements.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
|
||||||
|
| System.Windows.Forms.AnchorStyles.Left)
|
||||||
|
| System.Windows.Forms.AnchorStyles.Right)));
|
||||||
|
this.dgElements.BackgroundColor = System.Drawing.SystemColors.GradientInactiveCaption;
|
||||||
|
this.dgElements.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
|
||||||
|
this.dgElements.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] {
|
||||||
|
this.colEnableState,
|
||||||
|
this.colId,
|
||||||
|
this.colIndex,
|
||||||
|
this.colName});
|
||||||
|
this.dgElements.Location = new System.Drawing.Point(0, 30);
|
||||||
|
this.dgElements.MultiSelect = false;
|
||||||
|
this.dgElements.Name = "dgElements";
|
||||||
|
this.dgElements.RowTemplate.Height = 23;
|
||||||
|
this.dgElements.SelectionMode = System.Windows.Forms.DataGridViewSelectionMode.FullRowSelect;
|
||||||
|
this.dgElements.Size = new System.Drawing.Size(232, 185);
|
||||||
|
this.dgElements.TabIndex = 0;
|
||||||
|
this.dgElements.CellMouseDoubleClick += new System.Windows.Forms.DataGridViewCellMouseEventHandler(this.dgElements_CellMouseDoubleClick);
|
||||||
|
this.dgElements.SelectionChanged += new System.EventHandler(this.dgElements_SelectionChanged);
|
||||||
|
//
|
||||||
|
// colEnableState
|
||||||
|
//
|
||||||
|
this.colEnableState.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.Fill;
|
||||||
|
this.colEnableState.DataPropertyName = "IsEnabled";
|
||||||
|
this.colEnableState.FillWeight = 41.95804F;
|
||||||
|
this.colEnableState.HeaderText = "";
|
||||||
|
this.colEnableState.MinimumWidth = 30;
|
||||||
|
this.colEnableState.Name = "colEnableState";
|
||||||
|
this.colEnableState.Resizable = System.Windows.Forms.DataGridViewTriState.True;
|
||||||
|
//
|
||||||
|
// colId
|
||||||
|
//
|
||||||
|
this.colId.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.Fill;
|
||||||
|
this.colId.DataPropertyName = "ID";
|
||||||
|
this.colId.HeaderText = "ID";
|
||||||
|
this.colId.MinimumWidth = 30;
|
||||||
|
this.colId.Name = "colId";
|
||||||
|
this.colId.ReadOnly = true;
|
||||||
|
this.colId.Visible = false;
|
||||||
|
//
|
||||||
|
// colIndex
|
||||||
|
//
|
||||||
|
this.colIndex.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.DisplayedCells;
|
||||||
|
this.colIndex.DataPropertyName = "Index";
|
||||||
|
this.colIndex.HeaderText = "序号";
|
||||||
|
this.colIndex.MinimumWidth = 40;
|
||||||
|
this.colIndex.Name = "colIndex";
|
||||||
|
this.colIndex.ReadOnly = true;
|
||||||
|
this.colIndex.Width = 56;
|
||||||
|
//
|
||||||
|
// colName
|
||||||
|
//
|
||||||
|
this.colName.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.Fill;
|
||||||
|
this.colName.DataPropertyName = "Name";
|
||||||
|
this.colName.FillWeight = 158.042F;
|
||||||
|
this.colName.HeaderText = "名称";
|
||||||
|
this.colName.MinimumWidth = 60;
|
||||||
|
this.colName.Name = "colName";
|
||||||
|
this.colName.ReadOnly = true;
|
||||||
|
//
|
||||||
|
// propGridElement
|
||||||
|
//
|
||||||
|
this.propGridElement.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||||
|
this.propGridElement.LargeButtons = true;
|
||||||
|
this.propGridElement.LineColor = System.Drawing.SystemColors.ControlDark;
|
||||||
|
this.propGridElement.Location = new System.Drawing.Point(0, 0);
|
||||||
|
this.propGridElement.Margin = new System.Windows.Forms.Padding(3, 3, 3, 50);
|
||||||
|
this.propGridElement.Name = "propGridElement";
|
||||||
|
this.propGridElement.Size = new System.Drawing.Size(232, 248);
|
||||||
|
this.propGridElement.TabIndex = 0;
|
||||||
|
this.propGridElement.ToolbarVisible = false;
|
||||||
|
this.propGridElement.SelectedObjectsChanged += new System.EventHandler(this.propGridElement_SelectedObjectsChanged);
|
||||||
|
//
|
||||||
|
// miniToolStrip
|
||||||
|
//
|
||||||
|
this.miniToolStrip.AccessibleName = "新项选择";
|
||||||
|
this.miniToolStrip.AccessibleRole = System.Windows.Forms.AccessibleRole.ButtonDropDown;
|
||||||
|
this.miniToolStrip.AutoSize = false;
|
||||||
|
this.miniToolStrip.CanOverflow = false;
|
||||||
|
this.miniToolStrip.Dock = System.Windows.Forms.DockStyle.None;
|
||||||
|
this.miniToolStrip.GripStyle = System.Windows.Forms.ToolStripGripStyle.Hidden;
|
||||||
|
this.miniToolStrip.ImageScalingSize = new System.Drawing.Size(24, 24);
|
||||||
|
this.miniToolStrip.LayoutStyle = System.Windows.Forms.ToolStripLayoutStyle.VerticalStackWithOverflow;
|
||||||
|
this.miniToolStrip.Location = new System.Drawing.Point(0, 235);
|
||||||
|
this.miniToolStrip.Margin = new System.Windows.Forms.Padding(10, 0, 0, 0);
|
||||||
|
this.miniToolStrip.Name = "miniToolStrip";
|
||||||
|
this.miniToolStrip.Size = new System.Drawing.Size(29, 237);
|
||||||
|
this.miniToolStrip.TabIndex = 1;
|
||||||
|
//
|
||||||
|
// stsStatus
|
||||||
|
//
|
||||||
|
this.stsStatus.BackColor = System.Drawing.Color.Transparent;
|
||||||
|
this.stsStatus.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
|
||||||
|
this.tsslLocation,
|
||||||
|
this.tsslMouseState});
|
||||||
|
this.stsStatus.LayoutStyle = System.Windows.Forms.ToolStripLayoutStyle.Flow;
|
||||||
|
this.stsStatus.Location = new System.Drawing.Point(0, 445);
|
||||||
|
this.stsStatus.Name = "stsStatus";
|
||||||
|
this.stsStatus.Size = new System.Drawing.Size(635, 22);
|
||||||
|
this.stsStatus.TabIndex = 0;
|
||||||
|
this.stsStatus.Text = "statusStrip1";
|
||||||
|
//
|
||||||
|
// tsslLocation
|
||||||
|
//
|
||||||
|
this.tsslLocation.Name = "tsslLocation";
|
||||||
|
this.tsslLocation.Size = new System.Drawing.Size(24, 17);
|
||||||
|
this.tsslLocation.Text = " ";
|
||||||
|
//
|
||||||
|
// tsslMouseState
|
||||||
|
//
|
||||||
|
this.tsslMouseState.Name = "tsslMouseState";
|
||||||
|
this.tsslMouseState.Size = new System.Drawing.Size(52, 17);
|
||||||
|
this.tsslMouseState.Text = " ";
|
||||||
|
//
|
||||||
|
// dataGridViewCheckBoxColumn1
|
||||||
|
//
|
||||||
|
this.dataGridViewCheckBoxColumn1.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.Fill;
|
||||||
|
this.dataGridViewCheckBoxColumn1.DataPropertyName = "IsEnabled";
|
||||||
|
this.dataGridViewCheckBoxColumn1.FillWeight = 41.95804F;
|
||||||
|
this.dataGridViewCheckBoxColumn1.HeaderText = "";
|
||||||
|
this.dataGridViewCheckBoxColumn1.MinimumWidth = 30;
|
||||||
|
this.dataGridViewCheckBoxColumn1.Name = "dataGridViewCheckBoxColumn1";
|
||||||
|
this.dataGridViewCheckBoxColumn1.Resizable = System.Windows.Forms.DataGridViewTriState.True;
|
||||||
|
//
|
||||||
|
// dataGridViewTextBoxColumn1
|
||||||
|
//
|
||||||
|
this.dataGridViewTextBoxColumn1.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.Fill;
|
||||||
|
this.dataGridViewTextBoxColumn1.DataPropertyName = "Id";
|
||||||
|
this.dataGridViewTextBoxColumn1.HeaderText = "ID";
|
||||||
|
this.dataGridViewTextBoxColumn1.MinimumWidth = 30;
|
||||||
|
this.dataGridViewTextBoxColumn1.Name = "dataGridViewTextBoxColumn1";
|
||||||
|
this.dataGridViewTextBoxColumn1.ReadOnly = true;
|
||||||
|
this.dataGridViewTextBoxColumn1.Visible = false;
|
||||||
|
//
|
||||||
|
// dataGridViewTextBoxColumn2
|
||||||
|
//
|
||||||
|
this.dataGridViewTextBoxColumn2.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.DisplayedCellsExceptHeader;
|
||||||
|
this.dataGridViewTextBoxColumn2.DataPropertyName = "Index";
|
||||||
|
this.dataGridViewTextBoxColumn2.HeaderText = "序号";
|
||||||
|
this.dataGridViewTextBoxColumn2.MinimumWidth = 40;
|
||||||
|
this.dataGridViewTextBoxColumn2.Name = "dataGridViewTextBoxColumn2";
|
||||||
|
this.dataGridViewTextBoxColumn2.ReadOnly = true;
|
||||||
|
//
|
||||||
|
// dataGridViewTextBoxColumn3
|
||||||
|
//
|
||||||
|
this.dataGridViewTextBoxColumn3.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.DisplayedCellsExceptHeader;
|
||||||
|
this.dataGridViewTextBoxColumn3.DataPropertyName = "Name";
|
||||||
|
this.dataGridViewTextBoxColumn3.FillWeight = 158.042F;
|
||||||
|
this.dataGridViewTextBoxColumn3.HeaderText = "名称";
|
||||||
|
this.dataGridViewTextBoxColumn3.MinimumWidth = 80;
|
||||||
|
this.dataGridViewTextBoxColumn3.Name = "dataGridViewTextBoxColumn3";
|
||||||
|
this.dataGridViewTextBoxColumn3.ReadOnly = true;
|
||||||
|
//
|
||||||
|
// Canvas
|
||||||
|
//
|
||||||
|
this.Controls.Add(this.stsStatus);
|
||||||
|
this.Controls.Add(this.scMain);
|
||||||
|
this.Font = new System.Drawing.Font("Tahoma", 11F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.World, ((byte)(134)));
|
||||||
|
this.Name = "Canvas";
|
||||||
|
this.Size = new System.Drawing.Size(635, 467);
|
||||||
|
this.ctmsElements.ResumeLayout(false);
|
||||||
|
this.ctmsKeepElements.ResumeLayout(false);
|
||||||
|
this.scMain.Panel1.ResumeLayout(false);
|
||||||
|
this.scMain.Panel1.PerformLayout();
|
||||||
|
this.scMain.Panel2.ResumeLayout(false);
|
||||||
|
((System.ComponentModel.ISupportInitialize)(this.scMain)).EndInit();
|
||||||
|
this.scMain.ResumeLayout(false);
|
||||||
|
this.tsTool.ResumeLayout(false);
|
||||||
|
this.tsTool.PerformLayout();
|
||||||
|
this.splitContainer1.Panel1.ResumeLayout(false);
|
||||||
|
this.splitContainer1.Panel1.PerformLayout();
|
||||||
|
this.splitContainer1.Panel2.ResumeLayout(false);
|
||||||
|
((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).EndInit();
|
||||||
|
this.splitContainer1.ResumeLayout(false);
|
||||||
|
((System.ComponentModel.ISupportInitialize)(this.dgElements)).EndInit();
|
||||||
|
this.stsStatus.ResumeLayout(false);
|
||||||
|
this.stsStatus.PerformLayout();
|
||||||
|
this.ResumeLayout(false);
|
||||||
|
this.PerformLayout();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
private System.Windows.Forms.DataGridViewTextBoxColumn dataGridViewTextBoxColumn1;
|
||||||
|
private System.Windows.Forms.DataGridViewTextBoxColumn dataGridViewTextBoxColumn2;
|
||||||
|
private System.Windows.Forms.DataGridViewTextBoxColumn dataGridViewTextBoxColumn3;
|
||||||
|
private System.Windows.Forms.ContextMenuStrip ctmsElements;
|
||||||
|
private System.Windows.Forms.ToolStripMenuItem tsmiResort;
|
||||||
|
private System.Windows.Forms.ToolStripMenuItem tsmiInitialState;
|
||||||
|
private System.Windows.Forms.ToolStripMenuItem tsmiClearStandardValue;
|
||||||
|
private System.Windows.Forms.ToolStripMenuItem tsmiClearActualValue;
|
||||||
|
private System.Windows.Forms.DataGridViewCheckBoxColumn dataGridViewCheckBoxColumn1;
|
||||||
|
private System.Windows.Forms.ContextMenuStrip ctmsKeepElements;
|
||||||
|
private System.Windows.Forms.ToolStripMenuItem tsmiKeepSelected;
|
||||||
|
private System.Windows.Forms.ToolStripMenuItem tsmiKeepUnselected;
|
||||||
|
private System.Windows.Forms.ToolStripMenuItem tsmiUnselectElements;
|
||||||
|
private System.Windows.Forms.ToolStripPanel BottomToolStripPanel;
|
||||||
|
private System.Windows.Forms.ToolStripPanel TopToolStripPanel;
|
||||||
|
private System.Windows.Forms.ToolStripPanel RightToolStripPanel;
|
||||||
|
private System.Windows.Forms.ToolStripPanel LeftToolStripPanel;
|
||||||
|
private System.Windows.Forms.ToolStripContentPanel ContentPanel;
|
||||||
|
private System.Windows.Forms.SplitContainer scMain;
|
||||||
|
private System.Windows.Forms.StatusStrip stsStatus;
|
||||||
|
private System.Windows.Forms.ToolStripStatusLabel tsslLocation;
|
||||||
|
private System.Windows.Forms.ToolStripStatusLabel tsslMouseState;
|
||||||
|
private System.Windows.Forms.ToolStrip tsTool;
|
||||||
|
private System.Windows.Forms.ToolStripButton tsBtnLoadImage;
|
||||||
|
private System.Windows.Forms.ToolStripButton tsBtnSaveImage;
|
||||||
|
private System.Windows.Forms.ToolStripButton tsBtnSaveImageWithElements;
|
||||||
|
private System.Windows.Forms.ToolStripSeparator toolStripSeparator4;
|
||||||
|
private System.Windows.Forms.ToolStripButton tsBtnMapSize;
|
||||||
|
private System.Windows.Forms.ToolStripButton tsBtnScreenSize;
|
||||||
|
private System.Windows.Forms.ToolStripSeparator toolStripSeparator1;
|
||||||
|
private System.Windows.Forms.ToolStripButton tsBtnModeNormal;
|
||||||
|
private System.Windows.Forms.ToolStripButton tsBtnModeSelection;
|
||||||
|
private System.Windows.Forms.ToolStripSeparator toolStripSeparator2;
|
||||||
|
private System.Windows.Forms.SplitContainer splitContainer1;
|
||||||
|
private System.Windows.Forms.CheckBox chkShowChecked;
|
||||||
|
private System.Windows.Forms.DataGridView dgElements;
|
||||||
|
private System.Windows.Forms.DataGridViewCheckBoxColumn colEnableState;
|
||||||
|
private System.Windows.Forms.DataGridViewTextBoxColumn colId;
|
||||||
|
private System.Windows.Forms.DataGridViewTextBoxColumn colIndex;
|
||||||
|
private System.Windows.Forms.DataGridViewTextBoxColumn colName;
|
||||||
|
private System.Windows.Forms.PropertyGrid propGridElement;
|
||||||
|
private System.Windows.Forms.ToolStrip miniToolStrip;
|
||||||
|
private System.Windows.Forms.ToolStrip tsROIs;
|
||||||
|
}
|
||||||
|
}
|
||||||
629
DH.UI.Model.Winform/Canvas.cs
Normal file
629
DH.UI.Model.Winform/Canvas.cs
Normal file
@@ -0,0 +1,629 @@
|
|||||||
|
|
||||||
|
using DH.Commons.Enums;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Collections.ObjectModel;
|
||||||
|
using System.ComponentModel;
|
||||||
|
using System.Data;
|
||||||
|
using System.Drawing;
|
||||||
|
using System.Drawing.Drawing2D;
|
||||||
|
using System.Drawing.Imaging;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Windows.Forms;
|
||||||
|
using static DH.Commons.Enums.EnumHelper;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
namespace DH.UI.Model.Winform
|
||||||
|
{
|
||||||
|
public partial class Canvas : UserControl
|
||||||
|
{
|
||||||
|
readonly CanvasImage cvImage = new CanvasImage();
|
||||||
|
|
||||||
|
#region Grid
|
||||||
|
readonly GridCtrl gridCtrl = new GridCtrl();
|
||||||
|
|
||||||
|
private void GridValueChanged(int gridValue)
|
||||||
|
{
|
||||||
|
cvImage.GridValue = gridValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ShowGridChanged(bool isShowGrid)
|
||||||
|
{
|
||||||
|
cvImage.ShowGrid = isShowGrid;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void GridColorChanged(Color obj)
|
||||||
|
{
|
||||||
|
cvImage.Pen_Grid.Color = obj;
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
public Canvas()
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
DoubleBuffered = true;
|
||||||
|
SetStyle(ControlStyles.OptimizedDoubleBuffer |
|
||||||
|
ControlStyles.ResizeRedraw |
|
||||||
|
ControlStyles.AllPaintingInWmPaint, true);
|
||||||
|
|
||||||
|
cvImage.Dock = DockStyle.Fill;
|
||||||
|
scMain.Panel1.Controls.Add(cvImage);
|
||||||
|
|
||||||
|
dgElements.AutoGenerateColumns = false;
|
||||||
|
|
||||||
|
var checkHead = new DataGridViewCheckboxHeaderCell();
|
||||||
|
checkHead.OnCheckBoxClicked += CheckHead_OnCheckBoxClicked;
|
||||||
|
dgElements.Columns[0].HeaderCell = checkHead;
|
||||||
|
dgElements.Columns[0].HeaderCell.Value = string.Empty;
|
||||||
|
|
||||||
|
Elements.CollectionChanged += Elements_CollectionChanged;
|
||||||
|
|
||||||
|
cvImage.OnMouseLocationUpdated = OnMouseLocationUpdated;
|
||||||
|
cvImage.OnMouseStateChanged += OnMouseStateChanged;
|
||||||
|
|
||||||
|
gridCtrl.IsShowGridChanged = ShowGridChanged;
|
||||||
|
gridCtrl.GridValueChanged = GridValueChanged;
|
||||||
|
gridCtrl.GridColorChanged = GridColorChanged;
|
||||||
|
gridCtrl.Padding = new Padding(0, 5, 0, 5);
|
||||||
|
tsTool.Items.Add(new GridCtrlHost(gridCtrl));
|
||||||
|
tsTool.Invalidate();
|
||||||
|
|
||||||
|
_eleCollectionChangedTimer = new System.Threading.Timer(OnElementCollectionChangedBufferTimer, null, -1, -1);
|
||||||
|
|
||||||
|
//tsmiShowStatusBar.Checked = tsmiShowToolBar.Checked = IsShowElementList = IsShowROITool = IsShowStatusBar = IsShowToolBar = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnMouseStateChanged(MouseState ms)
|
||||||
|
{
|
||||||
|
if (ms != MouseState.SelectionZone && ms != MouseState.SelectionZoneDoing)
|
||||||
|
{
|
||||||
|
if (this.IsHandleCreated)
|
||||||
|
{
|
||||||
|
this.Invoke(new Action(() =>
|
||||||
|
{
|
||||||
|
tsBtnModeSelection.Checked = false;
|
||||||
|
tsBtnModeNormal.Checked = true;
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#region 底部状态栏
|
||||||
|
public bool IsShowStatusBar
|
||||||
|
{
|
||||||
|
get => stsStatus.Visible;
|
||||||
|
set => stsStatus.Visible = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnMouseLocationUpdated(Point screenPoint, PointF imagePoint, string colorDesc)
|
||||||
|
{
|
||||||
|
//await Task.Run(() => tsslLocation.Text = $"屏幕坐标X:{screenPoint.X},Y:{screenPoint.Y} 图片坐标X:{imagePoint.X},Y:{imagePoint.Y} 颜色:{colorDesc}");
|
||||||
|
this.Invoke(new Action(() =>
|
||||||
|
{
|
||||||
|
tsslLocation.Text = $"屏幕坐标X:{screenPoint.X},Y:{screenPoint.Y} 图片坐标X:{imagePoint.X.ToString("f2")},Y:{imagePoint.Y.ToString("f2")} 颜色:{colorDesc}";
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
//private void MouseLocationUpdated(Point screenPoint, Point imagePoint, string colorDesc)
|
||||||
|
//{
|
||||||
|
// if (InvokeRequired)
|
||||||
|
// {
|
||||||
|
// Invoke(new Action<Point, Point, string>(MouseLocationUpdated), screenPoint, imagePoint);
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
// {
|
||||||
|
// tsslLocation.Text = $"屏幕坐标X:{screenPoint.X},Y:{screenPoint.Y} 图片坐标X:{imagePoint.X},Y:{imagePoint.Y} 颜色:{colorDesc}";
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region 属性
|
||||||
|
#region CanvasImage相关
|
||||||
|
//private MouseState mouseState = MouseState.Normal;
|
||||||
|
//public MouseState MouseState
|
||||||
|
//{
|
||||||
|
// get
|
||||||
|
// {
|
||||||
|
// return mouseState;
|
||||||
|
// }
|
||||||
|
// set
|
||||||
|
// {
|
||||||
|
// if (mouseState != value)
|
||||||
|
// {
|
||||||
|
// mouseState = value;
|
||||||
|
|
||||||
|
// tsslMouseState.Text = mouseState.ToString();
|
||||||
|
|
||||||
|
// if (mouseState >= MouseState.SelectionZone)
|
||||||
|
// {
|
||||||
|
// tsBtnModeSelection.Checked = true;
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
// {
|
||||||
|
// tsBtnModeNormal.Checked = true;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
|
||||||
|
public string ImageFilePath { get; set; }
|
||||||
|
|
||||||
|
public Bitmap MAP
|
||||||
|
{
|
||||||
|
get => cvImage.MAP;
|
||||||
|
set => cvImage.MAP = value;
|
||||||
|
}
|
||||||
|
public Matrix Matrix
|
||||||
|
{
|
||||||
|
get => cvImage.Matrix;
|
||||||
|
set => cvImage.Matrix = value;
|
||||||
|
}
|
||||||
|
public MouseState MouseState
|
||||||
|
{
|
||||||
|
get => cvImage.MouseState;
|
||||||
|
set => cvImage.MouseState = value;
|
||||||
|
}
|
||||||
|
public ObservableCollection<IShapeElement> Elements
|
||||||
|
{
|
||||||
|
get => cvImage.Elements;
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
private bool isShowElementList = false;
|
||||||
|
public bool IsShowElementList
|
||||||
|
{
|
||||||
|
get => isShowElementList;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
//if (isShowElementList != value)
|
||||||
|
{
|
||||||
|
isShowElementList = value;
|
||||||
|
scMain.Panel2Collapsed = !value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool isShowROITool = false;
|
||||||
|
public bool IsShowROITool
|
||||||
|
{
|
||||||
|
get => isShowROITool;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
tsROIs.Visible = isShowROITool = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region 图片操作
|
||||||
|
/// <summary>
|
||||||
|
/// 载入图片
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="map"></param>
|
||||||
|
public void LoadImage(Bitmap map)
|
||||||
|
{
|
||||||
|
cvImage.LoadImage(map);
|
||||||
|
OnImageChanged?.Invoke();
|
||||||
|
}
|
||||||
|
public void Clear()
|
||||||
|
{
|
||||||
|
cvImage.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 设置图片为原始尺寸
|
||||||
|
/// </summary>
|
||||||
|
public void SetMapSize()
|
||||||
|
{
|
||||||
|
cvImage.SetMapSize();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 设置图片为适配尺寸
|
||||||
|
/// </summary>
|
||||||
|
public void SetScreenSize()
|
||||||
|
{
|
||||||
|
cvImage.SetScreenSize();
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region 基元列表
|
||||||
|
private void chkShowChecked_CheckedChanged(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
dgElements.DataSource = null;
|
||||||
|
|
||||||
|
if (Elements != null && Elements.Count > 0)
|
||||||
|
{
|
||||||
|
if (chkShowChecked.Checked)
|
||||||
|
{
|
||||||
|
dgElements.DataSource = Elements.Where(u => u.IsEnabled && u.IsShowing).ToList();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
dgElements.DataSource = Elements.Where(u => u.IsShowing).ToList();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void CheckHead_OnCheckBoxClicked(object sender, DataGridViewCheckboxHeaderEventArgs e)
|
||||||
|
{
|
||||||
|
//foreach (IShapeElement ele in Elements)
|
||||||
|
//{
|
||||||
|
// ele.IsEnabled = e.CheckedState;
|
||||||
|
//}
|
||||||
|
for (int i = 0; i < Elements.Count; i++)
|
||||||
|
{
|
||||||
|
Elements[i].IsEnabled = e.CheckedState;
|
||||||
|
}
|
||||||
|
OnElementChanged(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void dgElements_SelectionChanged(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
if (dgElements.SelectedRows.Count > 0)
|
||||||
|
{
|
||||||
|
var ele = Elements.FirstOrDefault(u => u.ID == dgElements.SelectedRows[0].Cells["colID"].Value.ToString());
|
||||||
|
propGridElement.SelectedObject = ele;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void dgElements_CellMouseDoubleClick(object sender, DataGridViewCellMouseEventArgs e)
|
||||||
|
{
|
||||||
|
if (dgElements.SelectedRows.Count > 0)
|
||||||
|
{
|
||||||
|
var ele = Elements.FirstOrDefault(u => u.ID == dgElements.SelectedRows[0].Cells["colID"].Value.ToString());
|
||||||
|
|
||||||
|
for (int i = 0; i < Elements.Count; i++)
|
||||||
|
{
|
||||||
|
Elements[i].State = ElementState.Normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
ele.State = ElementState.Selected;
|
||||||
|
|
||||||
|
SetDeviceByElement?.Invoke(ele);
|
||||||
|
|
||||||
|
Invalidate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
System.Threading.Timer _eleCollectionChangedTimer = null;
|
||||||
|
|
||||||
|
private void OnElementCollectionChangedBufferTimer(object state)
|
||||||
|
{
|
||||||
|
OnElementChanged(null);
|
||||||
|
for (int i = 0; i < Elements.Count; i++)
|
||||||
|
{
|
||||||
|
Elements[i].PropertyChanged -= Ele_PropertyChanged;
|
||||||
|
Elements[i].PropertyChanged += Ele_PropertyChanged;
|
||||||
|
}
|
||||||
|
//foreach (IShapeElement ele in Elements)
|
||||||
|
//{
|
||||||
|
// ele.PropertyChanged -= Ele_PropertyChanged;
|
||||||
|
// ele.PropertyChanged += Ele_PropertyChanged;
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Elements_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
|
||||||
|
{
|
||||||
|
//_eleCollectionChangedTimer?.Change(200, -1);
|
||||||
|
OnElementChanged(null);
|
||||||
|
for (int i = 0; i < Elements.Count; i++)
|
||||||
|
{
|
||||||
|
Elements[i].PropertyChanged -= Ele_PropertyChanged;
|
||||||
|
Elements[i].PropertyChanged += Ele_PropertyChanged;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Ele_PropertyChanged(object sender, PropertyChangedEventArgs e)
|
||||||
|
{
|
||||||
|
if (e.PropertyName == "IsEnabled")
|
||||||
|
{
|
||||||
|
OnElementChanged(sender as IShapeElement);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Invoke(new Action(() =>
|
||||||
|
{
|
||||||
|
cvImage.Invalidate();
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnElementChanged(IShapeElement ele)
|
||||||
|
{
|
||||||
|
if (ele != null)
|
||||||
|
OnElementChangedHandle?.Invoke(ele);
|
||||||
|
|
||||||
|
if (InvokeRequired)
|
||||||
|
{
|
||||||
|
Invoke(new Action(() => OnElementChanged(ele)));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (isShowElementList)
|
||||||
|
{
|
||||||
|
dgElements.DataSource = null;
|
||||||
|
if (Elements != null && Elements.Count > 0)
|
||||||
|
{
|
||||||
|
if (chkShowChecked.Checked)
|
||||||
|
{
|
||||||
|
dgElements.DataSource = Elements.ToList().Where(u => u.IsEnabled && u.IsShowing).ToList();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
dgElements.DataSource = Elements.ToList().Where(u => u.IsShowing).ToList();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Invalidate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void propGridElement_SelectedObjectsChanged(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
propGridElement.ExpandAllGridItems();
|
||||||
|
}
|
||||||
|
|
||||||
|
#region 基元列表右键菜单
|
||||||
|
private void tsmiResort_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
//Elements.Sort();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void tsmiClearActualValue_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
//foreach (IShapeElement ele in Elements)
|
||||||
|
//{
|
||||||
|
// if (ele.IsEnabled)
|
||||||
|
// {
|
||||||
|
// ele.SetActualValue(0.0);
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void tsmiInitialState_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
//foreach (IShapeElement ele in Elements)
|
||||||
|
//{
|
||||||
|
// if (ele.IsEnabled)
|
||||||
|
// {
|
||||||
|
// ele.State = ElementState.Normal;
|
||||||
|
// ele.InitialMeasureResult();
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void tsmiClearStandardValue_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
//foreach (IShapeElement ele in Elements)
|
||||||
|
//{
|
||||||
|
// if (ele.IsEnabled)
|
||||||
|
// {
|
||||||
|
// ele.SetStandardValue(0.0);
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region 图像区域右键菜单
|
||||||
|
private void tsmiKeepUnselected_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
KeepElements(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void tsmiKeepSelected_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
KeepElements(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void KeepElements(bool isKeepSelected)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < Elements.Count; i++)
|
||||||
|
{
|
||||||
|
var ele = Elements[i];
|
||||||
|
if (ele.IsEnabled)
|
||||||
|
{
|
||||||
|
if (ele.State == ElementState.Selected)
|
||||||
|
{
|
||||||
|
ele.IsEnabled = isKeepSelected;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ele.IsEnabled = !isKeepSelected;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void tsmiUnselectElements_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
//if (MouseState == MouseState.SelectedElement)
|
||||||
|
//{
|
||||||
|
// MouseState = MouseState.Normal;
|
||||||
|
|
||||||
|
// //Elements.ForEach(ele =>
|
||||||
|
// foreach (IShapeElement ele in Elements)
|
||||||
|
// {
|
||||||
|
// ele.State = ElementState.Normal;
|
||||||
|
// }
|
||||||
|
// //);
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region 基元的设备属性 运动设置和相机设置
|
||||||
|
public Action<IShapeElement> SetElementDevicePara;
|
||||||
|
|
||||||
|
public Action<IShapeElement> SetDeviceByElement;
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region 一般操作工具条
|
||||||
|
public bool IsShowToolBar
|
||||||
|
{
|
||||||
|
get => tsTool.Visible;
|
||||||
|
set => tsTool.Visible = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void tsBtnLoadImage_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
Thread InvokeThread = new Thread(new ThreadStart(OpenLoadImage));
|
||||||
|
InvokeThread.SetApartmentState(ApartmentState.STA);
|
||||||
|
InvokeThread.Start();
|
||||||
|
InvokeThread.Join();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OpenLoadImage()
|
||||||
|
{
|
||||||
|
ImageFilePath = "";
|
||||||
|
OpenFileDialog ofd = new OpenFileDialog();
|
||||||
|
if (ofd.ShowDialog() == DialogResult.OK)
|
||||||
|
{
|
||||||
|
ImageFilePath = ofd.FileName;
|
||||||
|
LoadImage((Bitmap)Bitmap.FromFile(ImageFilePath));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void tsBtnSaveImage_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
if (MAP == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
SaveFileDialog sfd = new SaveFileDialog();
|
||||||
|
sfd.Filter = "JPG文件|*.jpg|BMP文件|*.bmp";
|
||||||
|
if (sfd.ShowDialog() == DialogResult.OK)
|
||||||
|
{
|
||||||
|
string filePath = sfd.FileName;
|
||||||
|
if (filePath.EndsWith("bmp"))
|
||||||
|
{
|
||||||
|
MAP.Save(filePath, ImageFormat.Bmp);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
MAP.Save(filePath, ImageFormat.Jpeg);
|
||||||
|
}
|
||||||
|
MessageBox.Show("图片保存成功!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void tsBtnSaveImageWithElements_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
if (MAP == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
SaveFileDialog sfd = new SaveFileDialog();
|
||||||
|
sfd.Filter = "JPG文件|*.jpg|BMP文件|*.bmp";
|
||||||
|
if (sfd.ShowDialog() == DialogResult.OK)
|
||||||
|
{
|
||||||
|
string filePath = sfd.FileName;
|
||||||
|
|
||||||
|
Bitmap bmp = new Bitmap(MAP.Width, MAP.Height, PixelFormat.Format32bppArgb);
|
||||||
|
//Bitmap bmp = new Bitmap(MAP.Width, MAP.Height, MAP.PixelFormat);
|
||||||
|
//Bitmap bmp = new Bitmap(MAP.Width, MAP.Height);
|
||||||
|
using (Graphics g = Graphics.FromImage(bmp))
|
||||||
|
{
|
||||||
|
g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
|
||||||
|
g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
|
||||||
|
g.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
|
||||||
|
g.DrawImage(MAP, 0, 0);
|
||||||
|
|
||||||
|
for (int i = 0; i < Elements.Count; i++)
|
||||||
|
{
|
||||||
|
var ele = Elements[i];
|
||||||
|
if (ele.IsEnabled)
|
||||||
|
ele.Draw(g);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (filePath.EndsWith("bmp"))
|
||||||
|
{
|
||||||
|
bmp.Save(filePath, ImageFormat.Bmp);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
bmp.Save(filePath, ImageFormat.Jpeg);
|
||||||
|
}
|
||||||
|
MessageBox.Show("带基元图片保存成功!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void tsBtnMapSize_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
SetMapSize();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void tsBtnModeNormal_CheckedChanged(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
var btn = sender as ToolStripButton;
|
||||||
|
if (btn.Checked)
|
||||||
|
{
|
||||||
|
btn.BackColor = SystemColors.ActiveCaption;
|
||||||
|
|
||||||
|
foreach (ToolStripItem c in tsTool.Items)
|
||||||
|
{
|
||||||
|
if (c is ToolStripButton)
|
||||||
|
{
|
||||||
|
if (c.Name.StartsWith("tsBtnMode") && c.Name != btn.Name)
|
||||||
|
{
|
||||||
|
var temp = c as ToolStripButton;
|
||||||
|
temp.Checked = false;
|
||||||
|
temp.BackColor = SystemColors.Control;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (btn.Name)
|
||||||
|
{
|
||||||
|
case "tsBtnModeNormal":
|
||||||
|
MouseState = MouseState.Normal;
|
||||||
|
break;
|
||||||
|
case "tsBtnModeSelection":
|
||||||
|
MouseState = MouseState.SelectionZone;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void tsBtnScreenSize_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
SetScreenSize();
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region 基元工具条
|
||||||
|
//private void LoadElementTools()
|
||||||
|
//{
|
||||||
|
// var eleDict = ElementFactory.GetAllElementsInfo();
|
||||||
|
|
||||||
|
// foreach (KeyValuePair<ElementAttribute, Type> pair in eleDict)
|
||||||
|
// {
|
||||||
|
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
|
||||||
|
public void SetNewROIType(IShapeElement element)
|
||||||
|
{
|
||||||
|
cvImage.DrawTemplate = element;
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region 事件
|
||||||
|
public event Action<IShapeElement> OnElementChangedHandle;
|
||||||
|
public event Action OnImageChanged;
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region 工具栏显示/隐藏右键菜单
|
||||||
|
private void tsmiShowToolBar_CheckedChanged(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
//IsShowToolBar = tsmiShowToolBar.Checked;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void tsmiShowStatusBar_CheckedChanged(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
//IsShowStatusBar = tsmiShowStatusBar.Checked;
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
120
DH.UI.Model.Winform/Canvas.resx
Normal file
120
DH.UI.Model.Winform/Canvas.resx
Normal file
@@ -0,0 +1,120 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<root>
|
||||||
|
<!--
|
||||||
|
Microsoft ResX Schema
|
||||||
|
|
||||||
|
Version 2.0
|
||||||
|
|
||||||
|
The primary goals of this format is to allow a simple XML format
|
||||||
|
that is mostly human readable. The generation and parsing of the
|
||||||
|
various data types are done through the TypeConverter classes
|
||||||
|
associated with the data types.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
... ado.net/XML headers & schema ...
|
||||||
|
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||||
|
<resheader name="version">2.0</resheader>
|
||||||
|
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||||
|
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||||
|
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||||
|
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||||
|
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||||
|
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||||
|
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||||
|
<comment>This is a comment</comment>
|
||||||
|
</data>
|
||||||
|
|
||||||
|
There are any number of "resheader" rows that contain simple
|
||||||
|
name/value pairs.
|
||||||
|
|
||||||
|
Each data row contains a name, and value. The row also contains a
|
||||||
|
type or mimetype. Type corresponds to a .NET class that support
|
||||||
|
text/value conversion through the TypeConverter architecture.
|
||||||
|
Classes that don't support this are serialized and stored with the
|
||||||
|
mimetype set.
|
||||||
|
|
||||||
|
The mimetype is used for serialized objects, and tells the
|
||||||
|
ResXResourceReader how to depersist the object. This is currently not
|
||||||
|
extensible. For a given mimetype the value must be set accordingly:
|
||||||
|
|
||||||
|
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||||
|
that the ResXResourceWriter will generate, however the reader can
|
||||||
|
read any of the formats listed below.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.binary.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.soap.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||||
|
value : The object must be serialized into a byte array
|
||||||
|
: using a System.ComponentModel.TypeConverter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
-->
|
||||||
|
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||||
|
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||||
|
<xsd:element name="root" msdata:IsDataSet="true">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:choice maxOccurs="unbounded">
|
||||||
|
<xsd:element name="metadata">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="assembly">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:attribute name="alias" type="xsd:string" />
|
||||||
|
<xsd:attribute name="name" type="xsd:string" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="data">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="resheader">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:choice>
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:schema>
|
||||||
|
<resheader name="resmimetype">
|
||||||
|
<value>text/microsoft-resx</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="version">
|
||||||
|
<value>2.0</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="reader">
|
||||||
|
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="writer">
|
||||||
|
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
</root>
|
||||||
33
DH.UI.Model.Winform/CanvasImage.Designer.cs
generated
Normal file
33
DH.UI.Model.Winform/CanvasImage.Designer.cs
generated
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
namespace DH.UI.Model.Winform
|
||||||
|
{
|
||||||
|
partial class CanvasImage
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 必需的设计器变量。
|
||||||
|
/// </summary>
|
||||||
|
private System.ComponentModel.IContainer components = null;
|
||||||
|
|
||||||
|
#region 组件设计器生成的代码
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 设计器支持所需的方法 - 不要修改
|
||||||
|
/// 使用代码编辑器修改此方法的内容。
|
||||||
|
/// </summary>
|
||||||
|
private void InitializeComponent()
|
||||||
|
{
|
||||||
|
this.SuspendLayout();
|
||||||
|
//
|
||||||
|
// CanvasImage
|
||||||
|
//
|
||||||
|
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
|
||||||
|
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||||
|
this.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
|
||||||
|
this.Name = "CanvasImage";
|
||||||
|
this.Size = new System.Drawing.Size(575, 472);
|
||||||
|
this.ResumeLayout(false);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user