Compare commits
41 Commits
0ac00af0ad
...
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 |
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)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
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();
|
||||
}
|
||||
}
|
||||
}
|
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>
|
@ -1,130 +0,0 @@
|
||||
using System.ComponentModel;
|
||||
using System.Drawing.Imaging;
|
||||
using OpenCvSharp;
|
||||
|
||||
namespace DH.Devices.Devices
|
||||
{
|
||||
public class CameraBase
|
||||
{
|
||||
public volatile int SnapshotCount = 0;
|
||||
|
||||
public virtual bool isEnabled { get; set; } = false;
|
||||
|
||||
[Category("采图模式")]
|
||||
[Description("是否连续模式。true:连续模式采图;false:触发模式采图")]
|
||||
[DisplayName("连续模式")]
|
||||
public bool IsContinueMode { get; set; } = false;
|
||||
|
||||
|
||||
public virtual bool isSavePicEnabled { get; set; } = false;
|
||||
|
||||
|
||||
|
||||
[Category("图片保存")]
|
||||
[Description("图片保存文件夹")]
|
||||
[DisplayName("图片保存文件夹")]
|
||||
public virtual string ImageSaveDirectory { get; set; }
|
||||
|
||||
[Category("图片保存")]
|
||||
[Description("图片保存格式")]
|
||||
[DisplayName("图片保存格式")]
|
||||
public ImageFormat ImageFormat { get; set; } = ImageFormat.Jpeg;
|
||||
|
||||
[Category("采图模式")]
|
||||
[Description("是否硬触发模式。true:硬触发;false:软触发")]
|
||||
[DisplayName("硬触发")]
|
||||
public bool IsHardwareTrigger { get; set; } = false;
|
||||
|
||||
public string SerialNumber { get; set; } = string.Empty;
|
||||
public string CameraName { get; set; } = string.Empty;
|
||||
|
||||
public string CameraIP { get; set; } = string.Empty;
|
||||
|
||||
public string ComputerIP { get; set; } = string.Empty;
|
||||
|
||||
// public StreamFormat dvpStreamFormat = dvpStreamFormat.;
|
||||
|
||||
[Category("采图模式")]
|
||||
[Description("是否传感器直接硬触发。true:传感器硬触发,不通过软件触发;false:通过软件触发IO 的硬触发模式")]
|
||||
[DisplayName("是否传感器直接硬触发")]
|
||||
public bool IsDirectHardwareTrigger { get; set; } = false;
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 增益
|
||||
/// </summary>
|
||||
[Category("相机设置")]
|
||||
[DisplayName("增益")]
|
||||
[Description("Gain:增益,-1:不设置,不同型号相机的增益,请参考mvs")]
|
||||
public float Gain { get; set; } = -1;
|
||||
|
||||
[Category("图像旋转")]
|
||||
[Description("默认旋转,相机开启后默认不旋转")]
|
||||
[DisplayName("默认旋转")]
|
||||
public virtual float RotateImage { get; set; } = 0;
|
||||
|
||||
[Category("取像配置")]
|
||||
[Description("曝光")]
|
||||
[DisplayName("曝光")]
|
||||
public virtual float Exposure { get; set; } = 200;
|
||||
|
||||
[Category("相机设置")]
|
||||
[DisplayName("硬触发后的延迟")]
|
||||
[Description("TriggerDelay:硬触发后的延迟,单位:us 微秒")]
|
||||
public float TriggerDelay { get; set; } = 0;
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 滤波时间
|
||||
/// </summary>
|
||||
[Category("相机设置")]
|
||||
[DisplayName("滤波时间")]
|
||||
[Description("LineDebouncerTime:I/O去抖时间 单位:us")]
|
||||
public int LineDebouncerTime { get; set; } = 0;
|
||||
|
||||
|
||||
|
||||
public Action<DateTime, CameraBase, Mat> OnHImageOutput { get; set; }
|
||||
/// <summary>
|
||||
/// 相机连接
|
||||
/// </summary>
|
||||
/// <returns>是否成功</returns>
|
||||
public virtual bool CameraConnect() { return false; }
|
||||
|
||||
/// <summary>
|
||||
/// 相机断开
|
||||
/// </summary>
|
||||
/// <returns>是否成功</returns>
|
||||
public virtual bool CameraDisConnect() { return false; }
|
||||
|
||||
/// <summary>
|
||||
/// 抓取一张图像
|
||||
/// </summary>
|
||||
/// <returns>图像</returns>
|
||||
//internal virtual HObject GrabOneImage(string cameraName) { return null; }
|
||||
/// <summary>
|
||||
/// 设置曝光时间
|
||||
/// </summary>
|
||||
/// <param name="exposureTime">曝光时间</param>
|
||||
public virtual void SetExposure(int exposureTime, string cameraName) { }
|
||||
/// <summary>
|
||||
/// 设置增益
|
||||
/// </summary>
|
||||
/// <param name="exposure">增益</param>
|
||||
public virtual void SetGain(int gain, string cameraName) { }
|
||||
/// <summary>
|
||||
/// 设置采集模式
|
||||
/// </summary>
|
||||
/// <param name="mode">0=连续采集,即异步采集 1=单次采集,即同步采集</param>
|
||||
internal virtual void SetAcquisitionMode(int mode) { }
|
||||
/// <summary>
|
||||
/// 设置采集图像的ROI
|
||||
/// </summary>
|
||||
internal virtual void SetAcqRegion(int offsetV, int offsetH, int imageH, int imageW, string cameraName) { }
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
@ -1,186 +0,0 @@
|
||||
using System.Collections;
|
||||
using System.ComponentModel;
|
||||
using System.Drawing;
|
||||
using System.Drawing.Imaging;
|
||||
using DH.Commons.Enums;
|
||||
using HalconDotNet;
|
||||
using OpenCvSharp;
|
||||
|
||||
|
||||
|
||||
namespace DH.Devices.Devices
|
||||
{
|
||||
/// <summary>
|
||||
/// 视觉处理引擎:1.传统视觉 2.深度学习
|
||||
/// CV深度学习 四大领域
|
||||
/// Image Classification 图像分类:判别图中物体是什么,比如是猫还是狗;
|
||||
/// Semantic Segmentation 语义分割:对图像进行像素级分类,预测每个像素属于的类别,不区分个体;
|
||||
/// Object Detection 目标检测:寻找图像中的物体并进行定位;
|
||||
/// Instance Segmentation 实例分割:定位图中每个物体,并进行像素级标注,区分不同个体;
|
||||
/// </summary>
|
||||
public abstract class VisionEngineBase
|
||||
{
|
||||
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 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
public class CamModuleXY
|
||||
{
|
||||
[Category("图片行")]
|
||||
[DisplayName("行")]
|
||||
[Description("行")]
|
||||
// [TypeConverter(typeof(DeviceIdSelectorConverter<CameraBase>))]
|
||||
//[TypeConverter(typeof(CollectionCountConvert))]
|
||||
public int PicRows { get; set; } = 1;
|
||||
|
||||
[Category("图片列")]
|
||||
[DisplayName("列")]
|
||||
[Description("列")]
|
||||
// [TypeConverter(typeof(DeviceIdSelectorConverter<CameraBase>))]
|
||||
//[TypeConverter(typeof(CollectionCountConvert))]
|
||||
public int PicCols { get; set; } = 1;
|
||||
|
||||
public string GetDisplayText()
|
||||
{
|
||||
return "行:" + PicRows.ToString() + "列:" + PicCols.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
//public class RelatedCamera
|
||||
//{
|
||||
|
||||
// [Category("关联相机")]
|
||||
// [DisplayName("关联相机")]
|
||||
// [Description("关联相机描述")]
|
||||
// //[TypeConverter(typeof(DeviceIdSelectorConverter<CameraBase>))]
|
||||
// //[TypeConverter(typeof(CollectionCountConvert))]
|
||||
// public string CameraSourceId { get; set; } = "";
|
||||
|
||||
|
||||
// //public string GetDisplayText()
|
||||
// //{
|
||||
// // using (var scope = GlobalVar.Container.BeginLifetimeScope())
|
||||
// // {
|
||||
// // List<IDevice> deviceList = scope.Resolve<List<IDevice>>();
|
||||
// // IDevice CameraDevice = deviceList.FirstOrDefault(dev => dev.Id.Equals(CameraSourceId));
|
||||
|
||||
// // if (CameraDevice != null && CameraDevice is CameraBase)
|
||||
// // {
|
||||
// // return CameraDevice.Name;
|
||||
// // }
|
||||
|
||||
// // }
|
||||
// // return CameraSourceId;
|
||||
// //}
|
||||
//}
|
||||
public class VisionEngineInitialConfigBase //: InitialConfigBase
|
||||
{
|
||||
[Category("深度学习检测配置")]
|
||||
[DisplayName("检测配置集合")]
|
||||
[Description("检测配置集合")]
|
||||
//[TypeConverter(typeof(CollectionCountConvert))]
|
||||
//[Editor(typeof(ComplexCollectionEditor<DetectionConfig>), typeof(UITypeEditor))]
|
||||
public List<DetectionConfig> DetectionConfigs { get; set; } = new List<DetectionConfig>();
|
||||
|
||||
[Category("深度学习检测配置")]
|
||||
[DisplayName("标签分类")]
|
||||
[Description("标签分类,A_NG,B_TBD...")]
|
||||
// [TypeConverter(typeof(CollectionCountConvert))]
|
||||
// [Editor(typeof(ComplexCollectionEditor<RecongnitionLabelCategory>), typeof(UITypeEditor))]
|
||||
public List<RecongnitionLabelCategory> RecongnitionLabelCategoryList { get; set; } = new List<RecongnitionLabelCategory>();
|
||||
|
||||
[Category("深度学习检测配置")]
|
||||
[DisplayName("检测标签定义集合")]
|
||||
[Description("定义检测标签的集合,例如:Seg/Detection模式:断裂、油污、划伤...;Class模式:ok、ng、上面、下面、套环、正常...")]
|
||||
// [TypeConverter(typeof(CollectionCountConvert))]
|
||||
// [Editor(typeof(ComplexCollectionEditor<RecongnitionLabel>), typeof(UITypeEditor))]
|
||||
public List<RecongnitionLabel> RecongnitionLabelList { get; set; } = new List<RecongnitionLabel>();
|
||||
|
||||
[Category("深度学习检测配置")]
|
||||
[DisplayName("标签置信度")]
|
||||
[Description("标签置信度,过滤小于改置信度的标签,大于该设置的标签才能识别")]
|
||||
public float Score { get; set; } = 0.5f;
|
||||
|
||||
[Category("深度学习检测配置")]
|
||||
[DisplayName("CPU线程数量")]
|
||||
[Description("用于深度学习的CPU线程数量,不要设置太大,会单独占用线程,影响其他程序运行")]
|
||||
public int CPUNums { get; set; } = 1;
|
||||
|
||||
//[Category("深度学习检测配置")]
|
||||
//[DisplayName("检测项GPU指定")]
|
||||
//[Description("将检测项指定到GPU")]
|
||||
// [TypeConverter(typeof(CollectionCountConvert))]
|
||||
// [Editor(typeof(ComplexCollectionEditor<DetectionGPUConfig>), typeof(UITypeEditor))]
|
||||
// public List<DetectionGPUConfig> DetectionGPUList { get; set; } = new List<DetectionGPUConfig>();
|
||||
|
||||
// [Category("数据保存配置")]
|
||||
//[DisplayName("是否保存检测明细CSV")]
|
||||
//[Description("是否保存 检测明细CSV")]
|
||||
//public override bool IsEnableCSV { get; set; } = true;
|
||||
|
||||
//[Category("数据保存配置")]
|
||||
//[DisplayName("是否保存检测图片")]
|
||||
//[Description("是否保存 检测图片,总开关")]
|
||||
//public bool IsSaveImage { get; set; } = true;
|
||||
|
||||
//[Category("数据保存配置")]
|
||||
//[Description("检测图片 保存文件夹")]
|
||||
//[DisplayName("检测图片保存文件夹")]
|
||||
//[Editor(typeof(FoldDialogEditor), typeof(UITypeEditor))]
|
||||
//public string ImageSaveDirectory { get; set; } = "D:\\PROJECTS\\X017\\Images";
|
||||
|
||||
//[Category("数据保存配置")]
|
||||
//[Description("检测明细CSV文件夹")]
|
||||
//[DisplayName("检测明细CSV文件夹")]
|
||||
//[Editor(typeof(FoldDialogEditor), typeof(UITypeEditor))]
|
||||
//public string CSVDataPath { get; set; } = "D:\\PROJECTS\\X017\\Images";
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -17,9 +17,11 @@
|
||||
</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>
|
||||
|
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) { }
|
||||
}
|
||||
}
|
@ -6,25 +6,14 @@ using System.Text.RegularExpressions;
|
||||
using System.Text;
|
||||
using System.Drawing.Design;
|
||||
using AntdUI;
|
||||
using static DH.Commons.Enums.EnumHelper;
|
||||
using System.Text.Json.Serialization;
|
||||
using DH.Commons.Enums;
|
||||
using System.Drawing.Imaging;
|
||||
|
||||
namespace DH.Commons.Base
|
||||
{
|
||||
|
||||
namespace DH.Commons.Enums
|
||||
{
|
||||
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; }
|
||||
@ -116,20 +105,20 @@ namespace DH.Commons.Enums
|
||||
/// </summary>
|
||||
public class DetectionResultDetail
|
||||
{
|
||||
#pragma warning disable CS8618 // 在退出构造函数时,不可为 null 的字段必须包含非 null 值。请考虑声明为可以为 null。
|
||||
|
||||
public string LabelBGR { get; set; }//识别到对象的标签BGR
|
||||
|
||||
|
||||
|
||||
public int LabelNo { get; set; } // 识别到对象的标签索引
|
||||
|
||||
#pragma warning disable CS8618 // 在退出构造函数时,不可为 null 的字段必须包含非 null 值。请考虑声明为可以为 null。
|
||||
|
||||
public string LabelName { get; set; }//识别到对象的标签名称
|
||||
|
||||
|
||||
public double Score { get; set; }//识别目标结果的可能性、得分
|
||||
|
||||
#pragma warning disable CS8618 // 在退出构造函数时,不可为 null 的字段必须包含非 null 值。请考虑声明为可以为 null。
|
||||
|
||||
public string LabelDisplay { get; set; }//识别到对象的 显示信息
|
||||
|
||||
|
||||
@ -150,10 +139,10 @@ namespace DH.Commons.Enums
|
||||
public class MLResult
|
||||
{
|
||||
public bool IsSuccess = false;
|
||||
#pragma warning disable CS8618 // 在退出构造函数时,不可为 null 的字段必须包含非 null 值。请考虑声明为可以为 null。
|
||||
|
||||
public string ResultMessage;
|
||||
|
||||
#pragma warning disable CS8618 // 在退出构造函数时,不可为 null 的字段必须包含非 null 值。请考虑声明为可以为 null。
|
||||
|
||||
public Bitmap ResultMap;
|
||||
|
||||
public List<DetectionResultDetail> ResultDetails = new List<DetectionResultDetail>();
|
||||
@ -177,8 +166,7 @@ namespace DH.Commons.Enums
|
||||
public bool IsGPU;
|
||||
public int GPUId;
|
||||
public float Score_thre;
|
||||
#pragma warning disable CS8618 // 在退出构造函数时,不可为 null 的字段必须包含非 null 值。请考虑声明为可以为 null。
|
||||
#pragma warning disable CS8618 // 在退出构造函数时,不可为 null 的字段必须包含非 null 值。请考虑声明为可以为 null。
|
||||
|
||||
public MLInit(string modelFile, bool isGPU, int gpuId, float score_thre)
|
||||
|
||||
|
||||
@ -203,18 +191,32 @@ namespace DH.Commons.Enums
|
||||
}
|
||||
public class DetectStationResult
|
||||
{
|
||||
#pragma warning disable CS8618 // 在退出构造函数时,不可为 null 的字段必须包含非 null 值。请考虑声明为可以为 null。
|
||||
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 Pid { get; set; }
|
||||
|
||||
|
||||
#pragma warning disable CS8618 // 在退出构造函数时,不可为 null 的字段必须包含非 null 值。请考虑声明为可以为 null。
|
||||
public string TempPid { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 检测工位名称
|
||||
/// </summary>
|
||||
#pragma warning disable CS8618 // 在退出构造函数时,不可为 null 的字段必须包含非 null 值。请考虑声明为可以为 null。
|
||||
public string DetectName { get; set; }
|
||||
|
||||
|
||||
@ -224,8 +226,11 @@ namespace DH.Commons.Enums
|
||||
/// </summary>
|
||||
public List<DetectionResultDetail> DetectDetails = new List<DetectionResultDetail>();
|
||||
public List<IShapeElement> DetectionResultShapes = new List<IShapeElement>();
|
||||
/// <summary>
|
||||
/// 视觉测量结果集合
|
||||
/// </summary>
|
||||
|
||||
|
||||
public List<IndexedSpec> realSpecs { get; set; } = new List<IndexedSpec>();
|
||||
/// <summary>
|
||||
/// 工位检测结果
|
||||
/// </summary>
|
||||
@ -250,35 +255,24 @@ namespace DH.Commons.Enums
|
||||
/// 预处理阶段已经NG
|
||||
/// </summary>
|
||||
public bool IsPreTreatNG { get; set; } = false;
|
||||
|
||||
/// <summary>
|
||||
/// 检测原图
|
||||
/// </summary>
|
||||
public Bitmap DetectionOriginImage { get; set; }
|
||||
/// <summary>
|
||||
/// 目标检测NG
|
||||
/// </summary>
|
||||
public bool IsObjectDetectNG { get; set; } = false;
|
||||
|
||||
public ImageFormat ImageFormat { get; set; } = ImageFormat.Jpeg;
|
||||
public DateTime EndTime { get; set; }
|
||||
|
||||
public string ImageSaveDirectory { get; set; }
|
||||
public int StationDetectElapsed { get; set; }
|
||||
public static string NormalizeAndClean(string input)
|
||||
{
|
||||
#pragma warning disable CS8603 // 可能返回 null 引用。
|
||||
if (input == null) return null;
|
||||
#pragma warning restore CS8603 // 可能返回 null 引用。
|
||||
public bool SaveOKOriginal = false;
|
||||
public bool SaveNGOriginal = false;
|
||||
public bool SaveOKDetect = false;
|
||||
public bool SaveNGDetect = false;
|
||||
|
||||
// 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 : NotifyProperty
|
||||
@ -401,7 +395,7 @@ namespace DH.Commons.Enums
|
||||
|
||||
public static double GetDistance(CustomizedPoint p1, CustomizedPoint p2)
|
||||
{
|
||||
return Math.Sqrt(Math.Pow((p1.X - p2.X), 2) + Math.Pow((p1.Y - p2.Y), 2));
|
||||
return Math.Sqrt(Math.Pow(p1.X - p2.X, 2) + Math.Pow(p1.Y - p2.Y, 2));
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
@ -442,13 +436,13 @@ namespace DH.Commons.Enums
|
||||
|
||||
public int CompareTo(CustomizedPoint other)
|
||||
{
|
||||
return (X == other.X && Y == other.Y) ? 0 : 1;
|
||||
return X == other.X && Y == other.Y ? 0 : 1;
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
//return (int)(X * 10 + Y);
|
||||
return (new Tuple<double, double>(X, Y)).GetHashCode();
|
||||
return new Tuple<double, double>(X, Y).GetHashCode();
|
||||
}
|
||||
|
||||
public static CustomizedPoint operator -(CustomizedPoint p1, CustomizedPoint p2)
|
||||
@ -489,165 +483,415 @@ namespace DH.Commons.Enums
|
||||
|
||||
|
||||
// }
|
||||
public class DetectionConfig
|
||||
public class DetectionConfig : NotifyProperty
|
||||
{
|
||||
[ReadOnly(true)]
|
||||
public string Id { get; set; } = Guid.NewGuid().ToString();
|
||||
#region 属性字段
|
||||
private string _id = Guid.NewGuid().ToString();
|
||||
private string _name;
|
||||
private string _cameraSourceId = "";
|
||||
private List<RelatedCamera> _cameraCollects = new List<RelatedCamera>();
|
||||
private bool _isEnableGPU;
|
||||
private bool _isMixModel;
|
||||
private bool _isPreEnabled;
|
||||
private bool _isEnabled;
|
||||
private bool _isAddStation = true;
|
||||
private string _halconAlgorithemPath_Pre;
|
||||
private AntList<PreTreatParam> _preTreatParams = new AntList<PreTreatParam>();
|
||||
private AntList<PreTreatParam> _outPreTreatParams = new AntList<PreTreatParam>();
|
||||
private ModelType _modelType = ModelType.目标检测;
|
||||
private string _modelPath;
|
||||
private int _modelWidth = 640;
|
||||
private int _modelHeight = 640;
|
||||
private string _modeloutNodeName = "output0";
|
||||
private float _modelconfThreshold = 0.5f;
|
||||
private string _in_lable_path;
|
||||
private AntList<DetectionLable> _detectionLableList = new AntList<DetectionLable>();
|
||||
private AntList<SizeTreatParam> _sizeTreatParamList = new AntList<SizeTreatParam>();
|
||||
|
||||
private CustomizedPoint _showLocation = new CustomizedPoint();
|
||||
private string _imageSaveDirectory="D://Images";
|
||||
private bool _saveOKOriginal = false;
|
||||
private bool _saveNGOriginal = false;
|
||||
private bool _saveOKDetect = false;
|
||||
private bool _saveNGDetect = false;
|
||||
|
||||
#endregion
|
||||
|
||||
#region 属性声明
|
||||
[ReadOnly(true)]
|
||||
public string Id
|
||||
{
|
||||
get => _id;
|
||||
set
|
||||
{
|
||||
if (_id == value) return;
|
||||
_id = value;
|
||||
OnPropertyChanged(nameof(Id));
|
||||
}
|
||||
}
|
||||
|
||||
[Category("检测配置")]
|
||||
[DisplayName("检测配置名称")]
|
||||
[Description("检测配置名称")]
|
||||
public string Name { get; set; }
|
||||
|
||||
[Category("关联相机")]
|
||||
[DisplayName("关联相机")]
|
||||
[Description("关联相机描述")]
|
||||
|
||||
|
||||
public string CameraSourceId { get; set; } = "";
|
||||
|
||||
public string Name
|
||||
{
|
||||
get => _name;
|
||||
set
|
||||
{
|
||||
if (_name == value) return;
|
||||
_name = value;
|
||||
OnPropertyChanged(nameof(Name));
|
||||
}
|
||||
}
|
||||
|
||||
[Category("关联相机集合")]
|
||||
[DisplayName("关联相机集合")]
|
||||
[Description("关联相机描述")]
|
||||
//[TypeConverter(typeof(DeviceIdSelectorConverter<CameraBase>))]
|
||||
|
||||
|
||||
|
||||
public List<RelatedCamera> CameraCollects { get; set; } = new List<RelatedCamera>();
|
||||
|
||||
public List<RelatedCamera> CameraCollects
|
||||
{
|
||||
get => _cameraCollects;
|
||||
set
|
||||
{
|
||||
if (_cameraCollects == value) return;
|
||||
_cameraCollects = value;
|
||||
OnPropertyChanged(nameof(CameraCollects));
|
||||
}
|
||||
}
|
||||
|
||||
[Category("启用配置")]
|
||||
[DisplayName("是否启用GPU检测")]
|
||||
[Description("是否启用GPU检测")]
|
||||
public bool IsEnableGPU { get; set; } = false;
|
||||
public bool IsEnableGPU
|
||||
{
|
||||
get => _isEnableGPU;
|
||||
set
|
||||
{
|
||||
if (_isEnableGPU == value) return;
|
||||
_isEnableGPU = value;
|
||||
OnPropertyChanged(nameof(IsEnableGPU));
|
||||
}
|
||||
}
|
||||
|
||||
[Category("启用配置")]
|
||||
[DisplayName("是否混料模型")]
|
||||
[Description("是否混料模型")]
|
||||
public bool IsMixModel { get; set; } = false;
|
||||
|
||||
public bool IsMixModel
|
||||
{
|
||||
get => _isMixModel;
|
||||
set
|
||||
{
|
||||
if (_isMixModel == value) return;
|
||||
_isMixModel = value;
|
||||
OnPropertyChanged(nameof(IsMixModel));
|
||||
}
|
||||
}
|
||||
|
||||
[Category("启用配置")]
|
||||
[DisplayName("是否启用预处理")]
|
||||
[Description("是否启用预处理")]
|
||||
public bool IsPreEnabled
|
||||
{
|
||||
get => _isPreEnabled;
|
||||
set
|
||||
{
|
||||
if (_isPreEnabled == value) return;
|
||||
_isPreEnabled = value;
|
||||
OnPropertyChanged(nameof(IsPreEnabled));
|
||||
}
|
||||
}
|
||||
|
||||
[Category("启用配置")]
|
||||
[DisplayName("是否启用该检测")]
|
||||
[Description("是否启用该检测")]
|
||||
public bool IsEnabled { get; set; }
|
||||
public bool IsEnabled
|
||||
{
|
||||
get => _isEnabled;
|
||||
set
|
||||
{
|
||||
if (_isEnabled == value) return;
|
||||
_isEnabled = value;
|
||||
OnPropertyChanged(nameof(IsEnabled));
|
||||
}
|
||||
}
|
||||
|
||||
[Category("启用配置")]
|
||||
[DisplayName("是否加入检测工位")]
|
||||
[Description("是否加入检测工位")]
|
||||
public bool IsAddStation { get; set; } = true;
|
||||
|
||||
public bool IsAddStation
|
||||
{
|
||||
get => _isAddStation;
|
||||
set
|
||||
{
|
||||
if (_isAddStation == value) return;
|
||||
_isAddStation = value;
|
||||
OnPropertyChanged(nameof(IsAddStation));
|
||||
}
|
||||
}
|
||||
[Category("图片保存")]
|
||||
[DisplayName("图片保存文件夹")]
|
||||
[Description("图片保存文件夹")]
|
||||
public virtual string ImageSaveDirectory
|
||||
{
|
||||
get => _imageSaveDirectory;
|
||||
set
|
||||
{
|
||||
if (_imageSaveDirectory == value) return;
|
||||
_imageSaveDirectory = value;
|
||||
OnPropertyChanged(nameof(ImageSaveDirectory));
|
||||
}
|
||||
}
|
||||
[Category("1.预处理(视觉算子)")]
|
||||
[DisplayName("预处理-算法文件路径")]
|
||||
// [Description("预处理算法文件路径配置")][Editor(typeof(FileDialogEditor), typeof(UITypeEditor))]
|
||||
public string HalconAlgorithemPath_Pre { get; set; }
|
||||
|
||||
// [Category("1.预处理(视觉算子)")]
|
||||
//[DisplayName("预处理-输出结果的SPEC标准")]
|
||||
//[Description("预处理输出结果的SPEC标准配置")]
|
||||
|
||||
// public List<IndexedSpec> OutputSpec_Pre { get; set; } = new List<IndexedSpec>();
|
||||
public string HalconAlgorithemPath_Pre
|
||||
{
|
||||
get => _halconAlgorithemPath_Pre;
|
||||
set
|
||||
{
|
||||
if (_halconAlgorithemPath_Pre == value) return;
|
||||
_halconAlgorithemPath_Pre = value;
|
||||
OnPropertyChanged(nameof(HalconAlgorithemPath_Pre));
|
||||
}
|
||||
}
|
||||
|
||||
[Category("1.预处理(视觉算子)")]
|
||||
[DisplayName("预处理-参数列表")]
|
||||
[Description("预处理-参数列表")]
|
||||
|
||||
public List<PreTreatParam> PreTreatParams { get; set; } = new List<PreTreatParam>();
|
||||
public AntList<PreTreatParam> PreTreatParams
|
||||
{
|
||||
get => _preTreatParams;
|
||||
set
|
||||
{
|
||||
if (_preTreatParams == value) return;
|
||||
_preTreatParams = value;
|
||||
OnPropertyChanged(nameof(PreTreatParams));
|
||||
}
|
||||
}
|
||||
|
||||
[Category("1.预处理(视觉算子)")]
|
||||
[DisplayName("预处理-输出参数列表")]
|
||||
[Description("预处理-输出参数列表")]
|
||||
|
||||
public List<PreTreatParam> OUTPreTreatParams { get; set; } = new List<PreTreatParam>();
|
||||
public AntList<PreTreatParam> OUTPreTreatParams
|
||||
{
|
||||
get => _outPreTreatParams;
|
||||
set
|
||||
{
|
||||
if (_outPreTreatParams == value) return;
|
||||
_outPreTreatParams = value;
|
||||
OnPropertyChanged(nameof(OUTPreTreatParams));
|
||||
}
|
||||
}
|
||||
|
||||
[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;
|
||||
public ModelType ModelType
|
||||
{
|
||||
get => _modelType;
|
||||
set
|
||||
{
|
||||
if (_modelType == value) return;
|
||||
_modelType = value;
|
||||
OnPropertyChanged(nameof(ModelType));
|
||||
}
|
||||
}
|
||||
|
||||
[Category("2.中检测(深度学习)")]
|
||||
[DisplayName("中检测-模型文件路径")]
|
||||
[Description("中处理 深度学习模型文件路径,路径中不可含有中文字符,一般情况可以只配置中检测模型,当需要先用预检测过滤一次时,请先配置好与预检测相关配置")]
|
||||
|
||||
public string ModelPath { get; set; }
|
||||
[Description("中处理 深度学习模型文件路径")]
|
||||
public string ModelPath
|
||||
{
|
||||
get => _modelPath;
|
||||
set
|
||||
{
|
||||
if (_modelPath == value) return;
|
||||
_modelPath = value;
|
||||
OnPropertyChanged(nameof(ModelPath));
|
||||
}
|
||||
}
|
||||
|
||||
[Category("2.中检测(深度学习)")]
|
||||
[DisplayName("中检测-模型宽度")]
|
||||
[Description("中处理-模型宽度")]
|
||||
|
||||
public int ModelWidth { get; set; } = 640;
|
||||
public int ModelWidth
|
||||
{
|
||||
get => _modelWidth;
|
||||
set
|
||||
{
|
||||
if (_modelWidth == value) return;
|
||||
_modelWidth = value;
|
||||
OnPropertyChanged(nameof(ModelWidth));
|
||||
}
|
||||
}
|
||||
|
||||
[Category("2.中检测(深度学习)")]
|
||||
[DisplayName("中检测-模型高度")]
|
||||
[Description("中处理-模型高度")]
|
||||
|
||||
public int ModelHeight { get; set; } = 640;
|
||||
public int ModelHeight
|
||||
{
|
||||
get => _modelHeight;
|
||||
set
|
||||
{
|
||||
if (_modelHeight == value) return;
|
||||
_modelHeight = value;
|
||||
OnPropertyChanged(nameof(ModelHeight));
|
||||
}
|
||||
}
|
||||
|
||||
[Category("2.中检测(深度学习)")]
|
||||
[DisplayName("中检测-模型节点名称")]
|
||||
[Description("中处理-模型节点名称")]
|
||||
|
||||
public string ModeloutNodeName { get; set; } = "output0";
|
||||
public string ModeloutNodeName
|
||||
{
|
||||
get => _modeloutNodeName;
|
||||
set
|
||||
{
|
||||
if (_modeloutNodeName == value) return;
|
||||
_modeloutNodeName = value;
|
||||
OnPropertyChanged(nameof(ModeloutNodeName));
|
||||
}
|
||||
}
|
||||
|
||||
[Category("2.中检测(深度学习)")]
|
||||
[DisplayName("中检测-模型置信度")]
|
||||
[Description("中处理-模型置信度")]
|
||||
|
||||
public float ModelconfThreshold { get; set; } = 0.5f;
|
||||
public float ModelconfThreshold
|
||||
{
|
||||
get => _modelconfThreshold;
|
||||
set
|
||||
{
|
||||
if (_modelconfThreshold == value) return;
|
||||
_modelconfThreshold = value;
|
||||
OnPropertyChanged(nameof(ModelconfThreshold));
|
||||
}
|
||||
}
|
||||
|
||||
[Category("2.中检测(深度学习)")]
|
||||
[DisplayName("中检测-模型标签路径")]
|
||||
[Description("中处理-模型标签路径")]
|
||||
|
||||
public string in_lable_path { get; set; }
|
||||
|
||||
[Category("4.最终过滤(逻辑过滤)")]
|
||||
[DisplayName("过滤器集合")]
|
||||
[Description("最后的逻辑过滤:可根据 识别出对象的 宽度、高度、面积、得分来设置最终检测结果,同一识别目标同一判定,多项过滤器之间为“或”关系")]
|
||||
|
||||
public List<DetectionFilter> DetectionFilterList { get; set; } = new List<DetectionFilter>();
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 标签集合
|
||||
/// </summary>
|
||||
public List<DetectionLable> DetectionLableList { get; set; } = new List<DetectionLable>();
|
||||
//[Category("深度学习配置")]
|
||||
//[DisplayName("检测配置标签")]
|
||||
//[Description("检测配置标签关联")]
|
||||
|
||||
//public List<DetectConfigLabel> DetectConfigLabelList { get; set; } = new List<DetectConfigLabel>();
|
||||
[Category("显示配置")]
|
||||
[DisplayName("显示位置")]
|
||||
[Description("检测信息显示位置。左上角为(1,1),向右向下为正方向")]
|
||||
// [TypeConverter(typeof(ComplexObjectConvert))]
|
||||
// [Editor(typeof(PropertyObjectEditor), typeof(UITypeEditor))]
|
||||
public CustomizedPoint ShowLocation { get; set; } = new CustomizedPoint();
|
||||
|
||||
public DetectionConfig()
|
||||
public string In_lable_path
|
||||
{
|
||||
|
||||
get
|
||||
{
|
||||
if (string.IsNullOrEmpty(ModelPath) || string.IsNullOrWhiteSpace(ModelPath))
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
public DetectionConfig(string name, MLModelType modelType, string modelPath, bool isEnableGPU,string sCameraSourceId)
|
||||
string dir = Path.GetDirectoryName(ModelPath);
|
||||
string file = $"{Path.GetFileNameWithoutExtension(ModelPath)}.txt";
|
||||
return Path.Combine(dir, file);
|
||||
}
|
||||
set
|
||||
{
|
||||
if (_in_lable_path == value) return;
|
||||
_in_lable_path = value;
|
||||
OnPropertyChanged(nameof(In_lable_path));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
[Category("显示配置")]
|
||||
[DisplayName("显示位置")]
|
||||
[Description("检测信息显示位置")]
|
||||
public CustomizedPoint ShowLocation
|
||||
{
|
||||
get => _showLocation;
|
||||
set
|
||||
{
|
||||
if (_showLocation == value) return;
|
||||
_showLocation = value;
|
||||
OnPropertyChanged(nameof(ShowLocation));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 标签集合(需确保DetectionLable也实现INotifyPropertyChanged)
|
||||
/// </summary>
|
||||
public AntList<DetectionLable> DetectionLableList
|
||||
{
|
||||
get => _detectionLableList;
|
||||
set
|
||||
{
|
||||
if (_detectionLableList == value) return;
|
||||
_detectionLableList = value;
|
||||
OnPropertyChanged(nameof(DetectionLableList));
|
||||
}
|
||||
}
|
||||
|
||||
public AntList<SizeTreatParam> SizeTreatParamList
|
||||
{
|
||||
get => _sizeTreatParamList;
|
||||
set
|
||||
{
|
||||
if (_sizeTreatParamList == value) return;
|
||||
_sizeTreatParamList = value;
|
||||
OnPropertyChanged(nameof(SizeTreatParamList));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public bool SaveOKOriginal
|
||||
{
|
||||
get => _saveOKOriginal;
|
||||
set
|
||||
{
|
||||
if (_saveOKOriginal == value) return;
|
||||
_saveOKOriginal = value;
|
||||
OnPropertyChanged(nameof(SaveOKOriginal));
|
||||
}
|
||||
}
|
||||
|
||||
public bool SaveNGOriginal
|
||||
{
|
||||
get => _saveNGOriginal;
|
||||
set
|
||||
{
|
||||
if (_saveNGOriginal == value) return;
|
||||
_saveNGOriginal = value;
|
||||
OnPropertyChanged(nameof(SaveNGOriginal));
|
||||
}
|
||||
}
|
||||
public bool SaveOKDetect
|
||||
{
|
||||
get => _saveOKDetect;
|
||||
set
|
||||
{
|
||||
if (_saveOKDetect == value) return;
|
||||
_saveOKDetect = value;
|
||||
OnPropertyChanged(nameof(SaveOKDetect));
|
||||
}
|
||||
}
|
||||
public bool SaveNGDetect
|
||||
{
|
||||
get => _saveNGDetect;
|
||||
set
|
||||
{
|
||||
if (_saveNGDetect == value) return;
|
||||
_saveNGDetect = value;
|
||||
OnPropertyChanged(nameof(SaveNGDetect));
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region 构造函数
|
||||
public DetectionConfig() { }
|
||||
|
||||
public DetectionConfig(
|
||||
string name,
|
||||
ModelType modelType,
|
||||
string modelPath,
|
||||
bool isEnableGPU,
|
||||
string sCameraSourceId)
|
||||
{
|
||||
// 通过属性赋值触发通知
|
||||
ModelPath = modelPath ?? string.Empty;
|
||||
Name = name;
|
||||
ModelType = modelType;
|
||||
IsEnableGPU = isEnableGPU;
|
||||
Id = Guid.NewGuid().ToString();
|
||||
CameraSourceId = sCameraSourceId;
|
||||
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
|
||||
//大改预处理类
|
||||
@ -695,6 +939,7 @@ namespace DH.Commons.Enums
|
||||
}
|
||||
|
||||
private CellLink[] cellLinks;
|
||||
[JsonIgnore]
|
||||
public CellLink[] CellLinks
|
||||
{
|
||||
get { return cellLinks; }
|
||||
@ -713,10 +958,11 @@ namespace DH.Commons.Enums
|
||||
public class DetectionLable : NotifyProperty
|
||||
{
|
||||
private bool _selected = false;
|
||||
|
||||
private string _labelId;
|
||||
private string _labelName;
|
||||
private double _maxSource;
|
||||
private double _minSource;
|
||||
private double _maxScore;
|
||||
private double _minScore;
|
||||
private double _maxArea;
|
||||
private double _minArea;
|
||||
private ResultState _resultState = ResultState.ResultTBD;
|
||||
@ -736,6 +982,7 @@ namespace DH.Commons.Enums
|
||||
}
|
||||
|
||||
|
||||
|
||||
public string LabelId
|
||||
{
|
||||
get { return _labelId; }
|
||||
@ -758,25 +1005,25 @@ namespace DH.Commons.Enums
|
||||
}
|
||||
}
|
||||
|
||||
public double MaxSource
|
||||
public double MaxScore
|
||||
{
|
||||
get { return _maxSource; }
|
||||
get { return _maxScore; }
|
||||
set
|
||||
{
|
||||
if (_maxSource.Equals(value)) return;
|
||||
_maxSource = value;
|
||||
OnPropertyChanged(nameof(MaxSource));
|
||||
if (_maxScore.Equals(value)) return;
|
||||
_maxScore = value;
|
||||
OnPropertyChanged(nameof(MaxScore));
|
||||
}
|
||||
}
|
||||
|
||||
public double MinSource
|
||||
public double MinScore
|
||||
{
|
||||
get { return _minSource; }
|
||||
get { return _minScore; }
|
||||
set
|
||||
{
|
||||
if (_minSource.Equals(value)) return;
|
||||
_minSource = value;
|
||||
OnPropertyChanged(nameof(MinSource));
|
||||
if (_minScore.Equals(value)) return;
|
||||
_minScore = value;
|
||||
OnPropertyChanged(nameof(MinScore));
|
||||
}
|
||||
}
|
||||
|
||||
@ -814,6 +1061,7 @@ namespace DH.Commons.Enums
|
||||
}
|
||||
|
||||
private CellLink[] cellLinks;
|
||||
[JsonIgnore]
|
||||
public CellLink[] CellLinks
|
||||
{
|
||||
get { return cellLinks; }
|
||||
@ -826,7 +1074,126 @@ namespace DH.Commons.Enums
|
||||
}
|
||||
}
|
||||
|
||||
public class SizeTreatParam : NotifyProperty
|
||||
{
|
||||
private bool _selected = false;
|
||||
|
||||
|
||||
private bool _isEnable;
|
||||
private string _preName;
|
||||
private int _prePix;
|
||||
|
||||
private SizeEnum _preType;
|
||||
private string _resultShow;
|
||||
private string _outResultShow;
|
||||
|
||||
|
||||
private string _prePath;
|
||||
|
||||
|
||||
public bool Selected
|
||||
{
|
||||
get { return _selected; }
|
||||
set
|
||||
{
|
||||
if (_selected == value) return;
|
||||
_selected = value;
|
||||
OnPropertyChanged(nameof(Selected));
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsEnable
|
||||
{
|
||||
get { return _isEnable; }
|
||||
set
|
||||
{
|
||||
if (_isEnable == value) return;
|
||||
_isEnable = value;
|
||||
OnPropertyChanged(nameof(IsEnable));
|
||||
}
|
||||
}
|
||||
|
||||
public string PreName
|
||||
{
|
||||
get { return _preName; }
|
||||
set
|
||||
{
|
||||
if (_preName == value) return;
|
||||
_preName = value;
|
||||
OnPropertyChanged(nameof(PreName));
|
||||
}
|
||||
}
|
||||
|
||||
public SizeEnum PreType
|
||||
{
|
||||
get { return _preType; }
|
||||
set
|
||||
{
|
||||
if (_preType == value) return;
|
||||
_preType = value;
|
||||
OnPropertyChanged(nameof(PreType));
|
||||
}
|
||||
}
|
||||
|
||||
public int PrePix
|
||||
{
|
||||
get { return _prePix; }
|
||||
set
|
||||
{
|
||||
if (_prePix.Equals(value)) return;
|
||||
_prePix = value;
|
||||
OnPropertyChanged(nameof(PrePix));
|
||||
}
|
||||
}
|
||||
|
||||
public string ResultShow
|
||||
{
|
||||
get { return _resultShow; }
|
||||
set
|
||||
{
|
||||
if (_resultShow == value) return;
|
||||
_resultShow = value;
|
||||
OnPropertyChanged(nameof(ResultShow));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public string OutResultShow
|
||||
{
|
||||
get { return _outResultShow; }
|
||||
set
|
||||
{
|
||||
if (_outResultShow == value) return;
|
||||
_outResultShow = value;
|
||||
OnPropertyChanged(nameof(OutResultShow));
|
||||
}
|
||||
}
|
||||
|
||||
public string PrePath
|
||||
{
|
||||
get { return _prePath; }
|
||||
set
|
||||
{
|
||||
if (_prePath.Equals(value)) return;
|
||||
_prePath = value;
|
||||
OnPropertyChanged(nameof(PrePath));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private CellLink[] cellLinks;
|
||||
[JsonIgnore]
|
||||
public CellLink[] CellLinks
|
||||
{
|
||||
get { return cellLinks; }
|
||||
set
|
||||
{
|
||||
if (cellLinks == value) return;
|
||||
cellLinks = value;
|
||||
OnPropertyChanged(nameof(CellLinks));
|
||||
}
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// 识别目标定义 class:分类信息 Detection Segmentation:要识别的对象
|
||||
/// </summary>
|
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -16,9 +16,11 @@
|
||||
|
||||
<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>
|
||||
|
@ -1,16 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace DH.Commons.Enums
|
||||
{
|
||||
public class CameraInfo
|
||||
{
|
||||
public string CamName { get; set; }
|
||||
public string Serinum { get; set; }
|
||||
public string IP { get; set; }
|
||||
}
|
||||
|
||||
}
|
@ -7,12 +7,61 @@ using System.Threading.Tasks;
|
||||
|
||||
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
|
||||
{
|
||||
信捷XC_串口,
|
||||
信捷XC_网口,
|
||||
信捷XD_串口,
|
||||
信捷XD_网口
|
||||
[Description("信捷XC串口")]
|
||||
信捷XC串口 = 0,
|
||||
[Description("信捷XC网口")]
|
||||
信捷XC网口 = 1,
|
||||
[Description("信捷XD串口")]
|
||||
信捷XD串口 = 2,
|
||||
[Description("信捷XD网口")]
|
||||
信捷XD网口 = 3
|
||||
}
|
||||
|
||||
|
||||
@ -28,35 +77,70 @@ namespace DH.Commons.Enums
|
||||
public enum EnumPLCOutputIO
|
||||
{
|
||||
转盘方向=0,
|
||||
转盘速度=1,
|
||||
转盘使能=2,
|
||||
转盘启动=3,
|
||||
转盘清料=4,
|
||||
指示灯绿=5,
|
||||
指示灯黄=6,
|
||||
指示灯红=7,
|
||||
蜂鸣器=8,
|
||||
振动盘=9,
|
||||
皮带=10,
|
||||
工位1=11,
|
||||
工位2=12,
|
||||
工位3=13,
|
||||
工位4=14,
|
||||
工位5=15,
|
||||
OK料盒=16,
|
||||
NG料盒=17,
|
||||
OK吹气时间=18,
|
||||
NG吹气时间=19,
|
||||
产品计数=20,
|
||||
计数清零=21,
|
||||
工件最小值=22,
|
||||
工具最大值=23,
|
||||
启用心跳=24,
|
||||
心跳=25
|
||||
转盘速度,
|
||||
转盘使能,
|
||||
转盘启动,
|
||||
转盘清料,
|
||||
指示灯绿,
|
||||
指示灯黄,
|
||||
指示灯红,
|
||||
蜂鸣器,
|
||||
振动盘,
|
||||
皮带,
|
||||
工位1,
|
||||
工位2,
|
||||
工位3,
|
||||
工位4,
|
||||
工位5,
|
||||
工位6 ,
|
||||
工位7 ,
|
||||
工位8 ,
|
||||
工位9 ,
|
||||
工位10 ,
|
||||
相机触发时间,
|
||||
吹气时间,
|
||||
产品计数,
|
||||
计数清零,
|
||||
工件最小值,
|
||||
工件最大值,
|
||||
启用心跳,
|
||||
心跳地址,
|
||||
挡料电机回原点,
|
||||
挡料电机回原点速度,
|
||||
挡料电机速度,
|
||||
挡料电机顺时针,
|
||||
挡料电机逆时针,
|
||||
挡料电机位置,
|
||||
OK脉冲,
|
||||
NG脉冲,
|
||||
状态复位,
|
||||
启用定位,
|
||||
定位完成脉冲值
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
public enum EnumPLCDataType
|
||||
{
|
||||
单字整型,
|
||||
双字整型,
|
||||
浮点型,
|
||||
布尔型
|
||||
}
|
||||
|
||||
public enum EnumBool
|
||||
{
|
||||
关闭,
|
||||
启用
|
||||
}
|
||||
public enum EnumBool1
|
||||
{
|
||||
False,
|
||||
True
|
||||
}
|
||||
public enum StreamFormat
|
||||
{
|
||||
[Description("8位图像")]
|
||||
@ -542,5 +626,15 @@ namespace DH.Commons.Enums
|
||||
//[Description("插补模式")]
|
||||
//Coordinate = 11
|
||||
}
|
||||
|
||||
public enum CameraAcquisitionMode
|
||||
{
|
||||
连续模式=0,
|
||||
触发模式=1
|
||||
}
|
||||
|
||||
public enum CameraTriggerMode
|
||||
{
|
||||
软触发 = 0,
|
||||
硬触发 = 1
|
||||
}
|
||||
}
|
||||
|
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
|
||||
{
|
||||
}
|
||||
}
|
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>();
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
@ -76,159 +76,83 @@ namespace DH.Commons.Enums
|
||||
}
|
||||
}
|
||||
|
||||
//public static System.Windows.Media.Color GetEnumSelectedMediaColor(this Enum enumObj)
|
||||
//{
|
||||
// Type t = enumObj.GetType();
|
||||
// FieldInfo f = t.GetField(enumObj.ToString());
|
||||
|
||||
// ColorSelectAttribute attr = f.GetCustomAttribute<ColorSelectAttribute>();
|
||||
// if (attr != null)
|
||||
// {
|
||||
// var prop = typeof(System.Windows.Media.Colors).GetProperties().FirstOrDefault(p => p.Name == attr.SelectedColor);
|
||||
// if (prop != null)
|
||||
// {
|
||||
// return (System.Windows.Media.Color)prop.GetValue(null);
|
||||
// }
|
||||
// }
|
||||
// return System.Windows.Media.Colors.Transparent;
|
||||
//}
|
||||
|
||||
//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;
|
||||
// }
|
||||
//}
|
||||
|
||||
//public static string GetEnumSelectedColorString(this Enum enumObj)
|
||||
//{
|
||||
// Type t = enumObj.GetType();
|
||||
// FieldInfo f = t.GetField(enumObj.ToString());
|
||||
|
||||
// ColorSelectAttribute attr = f.GetCustomAttribute<ColorSelectAttribute>();
|
||||
// if (attr != null)
|
||||
// {
|
||||
// return attr.SelectedColor;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// return "Transparent";
|
||||
// }
|
||||
//}
|
||||
|
||||
// 根据描述获取枚举值(泛型方法)
|
||||
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="stateToBe"></param>
|
||||
/// <param name="currentState"></param>
|
||||
/// <returns></returns>
|
||||
//public static bool CheckPreStateValid(this Enum stateToBe, int currentState)
|
||||
//{
|
||||
// Type t = stateToBe.GetType();
|
||||
// FieldInfo f = t.GetField(stateToBe.ToString());
|
||||
/// <param name="enumType">枚举类型</param>
|
||||
/// <returns>描述文本列表</returns>
|
||||
public static List<string> GetEnumDescriptions(Type enumType)
|
||||
{
|
||||
// 验证类型是否为枚举
|
||||
if (!enumType.IsEnum)
|
||||
throw new ArgumentException("传入的类型必须是枚举类型", nameof(enumType));
|
||||
|
||||
// PreStateAttribute attr = f.GetCustomAttribute<PreStateAttribute>();
|
||||
// if (attr == null)
|
||||
// {
|
||||
// return true;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// return attr.CheckPreStateValid(currentState);
|
||||
// }
|
||||
//}
|
||||
var descriptions = new List<string>();
|
||||
|
||||
/// <summary>
|
||||
/// 设备状态定义
|
||||
/// 未初始化和异常状态无前置状态要求
|
||||
/// 初始化操作前置状态必须是未初始化、关闭状态和异常状态
|
||||
/// 打开前置必须是初始化和暂停
|
||||
/// 关闭前置必须是打开和暂停和异常
|
||||
/// 暂停前置必须是打开
|
||||
/// </summary>
|
||||
//public enum DeviceState
|
||||
//{
|
||||
// TBD = -1,
|
||||
foreach (var value in Enum.GetValues(enumType))
|
||||
{
|
||||
var fieldInfo = enumType.GetField(value.ToString());
|
||||
var attribute = fieldInfo.GetCustomAttribute<DescriptionAttribute>();
|
||||
descriptions.Add(attribute?.Description ?? value.ToString());
|
||||
}
|
||||
|
||||
// [ColorSelect("Gray")]
|
||||
// [FontColorSelect("Black")]
|
||||
// [Description("未初始化")]
|
||||
// DSUninit = 1,
|
||||
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();
|
||||
}
|
||||
|
||||
// [ColorSelect("Gold")]
|
||||
// [FontColorSelect("White")]
|
||||
// [PreState(1 + 2 + 4 + 8 + 32)]
|
||||
// [Description("初始化")]
|
||||
// DSInit = 2,
|
||||
public static System.Drawing.Color GetEnumSelectedColor(this Enum enumObj)
|
||||
{
|
||||
Type t = enumObj.GetType();
|
||||
FieldInfo f = t.GetField(enumObj.ToString());
|
||||
|
||||
// [ColorSelect("Lime")]
|
||||
// [FontColorSelect("Black")]
|
||||
// [PreState(2 + 4 + 16)]
|
||||
// [Description("运行中")]
|
||||
// DSOpen = 4,
|
||||
ColorSelectAttribute attr = f.GetCustomAttribute<ColorSelectAttribute>();
|
||||
if (attr != null)
|
||||
{
|
||||
return System.Drawing.Color.FromName(attr.SelectedColor);
|
||||
}
|
||||
else
|
||||
{
|
||||
return System.Drawing.Color.Transparent;
|
||||
}
|
||||
}
|
||||
|
||||
// [ColorSelect("Gray")]
|
||||
// [FontColorSelect("White")]
|
||||
// [PreState(1 + 4 + 8 + 16 + 32)]
|
||||
// [Description("关闭")]
|
||||
// DSClose = 8,
|
||||
public static System.Drawing.Color GetEnumSelectedFontColor(this Enum enumObj)
|
||||
{
|
||||
Type t = enumObj.GetType();
|
||||
FieldInfo f = t.GetField(enumObj.ToString());
|
||||
|
||||
// [ColorSelect("Gold")]
|
||||
// [FontColorSelect("White")]
|
||||
// [PreState(4 + 16)]
|
||||
// [Description("暂停")]
|
||||
// DSPause = 16,
|
||||
var attr = f.GetCustomAttribute<FontColorSelectAttribute>();
|
||||
if (attr != null)
|
||||
{
|
||||
return System.Drawing.Color.FromName(attr.SelectedColor);
|
||||
}
|
||||
else
|
||||
{
|
||||
return System.Drawing.Color.Transparent;
|
||||
}
|
||||
}
|
||||
|
||||
// [ColorSelect("Red")]
|
||||
// [FontColorSelect("White")]
|
||||
// [Description("异常")]
|
||||
// DSExcept = 32
|
||||
//}
|
||||
|
||||
///// <summary>
|
||||
///// 工序状态
|
||||
///// </summary>
|
||||
//public enum RunState
|
||||
//{
|
||||
// [ColorSelect("Gold")]
|
||||
// [Description("空闲")]
|
||||
// Idle = 1,
|
||||
// [ColorSelect("Lime")]
|
||||
// [Description("运行中")]
|
||||
// Running = 2,
|
||||
// [ColorSelect("Gray")]
|
||||
// [Description("停止")]
|
||||
// Stop = 3,
|
||||
// [ColorSelect("Red")]
|
||||
// [Description("宕机")]
|
||||
// Down = 99,
|
||||
//}
|
||||
|
||||
[Flags]
|
||||
public enum DeviceAttributeType
|
||||
@ -362,6 +286,37 @@ namespace DH.Commons.Enums
|
||||
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,
|
||||
@ -382,6 +337,59 @@ namespace DH.Commons.Enums
|
||||
// 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
|
||||
{
|
||||
@ -650,15 +658,15 @@ namespace DH.Commons.Enums
|
||||
public enum SizeEnum
|
||||
{
|
||||
[Description("圆形测量")]
|
||||
Circle = 1,
|
||||
圆形测量 = 1,
|
||||
[Description("直线测量")]
|
||||
Line = 2,
|
||||
直线测量 = 2,
|
||||
[Description("线线测量")]
|
||||
LineLine = 3,
|
||||
线线测量 = 3,
|
||||
[Description("线圆测量")]
|
||||
LineCircle = 4,
|
||||
线圆测量 = 4,
|
||||
[Description("高度测量")]
|
||||
Height = 5,
|
||||
高度测量 = 5,
|
||||
}
|
||||
|
||||
public enum MachineState
|
||||
|
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}";
|
||||
}
|
||||
}
|
||||
}
|
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");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
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>();
|
||||
}
|
||||
}
|
@ -24,7 +24,6 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\DH.Commons.Devies\DH.Commons.Devies.csproj" />
|
||||
<ProjectReference Include="..\DH.Commons\DH.Commons.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
|
@ -1,17 +1,21 @@
|
||||
using System.Diagnostics;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Diagnostics;
|
||||
using System.Reflection.Metadata;
|
||||
using System.Xml.Linq;
|
||||
using DH.Devices.Devices;
|
||||
using DH.Commons.Base;
|
||||
using DH.Commons.Enums;
|
||||
using DH.Commons.Helper;
|
||||
using DVPCameraType;
|
||||
using OpenCvSharp;
|
||||
using OpenCvSharp.Extensions;
|
||||
using static System.Net.Mime.MediaTypeNames;
|
||||
|
||||
using LogLevel = DH.Commons.Enums.EnumHelper.LogLevel;
|
||||
|
||||
|
||||
namespace DH.Devices.Camera
|
||||
{
|
||||
|
||||
public class Do3ThinkCamera : CameraBase
|
||||
public class Do3ThinkCamera : CameraBase, ILogger
|
||||
{
|
||||
|
||||
private dvpCameraInfo stDevInfo = new dvpCameraInfo();
|
||||
@ -24,8 +28,16 @@ namespace DH.Devices.Camera
|
||||
public dvpStreamFormat dvpStreamFormat = dvpStreamFormat.S_RGB24;
|
||||
public int m_CamCount = 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()
|
||||
{
|
||||
LoggerHelper.LogPath = "D://";
|
||||
LoggerHelper.LogPrefix = CameraName;
|
||||
|
||||
}
|
||||
|
||||
@ -78,17 +90,17 @@ namespace DH.Devices.Camera
|
||||
//GC.KeepAlive(pCallBackFunc);
|
||||
|
||||
//// ch:设置采集连续模式 | en:Set Continues Aquisition Mode
|
||||
//if (IIConfig.IsContinueMode)
|
||||
//{
|
||||
// // ch:设置触发模式为off || en:set trigger mode as off
|
||||
// nRet = DVPCamera.dvpSetTriggerState(m_handle, false);
|
||||
// if (dvpStatus.DVP_STATUS_OK != nRet)
|
||||
// {
|
||||
// throw new Exception("Set TriggerMode failed!");
|
||||
// }
|
||||
//}
|
||||
//else
|
||||
//{
|
||||
if (IsContinueMode)
|
||||
{
|
||||
// ch:设置触发模式为off || en:set trigger mode as off
|
||||
nRet = DVPCamera.dvpSetTriggerState(m_handle, false);
|
||||
if (dvpStatus.DVP_STATUS_OK != nRet)
|
||||
{
|
||||
throw new Exception("Set TriggerMode failed!");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// ch:设置触发模式为on || en:set trigger mode as on
|
||||
nRet = DVPCamera.dvpSetTriggerState(m_handle, true);
|
||||
if (dvpStatus.DVP_STATUS_OK != nRet)
|
||||
@ -97,8 +109,8 @@ namespace DH.Devices.Camera
|
||||
}
|
||||
|
||||
// 硬触发
|
||||
//if (IIConfig.IsHardwareTrigger)
|
||||
//{
|
||||
if (IsHardwareTrigger)
|
||||
{
|
||||
// ch:触发源选择:1 - Line1; | en:Trigger source select:1 - Line1;
|
||||
nRet = DVPCamera.dvpSetTriggerSource(m_handle, dvpTriggerSource.TRIGGER_SOURCE_LINE1);
|
||||
if (dvpStatus.DVP_STATUS_OK != nRet)
|
||||
@ -113,15 +125,15 @@ namespace DH.Devices.Camera
|
||||
{
|
||||
throw new Exception("Register image callback failed!");
|
||||
}
|
||||
//}
|
||||
//else // 软触发
|
||||
//{
|
||||
// nRet = DVPCamera.dvpSetTriggerSource(m_handle, dvpTriggerSource.TRIGGER_SOURCE_SOFTWARE);
|
||||
// if (dvpStatus.DVP_STATUS_OK != nRet)
|
||||
// {
|
||||
// throw new Exception("Set Software Trigger failed!");
|
||||
// }
|
||||
//}
|
||||
}
|
||||
else // 软触发
|
||||
{
|
||||
nRet = DVPCamera.dvpSetTriggerSource(m_handle, dvpTriggerSource.TRIGGER_SOURCE_SOFTWARE);
|
||||
if (dvpStatus.DVP_STATUS_OK != nRet)
|
||||
{
|
||||
throw new Exception("Set Software Trigger failed!");
|
||||
}
|
||||
}
|
||||
|
||||
// ch:开启抓图 || en: start grab image
|
||||
nRet = DVPCamera.dvpStart(m_handle);
|
||||
@ -130,40 +142,44 @@ namespace DH.Devices.Camera
|
||||
throw new Exception($"Start grabbing failed:{nRet:x8}");
|
||||
}
|
||||
//// 曝光
|
||||
//if (IIConfig.DefaultExposure != 0)
|
||||
//{
|
||||
// SetExposure(IIConfig.DefaultExposure);
|
||||
//}
|
||||
if (Exposure != 0)
|
||||
{
|
||||
SetExposure(Exposure);
|
||||
}
|
||||
//// 增益
|
||||
//if (IIConfig.Gain >= 0)
|
||||
//{
|
||||
// SetGain(IIConfig.Gain);
|
||||
//}
|
||||
//SetPictureRoi(IIConfig.VelocityPara.A_Pic_X, IIConfig.VelocityPara.A_Pic_Y, IIConfig.VelocityPara.Width, IIConfig.VelocityPara.Hight);
|
||||
if (Gain >= 0)
|
||||
{
|
||||
SetGain(Gain);
|
||||
}
|
||||
//全画幅
|
||||
if(!IsAllPicEnabled)
|
||||
SetPictureRoi((int)ROIX, (int)ROIY, (int)ROIW, (int)ROIH);
|
||||
|
||||
//// 设置 触发延迟
|
||||
//if (IIConfig.TriggerDelay > 0)
|
||||
//{
|
||||
// nRet = DVPCamera.dvpSetTriggerDelay(m_handle, IIConfig.TriggerDelay);
|
||||
// if (nRet != dvpStatus.DVP_STATUS_OK)
|
||||
// {
|
||||
// throw new Exception("Set TriggerDelay failed!");
|
||||
// }
|
||||
//}
|
||||
if (TriggerDelay > 0)
|
||||
{
|
||||
nRet = DVPCamera.dvpSetTriggerDelay(m_handle, TriggerDelay);
|
||||
if (nRet != dvpStatus.DVP_STATUS_OK)
|
||||
{
|
||||
throw new Exception("Set TriggerDelay failed!");
|
||||
}
|
||||
}
|
||||
|
||||
//// 信号消抖
|
||||
//if (IIConfig.LineDebouncerTime > 0)
|
||||
//{
|
||||
// nRet = DVPCamera.dvpSetTriggerJitterFilter(m_handle, IIConfig.LineDebouncerTime);
|
||||
// if (nRet != dvpStatus.DVP_STATUS_OK)
|
||||
// {
|
||||
// throw new Exception($"LineDebouncerTime set failed:{nRet}");
|
||||
// }
|
||||
//}
|
||||
if (LineDebouncerTime > 0)
|
||||
{
|
||||
nRet = DVPCamera.dvpSetTriggerJitterFilter(m_handle, LineDebouncerTime);
|
||||
if (nRet != dvpStatus.DVP_STATUS_OK)
|
||||
{
|
||||
throw new Exception($"LineDebouncerTime set failed:{nRet}");
|
||||
}
|
||||
}
|
||||
|
||||
//IIConfig.PropertyChanged -= IIConfig_PropertyChanged;
|
||||
//IIConfig.PropertyChanged += IIConfig_PropertyChanged;
|
||||
|
||||
|
||||
}
|
||||
return true;
|
||||
}
|
||||
catch
|
||||
@ -349,9 +365,17 @@ namespace DH.Devices.Camera
|
||||
break;
|
||||
}
|
||||
Mat smat = cvImage.Clone();
|
||||
var imageSet = new MatSet
|
||||
{
|
||||
|
||||
_mat = smat,
|
||||
|
||||
};
|
||||
InitialImageSet(imageSet);
|
||||
OnHImageOutput?.Invoke(DateTime.Now, this, smat);
|
||||
|
||||
|
||||
//存图
|
||||
DisplayAndSaveOriginImage(imageSet.Id,SnapshotCount);
|
||||
|
||||
|
||||
|
||||
@ -367,14 +391,93 @@ namespace DH.Devices.Camera
|
||||
}
|
||||
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()
|
||||
{
|
||||
try
|
||||
{
|
||||
dvpStreamState StreamState = new dvpStreamState();
|
||||
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)
|
||||
{
|
||||
// stop camera
|
||||
@ -409,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,7 +5,7 @@ using System.Runtime.InteropServices;
|
||||
using System.Xml.Linq;
|
||||
using DH.Commons.Enums;
|
||||
using static MvCamCtrl.NET.MyCamera;
|
||||
using DH.Devices.Devices;
|
||||
using DH.Commons.Base;
|
||||
|
||||
|
||||
|
||||
|
@ -12,10 +12,6 @@
|
||||
<Platforms>AnyCPU;x64</Platforms>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="System.IO.Ports" Version="9.0.2" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\DH.Commons\DH.Commons.csproj" />
|
||||
</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
@ -11,6 +11,14 @@
|
||||
<Platforms>AnyCPU;x64</Platforms>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
|
||||
<Optimize>False</Optimize>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<Optimize>False</Optimize>
|
||||
</PropertyGroup>
|
||||
|
||||
|
||||
|
||||
|
||||
@ -28,7 +36,6 @@
|
||||
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\DH.Commons.Devies\DH.Commons.Devies.csproj" />
|
||||
<ProjectReference Include="..\DH.Commons\DH.Commons.csproj" />
|
||||
<ProjectReference Include="..\DH.UI.Model.Winform\DH.UI.Model.Winform.csproj" />
|
||||
</ItemGroup>
|
||||
|
@ -13,7 +13,7 @@ using System.Threading.Tasks;
|
||||
using System.Security.Cryptography.Xml;
|
||||
using System.Runtime.InteropServices;
|
||||
using Newtonsoft.Json;
|
||||
using DH.Commons.Enums;
|
||||
using DH.Commons.Base;
|
||||
|
||||
|
||||
|
||||
@ -104,18 +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]}]}";
|
||||
//
|
||||
Console.WriteLine("检测结果JSON:" + json);
|
||||
#pragma warning disable CS8600 // 将 null 字面量或可能为 null 的值转换为非 null 类型。
|
||||
|
||||
HYoloResult detResult = JsonConvert.DeserializeObject<HYoloResult>(json);
|
||||
#pragma warning restore CS8600 // 将 null 字面量或可能为 null 的值转换为非 null 类型。
|
||||
|
||||
if (detResult == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
int iNum = detResult.HYolo.Count;
|
||||
#pragma warning disable CS0219 // 变量已被赋值,但从未使用过它的值
|
||||
|
||||
int IokNum = 0;
|
||||
#pragma warning restore CS0219 // 变量已被赋值,但从未使用过它的值
|
||||
|
||||
for (int ix = 0; ix < iNum; ix++)
|
||||
{
|
||||
var det = detResult.HYolo[ix];
|
||||
@ -145,7 +145,6 @@ namespace DH.Devices.Vision
|
||||
Mat originMat = new Mat();
|
||||
Mat detectMat = new Mat();
|
||||
|
||||
#pragma warning disable CS0168 // 声明了变量,但从未使用过
|
||||
try
|
||||
{
|
||||
if (req.mImage == null)
|
||||
|
@ -12,7 +12,7 @@ using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Runtime.InteropServices;
|
||||
using Newtonsoft.Json;
|
||||
using DH.Commons.Enums;
|
||||
using DH.Commons.Base;
|
||||
|
||||
|
||||
namespace DH.Devices.Vision
|
||||
|
@ -13,7 +13,7 @@ using System.Threading.Tasks;
|
||||
using System.Runtime.InteropServices;
|
||||
using Newtonsoft.Json;
|
||||
using System.Xml;
|
||||
using DH.Commons.Enums;
|
||||
using DH.Commons.Base;
|
||||
|
||||
|
||||
namespace DH.Devices.Vision
|
||||
@ -136,9 +136,8 @@ 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]}]}";
|
||||
//
|
||||
Console.WriteLine("检测结果JSON:" + json);
|
||||
#pragma warning disable CS8600 // 将 null 字面量或可能为 null 的值转换为非 null 类型。
|
||||
|
||||
SegResult detResult = JsonConvert.DeserializeObject<SegResult>(json);
|
||||
#pragma warning restore CS8600 // 将 null 字面量或可能为 null 的值转换为非 null 类型。
|
||||
if (detResult == null)
|
||||
{
|
||||
return;
|
||||
@ -176,7 +175,6 @@ namespace DH.Devices.Vision
|
||||
MLResult mlResult = new MLResult();
|
||||
Mat originMat=new Mat() ;
|
||||
Mat detectMat= new Mat();
|
||||
#pragma warning disable CS0168 // 声明了变量,但从未使用过
|
||||
try
|
||||
{
|
||||
if (req.mImage == null)
|
||||
@ -266,25 +264,24 @@ namespace DH.Devices.Vision
|
||||
// 释放 Mat 资源
|
||||
if (detectMat != null)
|
||||
{
|
||||
detectMat.Dispose();
|
||||
#pragma warning disable CS8600 // 将 null 字面量或可能为 null 的值转换为非 null 类型。
|
||||
|
||||
detectMat = null;
|
||||
#pragma warning restore CS8600 // 将 null 字面量或可能为 null 的值转换为非 null 类型。
|
||||
|
||||
}
|
||||
|
||||
if (originMat != null)
|
||||
{
|
||||
originMat.Dispose();
|
||||
#pragma warning disable CS8600 // 将 null 字面量或可能为 null 的值转换为非 null 类型。
|
||||
|
||||
originMat = null;
|
||||
#pragma warning restore CS8600 // 将 null 字面量或可能为 null 的值转换为非 null 类型。
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
// GC.Collect();
|
||||
}
|
||||
#pragma warning restore CS0168 // 声明了变量,但从未使用过
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
using DH.Commons.Enums;
|
||||
using DH.Devices.Devices;
|
||||
using DH.Commons.Base;
|
||||
using DH.Commons.Enums;
|
||||
using DH.Commons.Helper;
|
||||
using DH.UI.Model.Winform;
|
||||
using HalconDotNet;
|
||||
using OpenCvSharp;
|
||||
@ -7,6 +8,8 @@ using OpenCvSharp.Extensions;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Diagnostics.Eventing.Reader;
|
||||
using System.Drawing.Imaging;
|
||||
using System.Linq;
|
||||
using System.Runtime.ExceptionServices;
|
||||
using System.Text;
|
||||
@ -15,7 +18,8 @@ using System.Windows.Forms;
|
||||
using System.Xml.Linq;
|
||||
using XKRS.UI.Model.Winform;
|
||||
using static DH.Commons.Enums.EnumHelper;
|
||||
using ResultState = DH.Commons.Enums.ResultState;
|
||||
using LogLevel = DH.Commons.Enums.EnumHelper.LogLevel;
|
||||
using ResultState = DH.Commons.Base.ResultState;
|
||||
|
||||
|
||||
namespace DH.Devices.Vision
|
||||
@ -36,7 +40,20 @@ namespace DH.Devices.Vision
|
||||
// ImageSaveHelper.OnImageSaveExceptionRaised += ImageSaveHelper_OnImageSaveExceptionRaised;
|
||||
// base.Init();
|
||||
}
|
||||
|
||||
public void Stop()
|
||||
{
|
||||
SimboStationMLEngineList.ToList().ForEach(sm =>
|
||||
{
|
||||
if (sm.IsUseGPU)
|
||||
{
|
||||
sm.StationMLEngine.Dispose();
|
||||
}
|
||||
else
|
||||
{
|
||||
sm.StationMLEngine.Dispose2();
|
||||
}
|
||||
});
|
||||
}
|
||||
//private void ImageSaveHelper_OnImageSaveExceptionRaised(DateTime dt, string msg)
|
||||
//{
|
||||
// LogAsync(new LogMsg(dt, LogLevel.Error, msg));
|
||||
@ -57,16 +74,30 @@ namespace DH.Devices.Vision
|
||||
|
||||
if (detectConfig == null)
|
||||
{
|
||||
|
||||
LogAsync(DateTime.Now, LogLevel.Exception, $"异常:未能获取检测配置");
|
||||
//未能获得检测配置
|
||||
return detectResult;
|
||||
}
|
||||
detectResult.DetectName = detectConfig.Name;
|
||||
detectResult.ImageSaveDirectory=detectConfig.ImageSaveDirectory;
|
||||
detectResult.SaveNGDetect=detectConfig.SaveNGDetect;
|
||||
detectResult.SaveNGOriginal=detectConfig.SaveNGOriginal;
|
||||
detectResult.SaveOKDetect=detectConfig.SaveOKDetect;
|
||||
detectResult.SaveOKOriginal=detectConfig.SaveOKOriginal;
|
||||
Mat OriginImage = originImgSet.Clone();
|
||||
detectResult.DetectionOriginImage = CopyBitmapWithLockBits(OriginImage.ToBitmap());
|
||||
//detectResult.DetectionOriginImage = originImgSet.Clone().ToBitmap();
|
||||
Stopwatch sw = new Stopwatch();
|
||||
#region 1.预处理
|
||||
|
||||
sw.Start();
|
||||
using (Mat PreTMat = originImgSet.Clone())
|
||||
{
|
||||
PreTreated(detectConfig, detectResult, PreTMat);
|
||||
PreTreated2(detectConfig, detectResult, PreTMat);
|
||||
}
|
||||
sw.Stop();
|
||||
LogAsync(DateTime.Now, LogLevel.Information, $"产品:{detectResult.Pid} {detectConfig.Name}预处理耗时:{sw.ElapsedMilliseconds}ms。SpecsResults:{string.Join(";", detectResult.realSpecs.Select(u => $"{u.Code} {u.ActualValue}"))}");
|
||||
// 工位2尺寸测量
|
||||
|
||||
|
||||
|
||||
@ -98,7 +129,7 @@ namespace DH.Devices.Vision
|
||||
}
|
||||
|
||||
#region 2.深度学习推理
|
||||
//LogAsync(DateTime.Now, LogLevel.Information, $"{detectConfig.Name} 产品{detectResult.TempPid} 模型检测执行");
|
||||
LogAsync(DateTime.Now, LogLevel.Information, $"{detectConfig.Name} 产品{detectResult.TempPid} 模型检测执行");
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(detectConfig.ModelPath))
|
||||
{
|
||||
@ -113,7 +144,7 @@ namespace DH.Devices.Vision
|
||||
// req.Score = IIConfig.Score;
|
||||
req.mImage = originImgSet.Clone();
|
||||
|
||||
req.in_lable_path = detectConfig.in_lable_path;
|
||||
req.in_lable_path = detectConfig.In_lable_path;
|
||||
|
||||
req.confThreshold = detectConfig.ModelconfThreshold;
|
||||
req.iouThreshold = 0.3f;
|
||||
@ -121,16 +152,16 @@ namespace DH.Devices.Vision
|
||||
req.out_node_name = "output0";
|
||||
switch (detectConfig.ModelType)
|
||||
{
|
||||
case MLModelType.ImageClassification:
|
||||
case ModelType.图像分类:
|
||||
break;
|
||||
case MLModelType.ObjectDetection:
|
||||
case ModelType.目标检测:
|
||||
|
||||
break;
|
||||
case MLModelType.SemanticSegmentation:
|
||||
case ModelType.语义分割:
|
||||
break;
|
||||
case MLModelType.InstanceSegmentation:
|
||||
case ModelType.实例分割:
|
||||
break;
|
||||
case MLModelType.ObjectGPUDetection:
|
||||
case ModelType.目标检测GPU:
|
||||
|
||||
break;
|
||||
default:
|
||||
@ -140,7 +171,7 @@ namespace DH.Devices.Vision
|
||||
// LogAsync(DateTime.Now, LogLevel.Information, $"{detectConfig.Name} 产品{detectResult.TempPid} RunInference BEGIN");
|
||||
mlWatch.Start();
|
||||
//20230802改成多线程推理 RunInferenceFixed
|
||||
|
||||
// MLResult result = new MLResult();
|
||||
var result = mlSet.StationMLEngine.RunInference(req);
|
||||
// var result = mlSet.StationMLEngine.RunInferenceFixed(req);
|
||||
mlWatch.Stop();
|
||||
@ -180,6 +211,8 @@ namespace DH.Devices.Vision
|
||||
|
||||
if (result == null || (result != null && !result.IsSuccess))
|
||||
{
|
||||
LogAsync(DateTime.Now, LogLevel.Exception, $"CoreInx:{mlSet.GPUNo} 产品:{detectResult.Pid} {detectConfig.Name} 模型检测异常,{result?.ResultMessage}");
|
||||
|
||||
detectResult.IsMLDetectDone = false;
|
||||
}
|
||||
if (result != null && result.IsSuccess)
|
||||
@ -187,9 +220,13 @@ namespace DH.Devices.Vision
|
||||
detectResult.DetectDetails = result.ResultDetails;
|
||||
if (detectResult.DetectDetails != null)
|
||||
{
|
||||
LogAsync(DateTime.Now, LogLevel.Information, $"CoreInx:{mlSet.GPUNo} 产品:{detectResult.Pid} {detectResult.DetectName} 模型检测总耗时:{mlWatch.ElapsedMilliseconds} ms {result.ResultMessage},{string.Join(";", detectResult.DetectDetails.Select(u => $"{u.LabelName} X:{u.Rect.X} Y:{u.Rect.Y} Area:{u.Area.ToString("f2")} W:{u.Rect.Width} H:{u.Rect.Height}"))}");
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
LogAsync(DateTime.Now, LogLevel.Exception, $"CoreInx:{mlSet.GPUNo} 产品:{detectResult.Pid} {detectConfig.Name} 模型检测异常返回 null");
|
||||
|
||||
detectResult.IsMLDetectDone = false;
|
||||
}
|
||||
}
|
||||
@ -207,18 +244,13 @@ namespace DH.Devices.Vision
|
||||
|
||||
|
||||
// 当前检测项的 过滤条件
|
||||
//var conditionList = detectConfig.DetectionFilterList
|
||||
// .Where(u => u.IsEnabled && u.LabelName == d.LabelName)
|
||||
// .GroupBy(u => u.ResultState)
|
||||
// .OrderBy(u => u.Key)
|
||||
// .ToList();
|
||||
//当前检测项的 过滤条件
|
||||
var conditionList = detectConfig.DetectionFilterList
|
||||
.Where(u => u.IsEnabled && u.LabelName == d.LabelName)
|
||||
var conditionList = detectConfig.DetectionLableList
|
||||
.Where(u=>u.LabelName == d.LabelName)
|
||||
.GroupBy(u => u.ResultState)
|
||||
.OrderBy(u => u.Key)
|
||||
.ToList();
|
||||
|
||||
|
||||
if (conditionList.Count == 0)
|
||||
{
|
||||
|
||||
@ -236,8 +268,8 @@ namespace DH.Devices.Vision
|
||||
}
|
||||
|
||||
|
||||
foreach (IGrouping<ResultState, DetectionFilter> group in conditionList)
|
||||
{
|
||||
//foreach (IGrouping<ResultState, DetectionFilter> group in conditionList)
|
||||
//{
|
||||
// bool b = group.ToList().Any(f =>
|
||||
// {
|
||||
// return f.FilterOperation(d);
|
||||
@ -250,16 +282,8 @@ namespace DH.Devices.Vision
|
||||
// break;
|
||||
// }
|
||||
|
||||
if (group.Any(f => f.FilterOperation(d)))
|
||||
{
|
||||
d.FinalResult = group.Key;
|
||||
break;
|
||||
}
|
||||
//else
|
||||
//{
|
||||
// d.FinalResult = d.InferenceResult = ResultState.OK;
|
||||
|
||||
//}
|
||||
}
|
||||
});
|
||||
#endregion
|
||||
#region 5.统计缺陷过滤结果或预处理直接NG
|
||||
@ -280,6 +304,7 @@ namespace DH.Devices.Vision
|
||||
#endregion
|
||||
|
||||
|
||||
LogAsync(DateTime.Now, LogLevel.Information, $"{detectConfig.Name} 检测结果:{detectResult.ResultState.GetEnumDescription()}");
|
||||
|
||||
|
||||
|
||||
@ -395,18 +420,18 @@ namespace DH.Devices.Vision
|
||||
// 根据算法类型创建不同的实例
|
||||
switch (dc.ModelType)
|
||||
{
|
||||
case MLModelType.ImageClassification:
|
||||
case ModelType.图像分类:
|
||||
break;
|
||||
case MLModelType.ObjectDetection:
|
||||
case ModelType.目标检测:
|
||||
mLEngineSet.StationMLEngine = new SimboObjectDetection();
|
||||
break;
|
||||
case MLModelType.SemanticSegmentation:
|
||||
case ModelType.语义分割:
|
||||
|
||||
break;
|
||||
case MLModelType.InstanceSegmentation:
|
||||
case ModelType.实例分割:
|
||||
mLEngineSet.StationMLEngine = new SimboInstanceSegmentation();
|
||||
break;
|
||||
case MLModelType.ObjectGPUDetection:
|
||||
case ModelType.目标检测GPU:
|
||||
mLEngineSet.StationMLEngine = new SimboDetection();
|
||||
break;
|
||||
default:
|
||||
@ -430,12 +455,14 @@ namespace DH.Devices.Vision
|
||||
{
|
||||
// throw new ProcessException("异常:模型加载异常", null);
|
||||
}
|
||||
//LogAsync(DateTime.Now, LogLevel.Information, $"模型加载成功;是否GPU:{isGPU} CoreInx:{coreInx} - {dc.Name}" + $" {dc.ModelType.GetEnumDescription()}:{dc.ModelPath}");
|
||||
LogAsync(DateTime.Now, LogLevel.Information, $"模型加载成功;是否GPU:{isGPU} CoreInx:{coreInx} - {dc.Name}" + $" {dc.ModelType.GetEnumDescription()}:{dc.ModelPath}");
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
//throw new ProcessException($"异常:是否GPU:{isGPU} CoreInx:{coreInx} - {dc.Name}模型加载异常:{ex.GetExceptionMessage()}");
|
||||
// LogAsync(DateTime.Now, LogLevel.Error, $"模型加载成功;是否GPU:{isGPU} CoreInx:{coreInx} - {dc.Name}" + $" {dc.ModelType.GetEnumDescription()}:{dc.ModelPath}");
|
||||
|
||||
throw new ProcessException($"异常:是否GPU:{isGPU} CoreInx:{coreInx} - {dc.Name}模型加载异常:{ex.GetExceptionMessage()}");
|
||||
}
|
||||
return mLEngineSet;
|
||||
}
|
||||
@ -519,7 +546,7 @@ namespace DH.Devices.Vision
|
||||
if (!tool.RunProcedure(out string errorMsg, out _))
|
||||
{
|
||||
// detectResult.PreTreatedFlag = false;
|
||||
|
||||
LogAsync(DateTime.Now, LogLevel.Exception, $"{detectConfig.Name}预处理异常,{errorMsg}");
|
||||
detectResult.IsPreTreatDone = false;
|
||||
|
||||
|
||||
@ -534,12 +561,82 @@ namespace DH.Devices.Vision
|
||||
// detectResult.IsPreTreatDone = detectResult.VisionImageSet.PreTreatedFlag = preTreatRet == 1;
|
||||
//detectResult.IsPreTreatDone = detectResult.VisionImageSet.PreTreatedFlag = true;
|
||||
// detectResult.VisionImageSet.PreTreatedTime = DateTime.Now;
|
||||
switch (preTreatRet)
|
||||
{
|
||||
case 0: // 预处理算法无异常
|
||||
{
|
||||
|
||||
for (int i = 0; i < detectConfig.OUTPreTreatParams.Count; i++)
|
||||
{
|
||||
|
||||
var param = detectConfig.OUTPreTreatParams[i];
|
||||
tool.InputTupleDic[param.Name] = double.Parse(param.Value);
|
||||
|
||||
var Value = tool.GetResultTuple(param.Name);
|
||||
|
||||
// 显示结果
|
||||
IndexedSpec specRCricularity = new()
|
||||
{
|
||||
Code = param.Name,
|
||||
ActualValue = Value
|
||||
};
|
||||
detectResult.realSpecs.Add(specRCricularity);
|
||||
}
|
||||
detectResult.IsPreTreatNG = false;
|
||||
detectResult.IsPreTreatDone = true;
|
||||
}
|
||||
break;
|
||||
case -111: // 检测结果为NG
|
||||
{
|
||||
/// detectResult.VisionImageSet.DetectionResultImage =
|
||||
// tool.GetResultObject("OUTPUT_PreTreatedImage").ConvertHImageToBitmap();
|
||||
for (int i = 0; i < detectConfig.OUTPreTreatParams.Count; i++)
|
||||
{
|
||||
|
||||
var param = detectConfig.OUTPreTreatParams[i];
|
||||
|
||||
var Value = tool.GetResultTuple(param.Name);
|
||||
|
||||
// 显示结果
|
||||
IndexedSpec specRCricularity = new()
|
||||
{
|
||||
Code = param.Name,
|
||||
ActualValue = Value
|
||||
};
|
||||
detectResult.realSpecs.Add(specRCricularity);
|
||||
}
|
||||
// 结果为NG
|
||||
detectResult.ResultState = ResultState.DetectNG;
|
||||
detectResult.IsPreTreatNG = true;
|
||||
detectResult.IsPreTreatDone = true;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
case -999: // 算法异常
|
||||
{
|
||||
// 算法异常时,结果图
|
||||
// detectResult.VisionImageSet.DetectionResultImage =
|
||||
// tool.GetResultObject("OUTPUT_PreTreatedImage").ConvertHImageToBitmap();
|
||||
|
||||
for (int i = 0; i < detectConfig.OUTPreTreatParams.Count; i++)
|
||||
{
|
||||
|
||||
|
||||
var param = detectConfig.OUTPreTreatParams[i];
|
||||
// 显示结果
|
||||
IndexedSpec specRCricularity = new()
|
||||
{
|
||||
Code = param.Name,
|
||||
ActualValue = -1,
|
||||
};
|
||||
detectResult.realSpecs.Add(specRCricularity);
|
||||
}
|
||||
|
||||
// 结果保持TBD
|
||||
detectResult.IsPreTreatDone = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@ -571,7 +668,7 @@ namespace DH.Devices.Vision
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
||||
LogAsync(DateTime.Now, LogLevel.Exception, $"{detectConfig.Name}预处理异常:{ex.GetExceptionMessage()}");
|
||||
}
|
||||
finally
|
||||
{
|
||||
@ -582,6 +679,266 @@ namespace DH.Devices.Vision
|
||||
}
|
||||
|
||||
}
|
||||
public void PreTreated2(DetectionConfig detectConfig, DetectStationResult detectResult,Mat MhImage)
|
||||
{
|
||||
try
|
||||
{
|
||||
|
||||
if (detectConfig.SizeTreatParamList != null && detectConfig.SizeTreatParamList.Count > 0)
|
||||
{
|
||||
foreach (var preTreat in detectConfig.SizeTreatParamList)
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(preTreat.PrePath))
|
||||
{
|
||||
string toolKey = preTreat.PrePath;
|
||||
if (!HalconToolDict.ContainsKey(toolKey))
|
||||
{
|
||||
LogAsync(DateTime.Now, LogLevel.Exception, $"{detectConfig.Name}未获取预处理{preTreat.PreName}算法");
|
||||
return;
|
||||
}
|
||||
//Mean_Thre Deviation_Thre Mean_standard Deviation_standard
|
||||
var tool = HalconToolDict[toolKey];
|
||||
|
||||
//tool.InputTupleDic["Mean_Thre"] = 123;
|
||||
List<PreTreatParam> PreParams = new List<PreTreatParam>();
|
||||
preoutparms(PreParams, preTreat.ResultShow);
|
||||
for (int i = 0; i < PreParams.Count(); i++)
|
||||
{
|
||||
var param = PreParams[i];
|
||||
if (param.Value.Contains(","))
|
||||
{
|
||||
string[] strings = param.Value.Split(",");
|
||||
float[] array = strings.Select(s => float.Parse(s)).ToArray();
|
||||
HTuple hTupleArray = new HTuple(array);
|
||||
|
||||
tool.InputTupleDic[param.Name] = hTupleArray;
|
||||
}
|
||||
else
|
||||
{
|
||||
tool.InputTupleDic[param.Name] = double.Parse(param.Value);// param.Value.ToInt();
|
||||
}
|
||||
|
||||
IndexedSpec spec1 = new IndexedSpec();
|
||||
|
||||
switch (preTreat.PreType)
|
||||
{
|
||||
case SizeEnum.线线测量:
|
||||
|
||||
break;
|
||||
case SizeEnum.线圆测量:
|
||||
|
||||
break;
|
||||
case SizeEnum.圆形测量:
|
||||
break;
|
||||
case SizeEnum.高度测量:
|
||||
spec1.Code = $"in-{param.Name}";
|
||||
spec1.ActualValue = double.Parse(param.Value);
|
||||
break;
|
||||
case SizeEnum.直线测量:
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
|
||||
detectResult.realSpecs.Add(spec1);
|
||||
}
|
||||
//// 指定保存路径
|
||||
//string filePath = @"D:\saved_image.jpg"; // 你可以根据需要更改路径和文件名
|
||||
|
||||
//// 使用WriteImage保存图像
|
||||
//detectResult.VisionImageSet.HImage.WriteImage("jpeg", 0, filePath); // "jpeg" 表示图像格式,0表示不使用压缩
|
||||
HObject obj = OpenCVHelper.MatToHImage(MhImage);
|
||||
HImage hImage = HalconHelper.ConvertHObjectToHImage(obj);
|
||||
tool.InputImageDic["INPUT_Image"] = hImage;
|
||||
if (!tool.RunProcedure(out string errorMsg, out _))
|
||||
{
|
||||
// detectResult.VisionImageSet.PreTreatedFlag = false;
|
||||
LogAsync(DateTime.Now, LogLevel.Exception, $"{detectConfig.Name}预处理异常,{errorMsg}");
|
||||
detectResult.IsPreTreatDone = false;
|
||||
|
||||
// HandleDetectDone(detectResult, detectConfig);
|
||||
return;
|
||||
}
|
||||
|
||||
var preTreatRet = tool.GetResultTuple("OUTPUT_Flag").I;
|
||||
//double MatchScore = 1;
|
||||
//MatchScore = tool.GetResultTuple("MatchScore");
|
||||
|
||||
|
||||
detectResult.IsPreTreatDone = preTreatRet == 1;
|
||||
// detectResult.IsPreTreatDone = detectResult.VisionImageSet.PreTreatedFlag = true;
|
||||
// detectResult.VisionImageSet.PreTreatedTime = DateTime.Now;
|
||||
|
||||
|
||||
//IndexedSpec spec1 = new IndexedSpec();
|
||||
//spec1.Code = "score";
|
||||
//spec1.ActualValue = MatchScore;
|
||||
|
||||
|
||||
//detectResult.realSpecs.Add(spec1);
|
||||
;
|
||||
|
||||
|
||||
// 2023/10/16 新增预处理结果反馈,如果预处理结果为NG,直接返回
|
||||
if (preTreatRet != 0)
|
||||
{
|
||||
detectResult.ResultState = ResultState.DetectNG;
|
||||
|
||||
detectResult.IsPreTreatNG = true;
|
||||
// detectResult.VisionImageSet.DetectionResultImage = detectResult.VisionImageSet.MLImage.ConvertHImageToBitmap();
|
||||
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
switch (preTreat.PreType)
|
||||
{
|
||||
case SizeEnum.线线测量:
|
||||
isPreOutparams(ref detectResult, preTreat, tool, ref preTreatRet);
|
||||
break;
|
||||
case SizeEnum.线圆测量:
|
||||
isPreOutparams(ref detectResult, preTreat, tool, ref preTreatRet);
|
||||
break;
|
||||
case SizeEnum.圆形测量:
|
||||
break;
|
||||
case SizeEnum.高度测量:
|
||||
{
|
||||
|
||||
isPreOutparams(ref detectResult, preTreat, tool, ref preTreatRet);
|
||||
}
|
||||
break;
|
||||
case SizeEnum.直线测量:
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogAsync(DateTime.Now, LogLevel.Exception, $"{detectConfig.Name}尺寸预处理异常:{ex.GetExceptionMessage()}");
|
||||
}
|
||||
finally
|
||||
{
|
||||
//detectResult.VisionImageSet.HImage?.Dispose();
|
||||
//detectResult.VisionImageSet.HImage = null;
|
||||
}
|
||||
}
|
||||
public void isPreOutparams(ref DetectStationResult detectResult, SizeTreatParam preTreat, HDevEngineTool tool, ref int preTreatRet)
|
||||
{
|
||||
List<PreTreatParam> PreParams = new List<PreTreatParam>();
|
||||
preoutparms(PreParams, preTreat.OutResultShow);
|
||||
|
||||
for (int i = 0; i < PreParams.Count; i++)
|
||||
{
|
||||
var param = PreParams[i];
|
||||
double dParam = double.Parse(param.Value);
|
||||
double heights = tool.GetResultTuple(param.Name).D;
|
||||
switch (preTreat.PreType)
|
||||
{
|
||||
case SizeEnum.高度测量:
|
||||
|
||||
|
||||
IndexedSpec spec2 = new IndexedSpec();
|
||||
spec2.Code = $"out-{param.Name}";
|
||||
spec2.ActualValue = Convert.ToDouble(param.Value);
|
||||
|
||||
|
||||
detectResult.realSpecs.Add(spec2);
|
||||
|
||||
|
||||
IndexedSpec spec1 = new IndexedSpec();
|
||||
spec1.Code = $"actual-{param.Name}";
|
||||
spec1.ActualValue = heights;
|
||||
|
||||
|
||||
detectResult.realSpecs.Add(spec1);
|
||||
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
|
||||
|
||||
if ((heights > dParam - preTreat.PrePix) && (heights < dParam + preTreat.PrePix))
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
preTreatRet = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (preTreatRet != 0)
|
||||
{
|
||||
detectResult.ResultState = ResultState.DetectNG;
|
||||
|
||||
detectResult.IsPreTreatNG = true;
|
||||
//detectResult.VisionImageSet.DetectionResultImage = detectResult.VisionImageSet.MLImage.ConvertHImageToBitmap();
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
// detectResult.VisionImageSet.DetectionResultImage = detectResult.VisionImageSet.MLImage.ConvertHImageToBitmap();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void preoutparms(List<PreTreatParam> preTreatParams, string defectRows)
|
||||
{
|
||||
// 解析 ReslutShow 字符串,构建 PreTreatParam 列表
|
||||
if (!string.IsNullOrEmpty(defectRows))
|
||||
{
|
||||
var keyValuePairs = defectRows.Split(';');
|
||||
|
||||
foreach (var pair in keyValuePairs)
|
||||
{
|
||||
var parts = pair.Split(':');
|
||||
if (parts.Length == 2)
|
||||
{
|
||||
PreTreatParam param;
|
||||
if (parts[1].Trim().Contains(","))
|
||||
{
|
||||
param = new PreTreatParam
|
||||
{
|
||||
Name = parts[0].Trim(), // 去除多余的空格
|
||||
Value = parts[1].Trim() // 转换为 double,失败则为0
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
double dvalue = double.TryParse(parts[1].Trim(), out double value) ? value : 0;
|
||||
|
||||
param = new PreTreatParam
|
||||
{
|
||||
Name = parts[0].Trim(), // 去除多余的空格
|
||||
Value = dvalue.ToString() // 转换为 double,失败则为0
|
||||
};
|
||||
}
|
||||
|
||||
preTreatParams.Add(param);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 显示检测结果
|
||||
@ -606,14 +963,14 @@ namespace DH.Devices.Vision
|
||||
});
|
||||
}
|
||||
|
||||
//if (detectResult.realSpecs != null && detectResult.realSpecs?.Count > 0)
|
||||
//{
|
||||
// detectResult.realSpecs.ForEach(d =>
|
||||
// {
|
||||
// displayTxt +=
|
||||
// $"{d.Code} :{d.ActualValue} \r\n";
|
||||
// });
|
||||
//}
|
||||
if (detectResult.realSpecs != null && detectResult.realSpecs?.Count > 0)
|
||||
{
|
||||
detectResult.realSpecs.ForEach(d =>
|
||||
{
|
||||
displayTxt +=
|
||||
$"{d.Code} :{d.ActualValue} \r\n";
|
||||
});
|
||||
}
|
||||
Bitmap resultMask =result.ToBitmap();
|
||||
//if (detectResult.VisionImageSet.DetectionResultImage == null && detectResult.VisionImageSet.SizeResultImage == null)
|
||||
//{
|
||||
@ -648,8 +1005,8 @@ namespace DH.Devices.Vision
|
||||
List<IShapeElement> detectionResultShapesClone = new List<IShapeElement>(detectionResultShapes);
|
||||
|
||||
DetectionDone(DetectionId, resultMask, detectionResultShapes);
|
||||
|
||||
//SaveDetectResultImageAsync(detectResult);
|
||||
//detectResult.DetectionOriginImage = CopyBitmapWithLockBits(resultMask);
|
||||
SaveDetectResultImageAsync(detectResult);
|
||||
// SaveDetectResultCSVAsync(detectResult);
|
||||
}
|
||||
catch (Exception ex)
|
||||
@ -664,6 +1021,343 @@ namespace DH.Devices.Vision
|
||||
}
|
||||
});
|
||||
}
|
||||
public static Bitmap CopyBitmapWithLockBits(Bitmap original)
|
||||
{
|
||||
Bitmap copy = new Bitmap(original.Width, original.Height, original.PixelFormat);
|
||||
BitmapData originalData = original.LockBits(
|
||||
new Rectangle(0, 0, original.Width, original.Height),
|
||||
ImageLockMode.ReadOnly,
|
||||
original.PixelFormat
|
||||
);
|
||||
BitmapData copyData = copy.LockBits(
|
||||
new Rectangle(0, 0, copy.Width, copy.Height),
|
||||
ImageLockMode.WriteOnly,
|
||||
copy.PixelFormat
|
||||
);
|
||||
int bytesPerPixel = Image.GetPixelFormatSize(original.PixelFormat) / 8;
|
||||
int byteCount = originalData.Stride * original.Height;
|
||||
byte[] buffer = new byte[byteCount];
|
||||
System.Runtime.InteropServices.Marshal.Copy(originalData.Scan0, buffer, 0, byteCount);
|
||||
System.Runtime.InteropServices.Marshal.Copy(buffer, 0, copyData.Scan0, byteCount);
|
||||
original.UnlockBits(originalData);
|
||||
copy.UnlockBits(copyData);
|
||||
return copy;
|
||||
}
|
||||
/// <summary>
|
||||
///图片异步保存
|
||||
/// </summary>
|
||||
public void SaveDetectResultImageAsync1(DetectStationResult detectResult)
|
||||
{
|
||||
string format = detectResult.ImageFormat.ToString().ToLower();
|
||||
|
||||
if(detectResult.ImageSaveDirectory!=null)
|
||||
{
|
||||
if (!Directory.Exists(detectResult.ImageSaveDirectory))
|
||||
{
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
}else
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//根目录
|
||||
string rootPath = Path.Combine(detectResult.ImageSaveDirectory,
|
||||
DateTime.Now.ToString("yyyyMMdd"), detectResult.DetectName);
|
||||
|
||||
if (detectResult.ResultState != ResultState.OK)
|
||||
{
|
||||
|
||||
// NG原图
|
||||
if (detectResult.SaveNGOriginal && detectResult.DetectionOriginImage != null)
|
||||
{
|
||||
string prefix = Path.Combine(rootPath, "NGRawImages", detectResult.ResultLabel);
|
||||
string fullname = Path.Combine(prefix, $"{detectResult.Pid}_NGRawImage_{detectResult.DetectName}_{detectResult.Id}.{format}");
|
||||
SaveImageAsync(fullname, detectResult.DetectionOriginImage, detectResult.ImageFormat);
|
||||
}
|
||||
|
||||
|
||||
//NG结果图
|
||||
if (detectResult.SaveOKDetect && detectResult.DetectionOriginImage != null)
|
||||
{
|
||||
// 没有预处理,则保存原始图+检测结果图
|
||||
// if (detectResult.VisionImageSet.PreTreatedBitmap == null)
|
||||
{
|
||||
//string displayTxt = detectResult.ResultState.ToString() + "\r\n";
|
||||
string displayTxt = "";
|
||||
detectResult.DetectDetails.ForEach(d =>
|
||||
{
|
||||
displayTxt += $"{d.LabelName} score:{d.Score.ToString("f2")} area:{d.Area.ToString("f2")}\r\n";
|
||||
});
|
||||
if (detectResult.realSpecs != null && detectResult.realSpecs?.Count > 0)
|
||||
{
|
||||
detectResult.realSpecs.ForEach(d =>
|
||||
{
|
||||
displayTxt +=
|
||||
$"{d.Code} score:{d.ActualValue} \r\n";
|
||||
});
|
||||
}
|
||||
Bitmap resultMask = detectResult.DetectionOriginImage.CopyBitmap();
|
||||
|
||||
Bitmap preTreatedBitmap = detectResult.DetectionOriginImage.CopyBitmap();
|
||||
|
||||
//List<IShapeElement> detectionResultShapes = new List<IShapeElement>(detectResult.DetectionResultShapes);
|
||||
//DetectResultDisplay resultDisplay = new DetectResultDisplay(detectResult, resultMask, displayTxt);
|
||||
//detectionResultShapes.Add(resultDisplay);
|
||||
|
||||
Bitmap resultMap = GetResultImage(resultMask, detectResult.DetectionResultShapes);
|
||||
|
||||
|
||||
// resultDisplay.Dispose();
|
||||
//detectionResultShapes.Clear();
|
||||
|
||||
|
||||
Bitmap detectionFitImage = StaticHelper.HConnectBitmap(preTreatedBitmap, resultMap);
|
||||
|
||||
string prefix = Path.Combine(rootPath, "NGFitImages", detectResult.ResultLabel);
|
||||
Directory.CreateDirectory(prefix); // 自动创建所有缺失的目录
|
||||
string fullname = Path.Combine(prefix, $"{detectResult.Pid}_NGFitImage_{detectResult.DetectName}_{detectResult.Id}.{format}");
|
||||
|
||||
|
||||
|
||||
// SaveImageAsync(fullname, detectionFitImage, detectResult.ImageFormat);
|
||||
// 使用回调或 Task.ContinueWith 确保保存完成后再释放资源
|
||||
//SaveImageAsync(fullname, detectionFitImage, detectResult.ImageFormat)
|
||||
// .ContinueWith(t =>
|
||||
// {
|
||||
// resultMask?.Dispose();
|
||||
// preTreatedBitmap?.Dispose();
|
||||
// resultMap?.Dispose();
|
||||
// detectionFitImage?.Dispose();
|
||||
// }, TaskScheduler.Default);
|
||||
|
||||
resultMask?.Dispose();
|
||||
preTreatedBitmap?.Dispose();
|
||||
resultMap?.Dispose();
|
||||
detectionFitImage?.Dispose();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
else
|
||||
{ // OK原图
|
||||
if (detectResult.SaveOKOriginal && detectResult.DetectionOriginImage != null)
|
||||
{
|
||||
string prefix = Path.Combine(rootPath, "OKRawImages", detectResult.ResultLabel);
|
||||
string fullname = Path.Combine(prefix, $"{detectResult.Pid}_OKRawImage_{detectResult.DetectName}_{detectResult.Id}.{format}");
|
||||
SaveImageAsync(fullname, detectResult.DetectionOriginImage, detectResult.ImageFormat);
|
||||
}
|
||||
|
||||
//ok结果图
|
||||
if (detectResult.SaveOKDetect && detectResult.DetectionOriginImage != null)
|
||||
{
|
||||
// 没有预处理,则保存原始图+检测结果图
|
||||
// if (detectResult.VisionImageSet.PreTreatedBitmap == null)
|
||||
{
|
||||
//string displayTxt = detectResult.ResultState.ToString() + "\r\n";
|
||||
string displayTxt = "";
|
||||
detectResult.DetectDetails.ForEach(d =>
|
||||
{
|
||||
displayTxt += $"{d.LabelName} score:{d.Score.ToString("f2")} area:{d.Area.ToString("f2")}\r\n";
|
||||
});
|
||||
if (detectResult.realSpecs != null && detectResult.realSpecs?.Count > 0)
|
||||
{
|
||||
detectResult.realSpecs.ForEach(d =>
|
||||
{
|
||||
displayTxt +=
|
||||
$"{d.Code} score:{d.ActualValue} \r\n";
|
||||
});
|
||||
}
|
||||
Bitmap resultMask = detectResult.DetectionOriginImage.CopyBitmap();
|
||||
|
||||
Bitmap preTreatedBitmap = detectResult.DetectionOriginImage.CopyBitmap();
|
||||
|
||||
List<IShapeElement> detectionResultShapes = new List<IShapeElement>(detectResult.DetectionResultShapes);
|
||||
DetectResultDisplay resultDisplay = new DetectResultDisplay(detectResult, resultMask, displayTxt);
|
||||
detectionResultShapes.Add(resultDisplay);
|
||||
|
||||
Bitmap resultMap = GetResultImage(resultMask, detectionResultShapes);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Bitmap detectionFitImage = StaticHelper.HConnectBitmap(preTreatedBitmap, resultMap);
|
||||
|
||||
string prefix = Path.Combine(rootPath, "OKFitImages", detectResult.ResultLabel);
|
||||
string fullname = Path.Combine(prefix, $"{detectResult.Pid}_" +
|
||||
$"OKFitImage_{detectResult.DetectName}_{detectResult.Id}.{format}");
|
||||
|
||||
|
||||
|
||||
SaveImageAsync(fullname, detectionFitImage, detectResult.ImageFormat);
|
||||
|
||||
//resultDisplay.Dispose();
|
||||
//detectionResultShapes.Clear();
|
||||
//resultMask?.Dispose();
|
||||
//preTreatedBitmap?.Dispose();
|
||||
//resultMap?.Dispose();
|
||||
//detectionFitImage?.Dispose();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
public virtual Bitmap GetResultImage(Bitmap baseImage, List<IShapeElement> eleList)
|
||||
{
|
||||
try
|
||||
{
|
||||
// 重新生成画布 避免 无法从带有索引像素格式的图像创建graphics对象
|
||||
Bitmap image = new Bitmap(baseImage.Width, baseImage.Height);
|
||||
|
||||
using (Graphics g = Graphics.FromImage(image))
|
||||
{
|
||||
g.DrawImage(baseImage, 0, 0);
|
||||
|
||||
// 创建临时拷贝避免共享状态
|
||||
// var tempElements = eleList.Select(e => e.Clone()).Cast<IShapeElement>().ToList();
|
||||
|
||||
eleList.ForEach(e =>
|
||||
{
|
||||
e.State = ElementState.Normal;
|
||||
e.Draw(g);
|
||||
});
|
||||
}
|
||||
return image;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogAsync(DateTime.Now, LogLevel.Exception, $"获取叠加结果图片异常:{ex.GetExceptionMessage()}");
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void SaveDetectResultImageAsync(DetectStationResult detectResult)
|
||||
{
|
||||
if (detectResult.ImageSaveDirectory == null) return;
|
||||
|
||||
string format = detectResult.ImageFormat.ToString().ToLower();
|
||||
string rootPath = Path.Combine(detectResult.ImageSaveDirectory,
|
||||
DateTime.Now.ToString("yyyyMMdd"), detectResult.DetectName);
|
||||
|
||||
try
|
||||
{
|
||||
if (detectResult.ResultState != ResultState.OK)
|
||||
{
|
||||
SaveNGImages(detectResult, rootPath, format);
|
||||
}
|
||||
else
|
||||
{
|
||||
SaveOKImages(detectResult, rootPath, format);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// Logger.Error($"保存检测结果失败: {ex.Message}");
|
||||
}
|
||||
finally {
|
||||
GC.Collect();
|
||||
GC.WaitForPendingFinalizers();
|
||||
}
|
||||
}
|
||||
private void SaveNGImages(DetectStationResult result, string rootPath, string format)
|
||||
{
|
||||
// NG 原图
|
||||
if (result.SaveNGOriginal && result.DetectionOriginImage != null)
|
||||
{
|
||||
string prefix = Path.Combine(rootPath, "NGRawImages", result.ResultLabel);
|
||||
Directory.CreateDirectory(prefix);
|
||||
string fullname = Path.Combine(prefix, $"{result.Pid}_NGRawImage_{result.DetectName}_{result.Id}.{format}");
|
||||
SaveImageAsync(fullname, result.DetectionOriginImage, result.ImageFormat);
|
||||
}
|
||||
|
||||
// NG 结果图
|
||||
if (result.SaveOKDetect && result.DetectionOriginImage != null)
|
||||
{
|
||||
string displayTxt = BuildDisplayText(result);
|
||||
using (Bitmap resultMask = result.DetectionOriginImage.CopyBitmap())
|
||||
using (Bitmap preTreatedBitmap = result.DetectionOriginImage.CopyBitmap())
|
||||
{
|
||||
var detectionResultShapes = new List<IShapeElement>()
|
||||
{
|
||||
new DetectResultDisplay(result, resultMask, displayTxt)
|
||||
};
|
||||
|
||||
using (Bitmap resultMap = GetResultImage(resultMask, detectionResultShapes))
|
||||
using (Bitmap detectionFitImage = StaticHelper.HConnectBitmap(preTreatedBitmap, resultMap))
|
||||
{
|
||||
string prefix = Path.Combine(rootPath, "NGFitImages", result.ResultLabel);
|
||||
Directory.CreateDirectory(prefix);
|
||||
string fullname = Path.Combine(prefix, $"{result.Pid}_NGFitImage_{result.DetectName}_{result.Id}.{format}");
|
||||
SaveImageAsync(fullname, detectionFitImage, result.ImageFormat);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
private void SaveOKImages(DetectStationResult result, string rootPath, string format)
|
||||
{
|
||||
// OK 原图
|
||||
if (result.SaveOKOriginal && result.DetectionOriginImage != null)
|
||||
{
|
||||
string prefix = Path.Combine(rootPath, "OKRawImages", result.ResultLabel);
|
||||
Directory.CreateDirectory(prefix);
|
||||
string fullname = Path.Combine(prefix, $"{result.Pid}_OKRawImage_{result.DetectName}_{result.Id}.{format}");
|
||||
SaveImageAsync(fullname, result.DetectionOriginImage, result.ImageFormat);
|
||||
}
|
||||
|
||||
// OK 结果图
|
||||
if (result.SaveOKDetect && result.DetectionOriginImage != null)
|
||||
{
|
||||
string displayTxt = BuildDisplayText(result);
|
||||
using (Bitmap resultMask = result.DetectionOriginImage.CopyBitmap())
|
||||
using (Bitmap preTreatedBitmap = result.DetectionOriginImage.CopyBitmap())
|
||||
{
|
||||
var detectionResultShapes = new List<IShapeElement>()
|
||||
{
|
||||
new DetectResultDisplay(result, resultMask, displayTxt)
|
||||
};
|
||||
|
||||
using (Bitmap resultMap = GetResultImage(resultMask, detectionResultShapes))
|
||||
using (Bitmap detectionFitImage = StaticHelper.HConnectBitmap(preTreatedBitmap, resultMap))
|
||||
{
|
||||
string prefix = Path.Combine(rootPath, "OKFitImages", result.ResultLabel);
|
||||
Directory.CreateDirectory(prefix);
|
||||
string fullname = Path.Combine(prefix, $"{result.Pid}_OKFitImage_{result.DetectName}_{result.Id}.{format}");
|
||||
SaveImageAsync(fullname, detectionFitImage, result.ImageFormat);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private string BuildDisplayText(DetectStationResult result)
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
result.DetectDetails.ForEach(d => sb.AppendLine($"{d.LabelName} score:{d.Score:f2} area:{d.Area:f2}"));
|
||||
if (result.realSpecs?.Count > 0)
|
||||
{
|
||||
result.realSpecs.ForEach(d => sb.AppendLine($"{d.Code} score:{d.ActualValue}"));
|
||||
}
|
||||
return sb.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
using AntdUI;
|
||||
|
||||
using DH.Commons.Base;
|
||||
using DH.Commons.Enums;
|
||||
using OpenCvSharp;
|
||||
using System;
|
||||
@ -17,7 +17,7 @@ namespace DH.Devices.Vision
|
||||
public Mat ColorLut { get; set; }
|
||||
public byte[] ColorMap { get; set; }
|
||||
|
||||
public MLModelType ModelType { get; set; }
|
||||
public ModelType ModelType { get; set; }
|
||||
|
||||
public IntPtr Model { get; set; }
|
||||
|
||||
|
@ -10,6 +10,14 @@
|
||||
<Platforms>AnyCPU;x64</Platforms>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
|
||||
<Optimize>False</Optimize>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<Optimize>False</Optimize>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\DH.Commons\DH.Commons.csproj" />
|
||||
</ItemGroup>
|
||||
|
@ -580,7 +580,7 @@ namespace DH.UI.Model.Winform
|
||||
/// </summary>
|
||||
[Browsable(false)]
|
||||
public Rectangle BaseRectangle { get; set; }
|
||||
EnumHelper.ElementState IShapeElement.State { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
|
||||
|
||||
|
||||
public abstract bool IsMouseHover(PointF p);
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
|
||||
using DH.Commons.Enums;
|
||||
using DH.Commons.Base;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
|
@ -25,14 +25,18 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Motion", "Motion", "{5C8472
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DH.Devices.Motion", "DH.Devices.Motion\DH.Devices.Motion.csproj", "{144E3775-0BD7-4528-9FB0-A0F4ADC74313}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DH.Commons.Devies", "DH.Commons.Devies\DH.Commons.Devies.csproj", "{A33108B6-2740-4D28-AD22-B280372980BE}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "UI", "UI", "{3EAF3D9C-D3F9-4B6E-89DE-58F129CD1F4C}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DH.UI.Model.Winform", "DH.UI.Model.Winform\DH.UI.Model.Winform.csproj", "{12CB9041-B1B1-41AE-B308-AABDACAA580E}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DH.Devices.Vision", "DH.Devices.Vision\DH.Devices.Vision.csproj", "{5AD3A29E-149A-4C37-9548-7638A36C8175}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Size", "Size", "{048B30B5-D075-4CE0-BF9F-CB6152E6D376}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "XKRS.CanFly", "CanFly\XKRS.CanFly.csproj", "{1FB768DB-843E-4C67-96B9-7684CF890D89}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CanFly.Canvas", "CanFly.Canvas\CanFly.Canvas.csproj", "{EA7E228B-DB5C-4BF1-832B-D51B7F7D5F35}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
@ -81,14 +85,6 @@ Global
|
||||
{144E3775-0BD7-4528-9FB0-A0F4ADC74313}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{144E3775-0BD7-4528-9FB0-A0F4ADC74313}.Release|x64.ActiveCfg = Release|x64
|
||||
{144E3775-0BD7-4528-9FB0-A0F4ADC74313}.Release|x64.Build.0 = Release|x64
|
||||
{A33108B6-2740-4D28-AD22-B280372980BE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{A33108B6-2740-4D28-AD22-B280372980BE}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{A33108B6-2740-4D28-AD22-B280372980BE}.Debug|x64.ActiveCfg = Debug|X64
|
||||
{A33108B6-2740-4D28-AD22-B280372980BE}.Debug|x64.Build.0 = Debug|X64
|
||||
{A33108B6-2740-4D28-AD22-B280372980BE}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{A33108B6-2740-4D28-AD22-B280372980BE}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{A33108B6-2740-4D28-AD22-B280372980BE}.Release|x64.ActiveCfg = Release|X64
|
||||
{A33108B6-2740-4D28-AD22-B280372980BE}.Release|x64.Build.0 = Release|X64
|
||||
{12CB9041-B1B1-41AE-B308-AABDACAA580E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{12CB9041-B1B1-41AE-B308-AABDACAA580E}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{12CB9041-B1B1-41AE-B308-AABDACAA580E}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
@ -105,6 +101,22 @@ Global
|
||||
{5AD3A29E-149A-4C37-9548-7638A36C8175}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{5AD3A29E-149A-4C37-9548-7638A36C8175}.Release|x64.ActiveCfg = Release|x64
|
||||
{5AD3A29E-149A-4C37-9548-7638A36C8175}.Release|x64.Build.0 = Release|x64
|
||||
{1FB768DB-843E-4C67-96B9-7684CF890D89}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{1FB768DB-843E-4C67-96B9-7684CF890D89}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{1FB768DB-843E-4C67-96B9-7684CF890D89}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{1FB768DB-843E-4C67-96B9-7684CF890D89}.Debug|x64.Build.0 = Debug|x64
|
||||
{1FB768DB-843E-4C67-96B9-7684CF890D89}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{1FB768DB-843E-4C67-96B9-7684CF890D89}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{1FB768DB-843E-4C67-96B9-7684CF890D89}.Release|x64.ActiveCfg = Release|x64
|
||||
{1FB768DB-843E-4C67-96B9-7684CF890D89}.Release|x64.Build.0 = Release|x64
|
||||
{EA7E228B-DB5C-4BF1-832B-D51B7F7D5F35}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{EA7E228B-DB5C-4BF1-832B-D51B7F7D5F35}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{EA7E228B-DB5C-4BF1-832B-D51B7F7D5F35}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{EA7E228B-DB5C-4BF1-832B-D51B7F7D5F35}.Debug|x64.Build.0 = Debug|x64
|
||||
{EA7E228B-DB5C-4BF1-832B-D51B7F7D5F35}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{EA7E228B-DB5C-4BF1-832B-D51B7F7D5F35}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{EA7E228B-DB5C-4BF1-832B-D51B7F7D5F35}.Release|x64.ActiveCfg = Release|x64
|
||||
{EA7E228B-DB5C-4BF1-832B-D51B7F7D5F35}.Release|x64.Build.0 = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
@ -118,9 +130,10 @@ Global
|
||||
{458B2CF6-6F1B-4B8B-BB85-C6FD7F453A5D} = {2560C5A5-0CA2-48AD-B606-6C55BEFD8109}
|
||||
{5C8472C6-EB6A-4D89-B519-7073BBF6A5D2} = {8EC33C16-65CE-4C12-9C8D-DB2425F9F7C0}
|
||||
{144E3775-0BD7-4528-9FB0-A0F4ADC74313} = {5C8472C6-EB6A-4D89-B519-7073BBF6A5D2}
|
||||
{A33108B6-2740-4D28-AD22-B280372980BE} = {0AB4BB9A-A861-4F80-B549-CD331490942B}
|
||||
{12CB9041-B1B1-41AE-B308-AABDACAA580E} = {3EAF3D9C-D3F9-4B6E-89DE-58F129CD1F4C}
|
||||
{5AD3A29E-149A-4C37-9548-7638A36C8175} = {F77AF94C-280D-44C5-B7C0-FC86AA9EC504}
|
||||
{1FB768DB-843E-4C67-96B9-7684CF890D89} = {048B30B5-D075-4CE0-BF9F-CB6152E6D376}
|
||||
{EA7E228B-DB5C-4BF1-832B-D51B7F7D5F35} = {048B30B5-D075-4CE0-BF9F-CB6152E6D376}
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {6FC1A8DF-636E-434C-981E-10F20FAD723B}
|
||||
|
9
DHSoftware/App.config
Normal file
9
DHSoftware/App.config
Normal file
@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<configuration>
|
||||
<appSettings>
|
||||
<!-- 方案存储键(初始值为空) -->
|
||||
<add key="Schemes" value=""/>
|
||||
<!-- 当前方案键(初始值为空) -->
|
||||
<add key="CurrentScheme" value=""/>
|
||||
</appSettings>
|
||||
</configuration>
|
@ -11,33 +11,16 @@
|
||||
<Platforms>AnyCPU;x64</Platforms>
|
||||
<OutputType>WinExe</OutputType>
|
||||
</PropertyGroup>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="AntdUI" Version="1.8.9" />
|
||||
<PackageReference Include="System.IO.Ports" Version="9.0.2" />
|
||||
<PackageReference Include="SqlSugarCore" Version="5.1.4.185" />
|
||||
<PackageReference Include="System.Data.SQLite.Core" Version="1.0.119" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\CanFly\XKRS.CanFly.csproj" />
|
||||
<ProjectReference Include="..\DH.Devices.Camera\DH.Devices.Camera.csproj" />
|
||||
<ProjectReference Include="..\DH.Devices.Motion\DH.Devices.Motion.csproj" />
|
||||
<ProjectReference Include="..\DH.Devices.PLC\DH.Devices.PLC.csproj" />
|
||||
|
@ -1,68 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace DHSoftware
|
||||
{
|
||||
public static class EnumHelper
|
||||
{
|
||||
public enum SelectPicType
|
||||
{
|
||||
[Description("训练图片")]
|
||||
train =0,
|
||||
[Description("测试图片")]
|
||||
test
|
||||
|
||||
}
|
||||
public enum NetModel
|
||||
{
|
||||
[Description("目标检测")]
|
||||
training = 0,
|
||||
[Description("语义分割")]
|
||||
train_seg,
|
||||
[Description("模型导出")]
|
||||
emport,
|
||||
[Description("推理预测")]
|
||||
infernce
|
||||
|
||||
}
|
||||
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}' 的值");
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -1,10 +1,4 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace DHSoftware.Languages
|
||||
namespace DHSoftware.Languages
|
||||
{
|
||||
public class Localizer_enus : AntdUI.ILocalization
|
||||
{
|
||||
@ -14,125 +8,182 @@ namespace DHSoftware.Languages
|
||||
{
|
||||
case "search":
|
||||
return "Search";
|
||||
|
||||
case "welcome":
|
||||
return "Welcome to the AntdUI Demo";
|
||||
|
||||
case "home":
|
||||
return "Home";
|
||||
|
||||
case "closeall":
|
||||
return "Close all tabs";
|
||||
|
||||
#region systemset
|
||||
|
||||
case "systemset":
|
||||
return "System Settings";
|
||||
|
||||
case "baseset":
|
||||
return "Basic Settings";
|
||||
|
||||
case "messageconfig":
|
||||
return "Message configuration";
|
||||
|
||||
case "animationon":
|
||||
return "Turn on animation";
|
||||
|
||||
case "shadowon":
|
||||
return "Enable shadow";
|
||||
|
||||
case "scrollbarhide":
|
||||
return "Hide scrollbar";
|
||||
|
||||
case "showinwindow":
|
||||
return "Show in window";
|
||||
|
||||
case "windowOffsetXY":
|
||||
return "WindowOffsetXY";
|
||||
|
||||
case "tip":
|
||||
return "Tip";
|
||||
|
||||
case "switchsuccess":
|
||||
return "Switch successful.";
|
||||
#endregion
|
||||
|
||||
#endregion systemset
|
||||
|
||||
#region Button
|
||||
|
||||
case "Button.Text":
|
||||
return "Button";
|
||||
|
||||
case "Button.Description":
|
||||
return "To trigger an operation.";
|
||||
|
||||
case "type":
|
||||
return "Type";
|
||||
|
||||
case "wave":
|
||||
return "Wave";
|
||||
|
||||
case "loading":
|
||||
return "Loading";
|
||||
|
||||
case "ghost":
|
||||
return "Ghost";
|
||||
|
||||
case "border":
|
||||
return "Border";
|
||||
|
||||
case "icon":
|
||||
return "Icon";
|
||||
|
||||
case "arrow":
|
||||
return "Arrow";
|
||||
|
||||
case "join":
|
||||
return "Join";
|
||||
|
||||
case "gradient":
|
||||
return "Gradient";
|
||||
|
||||
case "toggle":
|
||||
return "Toggle";
|
||||
#endregion
|
||||
|
||||
#endregion Button
|
||||
|
||||
#region FloatButton
|
||||
|
||||
case "FloatButton.Text":
|
||||
return "FloatButton";
|
||||
|
||||
case "FloatButton.Description":
|
||||
return "A button that floats at the top of the page.";
|
||||
|
||||
case "FloatButton.Tip":
|
||||
return "FloatButton does not have a toolbox control and is called code.";
|
||||
|
||||
case "control_option":
|
||||
return "Control Options";
|
||||
|
||||
case "button_option":
|
||||
return "Button Options";
|
||||
|
||||
case "open":
|
||||
return "Open";
|
||||
|
||||
case "close":
|
||||
return "Close";
|
||||
|
||||
case "reset":
|
||||
return "Reset";
|
||||
#endregion
|
||||
|
||||
#endregion FloatButton
|
||||
|
||||
#region Icon
|
||||
|
||||
case "Icon.Text":
|
||||
return "Icon";
|
||||
|
||||
case "Icon.Description":
|
||||
return "Semantic vector graphics.";
|
||||
|
||||
case "Icon.Tip":
|
||||
return "Icon does not have a toolbox control and is used for Svg property assignments.";
|
||||
|
||||
case "outlined":
|
||||
return "Outlined";
|
||||
|
||||
case "filled":
|
||||
return "Filled";
|
||||
|
||||
case "directionalicon":
|
||||
return "Directional icons";
|
||||
|
||||
case "suggestionicon":
|
||||
return "Suggestion Icon";
|
||||
|
||||
case "editingicon":
|
||||
return "Editing Icons";
|
||||
|
||||
case "dataicon":
|
||||
return "Data icons";
|
||||
|
||||
case "brand":
|
||||
return "Brand and logo";
|
||||
|
||||
case "universal":
|
||||
return "Universal Icons for Websites";
|
||||
|
||||
case "copysuccess":
|
||||
return "Copy successful!";
|
||||
|
||||
case "copyfail":
|
||||
return "Copy failed!";
|
||||
#endregion
|
||||
|
||||
#endregion Icon
|
||||
|
||||
#region Divider
|
||||
|
||||
case "Divider.Text":
|
||||
return "Divider";
|
||||
|
||||
case "Divider.Description":
|
||||
return "A divider line separates different content.";
|
||||
|
||||
case "basicusage":
|
||||
return "Basic Usage";
|
||||
|
||||
case "vertical":
|
||||
return "Vertical";
|
||||
|
||||
case "horizontal":
|
||||
return "Horizontal";
|
||||
#endregion
|
||||
|
||||
#endregion Divider
|
||||
|
||||
default:
|
||||
return null;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
117
DHSoftware/LoginWindow.Designer.cs
generated
Normal file
117
DHSoftware/LoginWindow.Designer.cs
generated
Normal file
@ -0,0 +1,117 @@
|
||||
namespace DHSoftware
|
||||
{
|
||||
partial class LoginWindow
|
||||
{
|
||||
/// <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(LoginWindow));
|
||||
label1 = new AntdUI.Label();
|
||||
iptName = new AntdUI.Input();
|
||||
iptPwd = new AntdUI.Input();
|
||||
button_cancel = new AntdUI.Button();
|
||||
button_ok = new AntdUI.Button();
|
||||
SuspendLayout();
|
||||
//
|
||||
// label1
|
||||
//
|
||||
label1.BackColor = SystemColors.Window;
|
||||
label1.Font = new Font("Microsoft YaHei UI", 14.25F, FontStyle.Bold, GraphicsUnit.Point, 134);
|
||||
label1.Location = new Point(351, 44);
|
||||
label1.Name = "label1";
|
||||
label1.Size = new Size(212, 23);
|
||||
label1.TabIndex = 0;
|
||||
label1.Text = "登录CCD光学筛选系统";
|
||||
//
|
||||
// iptName
|
||||
//
|
||||
iptName.Location = new Point(351, 95);
|
||||
iptName.Name = "iptName";
|
||||
iptName.PlaceholderText = "请输入用户名";
|
||||
iptName.Size = new Size(227, 37);
|
||||
iptName.TabIndex = 1;
|
||||
//
|
||||
// iptPwd
|
||||
//
|
||||
iptPwd.Location = new Point(351, 156);
|
||||
iptPwd.Name = "iptPwd";
|
||||
iptPwd.PasswordPaste = false;
|
||||
iptPwd.PlaceholderText = "请输入密码";
|
||||
iptPwd.Size = new Size(227, 37);
|
||||
iptPwd.TabIndex = 2;
|
||||
iptPwd.UseSystemPasswordChar = true;
|
||||
//
|
||||
// button_cancel
|
||||
//
|
||||
button_cancel.BorderWidth = 1F;
|
||||
button_cancel.Font = new Font("Microsoft YaHei UI", 9F);
|
||||
button_cancel.Ghost = true;
|
||||
button_cancel.Location = new Point(468, 231);
|
||||
button_cancel.Name = "button_cancel";
|
||||
button_cancel.Size = new Size(95, 38);
|
||||
button_cancel.TabIndex = 4;
|
||||
button_cancel.Text = "取消";
|
||||
//
|
||||
// button_ok
|
||||
//
|
||||
button_ok.Font = new Font("Microsoft YaHei UI", 9F, FontStyle.Regular, GraphicsUnit.Point, 134);
|
||||
button_ok.Location = new Point(364, 231);
|
||||
button_ok.Name = "button_ok";
|
||||
button_ok.Size = new Size(95, 38);
|
||||
button_ok.TabIndex = 3;
|
||||
button_ok.Text = "登录";
|
||||
button_ok.Type = AntdUI.TTypeMini.Primary;
|
||||
//
|
||||
// LoginWindow
|
||||
//
|
||||
BackgroundImage = (Image)resources.GetObject("$this.BackgroundImage");
|
||||
BackgroundImageLayout = ImageLayout.Stretch;
|
||||
ClientSize = new Size(590, 340);
|
||||
ControlBox = false;
|
||||
Controls.Add(button_cancel);
|
||||
Controls.Add(button_ok);
|
||||
Controls.Add(iptPwd);
|
||||
Controls.Add(iptName);
|
||||
Controls.Add(label1);
|
||||
Font = new Font("Microsoft YaHei UI", 9F, FontStyle.Regular, GraphicsUnit.Point, 134);
|
||||
Icon = (Icon)resources.GetObject("$this.Icon");
|
||||
Name = "LoginWindow";
|
||||
StartPosition = FormStartPosition.CenterScreen;
|
||||
Text = "登录界面";
|
||||
Load += LoginWindow_Load;
|
||||
ResumeLayout(false);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
private AntdUI.Label label1;
|
||||
private AntdUI.Input iptName;
|
||||
private AntdUI.Input iptPwd;
|
||||
private AntdUI.Button button_cancel;
|
||||
private AntdUI.Button button_ok;
|
||||
}
|
||||
}
|
123
DHSoftware/LoginWindow.cs
Normal file
123
DHSoftware/LoginWindow.cs
Normal file
@ -0,0 +1,123 @@
|
||||
using AntdUI;
|
||||
using DHSoftware.Models;
|
||||
using DHSoftware.Services;
|
||||
|
||||
namespace DHSoftware
|
||||
{
|
||||
public partial class LoginWindow : AntdUI.Window
|
||||
{
|
||||
public LoginWindow()
|
||||
{
|
||||
InitializeComponent();
|
||||
// 关键设置:允许窗体优先接收按键事件
|
||||
this.KeyPreview = true;
|
||||
|
||||
// 绑定按键事件
|
||||
this.KeyDown += Login_KeyDown;
|
||||
button_ok.Click += Button_ok_Click;
|
||||
button_cancel.Click += Button_cancel_Click;
|
||||
}
|
||||
|
||||
private void Login_KeyDown(object? sender, KeyEventArgs e)
|
||||
{
|
||||
// 监听回车键
|
||||
if (e.KeyCode == Keys.Enter)
|
||||
{
|
||||
button_ok.PerformClick(); // 触发确定按钮的点击事件
|
||||
e.Handled = true; // 阻止其他控件处理该按键
|
||||
}
|
||||
|
||||
// 监听 ESC 键
|
||||
if (e.KeyCode == Keys.Escape)
|
||||
{
|
||||
button_cancel.PerformClick(); // 触发取消按钮的点击事件
|
||||
e.Handled = true;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 窗体对象实例
|
||||
/// </summary>
|
||||
private static LoginWindow _instance;
|
||||
|
||||
internal static LoginWindow Instance
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_instance == null || _instance.IsDisposed)
|
||||
_instance = new LoginWindow();
|
||||
return _instance;
|
||||
}
|
||||
}
|
||||
|
||||
private void Button_cancel_Click(object? sender, EventArgs e)
|
||||
{
|
||||
this.Dispose();
|
||||
}
|
||||
|
||||
private void Button_ok_Click(object? sender, EventArgs e)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(iptName.Text))
|
||||
{
|
||||
AntdUI.Message.warn(this, "用户名不能为空!", autoClose: 3);
|
||||
return;
|
||||
}
|
||||
if (string.IsNullOrWhiteSpace(iptPwd.Text))
|
||||
{
|
||||
AntdUI.Message.warn(this, "密码不能为空!", autoClose: 3);
|
||||
return;
|
||||
}
|
||||
if (AuthService.Login(iptName.Text, iptPwd.Text))
|
||||
{
|
||||
if (this.Owner is MainWindow parent)
|
||||
{
|
||||
List<string> UserPermissions = AuthService.GetUserPermissions();
|
||||
// 检查当前用户是否有权限
|
||||
if (AuthService.HasPermission("system:config"))
|
||||
{
|
||||
parent.ShowConfig = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
parent.ShowConfig = false;
|
||||
}
|
||||
if (AuthService.HasPermission("system:loadscheme"))
|
||||
{
|
||||
parent.Loadscheme = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
parent.Loadscheme = false;
|
||||
}
|
||||
if (AuthService.HasPermission("system:addscheme"))
|
||||
{
|
||||
parent.Addscheme = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
parent.Addscheme = false;
|
||||
}
|
||||
if (AuthService.HasPermission("system:deletescheme"))
|
||||
{
|
||||
parent.Deleteschememe = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
parent.Deleteschememe = false;
|
||||
}
|
||||
|
||||
parent.LoginName = iptName.Text;
|
||||
}
|
||||
this.Dispose();
|
||||
}
|
||||
else
|
||||
{
|
||||
AntdUI.Message.warn(this, "用户名或密码错误,登录失败!", autoClose: 3);
|
||||
}
|
||||
}
|
||||
|
||||
private void LoginWindow_Load(object sender, EventArgs e)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
7609
DHSoftware/LoginWindow.resx
Normal file
7609
DHSoftware/LoginWindow.resx
Normal file
File diff suppressed because it is too large
Load Diff
847
DHSoftware/MainWindow.Designer.cs
generated
847
DHSoftware/MainWindow.Designer.cs
generated
@ -28,62 +28,75 @@
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(MainWindow));
|
||||
AntdUI.Tabs.StyleCard styleCard1 = new AntdUI.Tabs.StyleCard();
|
||||
AntdUI.Tabs.StyleLine styleLine2 = new AntdUI.Tabs.StyleLine();
|
||||
AntdUI.Tabs.StyleCard styleCard2 = new AntdUI.Tabs.StyleCard();
|
||||
AntdUI.Tabs.StyleCard styleCard3 = new AntdUI.Tabs.StyleCard();
|
||||
AntdUI.SegmentedItem segmentedItem1 = new AntdUI.SegmentedItem();
|
||||
AntdUI.SegmentedItem segmentedItem2 = new AntdUI.SegmentedItem();
|
||||
AntdUI.SegmentedItem segmentedItem3 = new AntdUI.SegmentedItem();
|
||||
AntdUI.SegmentedItem segmentedItem4 = new AntdUI.SegmentedItem();
|
||||
AntdUI.SegmentedItem segmentedItem5 = new AntdUI.SegmentedItem();
|
||||
AntdUI.SegmentedItem segmentedItem6 = new AntdUI.SegmentedItem();
|
||||
AntdUI.SegmentedItem segmentedItem7 = new AntdUI.SegmentedItem();
|
||||
AntdUI.SegmentedItem segmentedItem8 = new AntdUI.SegmentedItem();
|
||||
AntdUI.SegmentedItem segmentedItem9 = new AntdUI.SegmentedItem();
|
||||
AntdUI.SegmentedItem segmentedItem10 = new AntdUI.SegmentedItem();
|
||||
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(MainWindow));
|
||||
titlebar = new AntdUI.PageHeader();
|
||||
button_color = new AntdUI.Button();
|
||||
buttonSZ = new AntdUI.Button();
|
||||
pageHeader1 = new AntdUI.PageHeader();
|
||||
label1 = new Label();
|
||||
divider2 = new AntdUI.Divider();
|
||||
panelmain = new AntdUI.Panel();
|
||||
panel2 = new AntdUI.Panel();
|
||||
panel4 = new AntdUI.Panel();
|
||||
panel6 = new AntdUI.Panel();
|
||||
splitContainer1 = new SplitContainer();
|
||||
splitContainer2 = new SplitContainer();
|
||||
tabImgDisplay = new AntdUI.Tabs();
|
||||
tabMain = new AntdUI.TabPage();
|
||||
lbName = new AntdUI.Label();
|
||||
tabsStas = new AntdUI.Tabs();
|
||||
tabPage3 = new AntdUI.TabPage();
|
||||
richTextBox1 = new RichTextBox();
|
||||
tabsConfig = new AntdUI.Tabs();
|
||||
tabPage2 = new AntdUI.TabPage();
|
||||
panel7 = new Panel();
|
||||
tabMain = new AntdUI.TabPage();
|
||||
panelmain = new AntdUI.Panel();
|
||||
splitter2 = new AntdUI.Splitter();
|
||||
tabImgDisplay = new AntdUI.Tabs();
|
||||
splitter1 = new AntdUI.Splitter();
|
||||
pnlLog = new AntdUI.Panel();
|
||||
panel6 = new AntdUI.Panel();
|
||||
tableLayoutstatistics = new TableLayoutPanel();
|
||||
dgvCamreaNums = new DataGridView();
|
||||
panelNums = new AntdUI.Panel();
|
||||
tableLayoutNums = new TableLayoutPanel();
|
||||
dgvProductNums = new DataGridView();
|
||||
tableLayoutPanel3 = new TableLayoutPanel();
|
||||
lblTotalTime = new Label();
|
||||
label1 = new Label();
|
||||
label12 = new Label();
|
||||
lblUPH = new Label();
|
||||
lblStartTime = new Label();
|
||||
lblOEE_Total = new Label();
|
||||
label10 = new Label();
|
||||
label7 = new Label();
|
||||
panel2 = new AntdUI.Panel();
|
||||
panel1 = new AntdUI.Panel();
|
||||
panel3 = new AntdUI.Panel();
|
||||
btnDeleteProject = new AntdUI.Button();
|
||||
btnAddProject = new AntdUI.Button();
|
||||
btnLoadProject = new AntdUI.Button();
|
||||
sltProjects = new AntdUI.Select();
|
||||
segmented1 = new AntdUI.Segmented();
|
||||
titlebar.SuspendLayout();
|
||||
pageHeader1.SuspendLayout();
|
||||
panelmain.SuspendLayout();
|
||||
panel2.SuspendLayout();
|
||||
panel4.SuspendLayout();
|
||||
panel6.SuspendLayout();
|
||||
((System.ComponentModel.ISupportInitialize)splitContainer1).BeginInit();
|
||||
splitContainer1.Panel1.SuspendLayout();
|
||||
splitContainer1.Panel2.SuspendLayout();
|
||||
splitContainer1.SuspendLayout();
|
||||
((System.ComponentModel.ISupportInitialize)splitContainer2).BeginInit();
|
||||
splitContainer2.Panel1.SuspendLayout();
|
||||
splitContainer2.Panel2.SuspendLayout();
|
||||
splitContainer2.SuspendLayout();
|
||||
tabImgDisplay.SuspendLayout();
|
||||
tabsStas.SuspendLayout();
|
||||
tabPage3.SuspendLayout();
|
||||
tabsConfig.SuspendLayout();
|
||||
panelmain.SuspendLayout();
|
||||
((System.ComponentModel.ISupportInitialize)splitter2).BeginInit();
|
||||
splitter2.Panel1.SuspendLayout();
|
||||
splitter2.Panel2.SuspendLayout();
|
||||
splitter2.SuspendLayout();
|
||||
((System.ComponentModel.ISupportInitialize)splitter1).BeginInit();
|
||||
splitter1.Panel1.SuspendLayout();
|
||||
splitter1.Panel2.SuspendLayout();
|
||||
splitter1.SuspendLayout();
|
||||
panel6.SuspendLayout();
|
||||
tableLayoutstatistics.SuspendLayout();
|
||||
((System.ComponentModel.ISupportInitialize)dgvCamreaNums).BeginInit();
|
||||
panelNums.SuspendLayout();
|
||||
tableLayoutNums.SuspendLayout();
|
||||
((System.ComponentModel.ISupportInitialize)dgvProductNums).BeginInit();
|
||||
tableLayoutPanel3.SuspendLayout();
|
||||
panel1.SuspendLayout();
|
||||
panel3.SuspendLayout();
|
||||
SuspendLayout();
|
||||
//
|
||||
// titlebar
|
||||
//
|
||||
titlebar.BackColor = SystemColors.MenuHighlight;
|
||||
titlebar.Controls.Add(button_color);
|
||||
titlebar.Controls.Add(buttonSZ);
|
||||
titlebar.BackColor = Color.FromArgb(46, 108, 227);
|
||||
titlebar.Controls.Add(lbName);
|
||||
titlebar.DividerShow = true;
|
||||
titlebar.DividerThickness = 0F;
|
||||
titlebar.Dock = DockStyle.Top;
|
||||
@ -99,157 +112,44 @@
|
||||
titlebar.TabIndex = 0;
|
||||
titlebar.Text = "山东迭慧智能科技有限公司";
|
||||
//
|
||||
// button_color
|
||||
// lbName
|
||||
//
|
||||
button_color.Dock = DockStyle.Right;
|
||||
button_color.Ghost = true;
|
||||
button_color.IconRatio = 0.6F;
|
||||
button_color.IconSvg = "SunOutlined";
|
||||
button_color.Location = new Point(780, 0);
|
||||
button_color.Name = "button_color";
|
||||
button_color.Radius = 0;
|
||||
button_color.Size = new Size(50, 40);
|
||||
button_color.TabIndex = 1;
|
||||
button_color.ToggleIconSvg = "MoonOutlined";
|
||||
button_color.Visible = false;
|
||||
button_color.WaveSize = 0;
|
||||
lbName.Dock = DockStyle.Right;
|
||||
lbName.ForeColor = SystemColors.Window;
|
||||
lbName.Location = new Point(746, 0);
|
||||
lbName.Name = "lbName";
|
||||
lbName.Size = new Size(134, 40);
|
||||
lbName.TabIndex = 0;
|
||||
lbName.Text = "";
|
||||
lbName.TextAlign = ContentAlignment.MiddleRight;
|
||||
//
|
||||
// buttonSZ
|
||||
// tabsStas
|
||||
//
|
||||
buttonSZ.Dock = DockStyle.Right;
|
||||
buttonSZ.Ghost = true;
|
||||
buttonSZ.IconSvg = resources.GetString("buttonSZ.IconSvg");
|
||||
buttonSZ.Location = new Point(830, 0);
|
||||
buttonSZ.Name = "buttonSZ";
|
||||
buttonSZ.Radius = 0;
|
||||
buttonSZ.Size = new Size(50, 40);
|
||||
buttonSZ.TabIndex = 0;
|
||||
buttonSZ.Visible = false;
|
||||
buttonSZ.WaveSize = 0;
|
||||
tabsStas.Dock = DockStyle.Fill;
|
||||
tabsStas.Location = new Point(0, 0);
|
||||
tabsStas.Name = "tabsStas";
|
||||
tabsStas.Pages.Add(tabPage3);
|
||||
tabsStas.Size = new Size(580, 176);
|
||||
tabsStas.Style = styleLine2;
|
||||
tabsStas.TabIndex = 3;
|
||||
tabsStas.Text = "tabs3";
|
||||
//
|
||||
// pageHeader1
|
||||
// tabPage3
|
||||
//
|
||||
pageHeader1.Controls.Add(label1);
|
||||
pageHeader1.Controls.Add(divider2);
|
||||
pageHeader1.DividerShow = true;
|
||||
pageHeader1.Dock = DockStyle.Bottom;
|
||||
pageHeader1.Font = new Font("Microsoft YaHei UI", 12F, FontStyle.Regular, GraphicsUnit.Point, 134);
|
||||
pageHeader1.Location = new Point(0, 608);
|
||||
pageHeader1.Name = "pageHeader1";
|
||||
pageHeader1.Size = new Size(1024, 40);
|
||||
pageHeader1.TabIndex = 7;
|
||||
pageHeader1.Text = "UPH";
|
||||
tabPage3.Controls.Add(panel7);
|
||||
tabPage3.Location = new Point(3, 3);
|
||||
tabPage3.Name = "tabPage3";
|
||||
tabPage3.Size = new Size(574, 170);
|
||||
tabPage3.TabIndex = 0;
|
||||
tabPage3.Text = "日志";
|
||||
//
|
||||
// label1
|
||||
// panel7
|
||||
//
|
||||
label1.AutoSize = true;
|
||||
label1.Location = new Point(979, 10);
|
||||
label1.Name = "label1";
|
||||
label1.Size = new Size(64, 21);
|
||||
label1.TabIndex = 1;
|
||||
label1.Text = "100000";
|
||||
//
|
||||
// divider2
|
||||
//
|
||||
divider2.Dock = DockStyle.Top;
|
||||
divider2.Location = new Point(54, 0);
|
||||
divider2.Name = "divider2";
|
||||
divider2.OrientationMargin = 0F;
|
||||
divider2.Size = new Size(970, 10);
|
||||
divider2.TabIndex = 0;
|
||||
divider2.Text = "";
|
||||
//
|
||||
// panelmain
|
||||
//
|
||||
panelmain.Controls.Add(panel2);
|
||||
panelmain.Controls.Add(panel1);
|
||||
panelmain.Dock = DockStyle.Fill;
|
||||
panelmain.Location = new Point(0, 40);
|
||||
panelmain.Margin = new Padding(0);
|
||||
panelmain.Name = "panelmain";
|
||||
panelmain.Size = new Size(1024, 568);
|
||||
panelmain.TabIndex = 8;
|
||||
//
|
||||
// panel2
|
||||
//
|
||||
panel2.Controls.Add(panel4);
|
||||
panel2.Dock = DockStyle.Fill;
|
||||
panel2.Location = new Point(0, 68);
|
||||
panel2.Name = "panel2";
|
||||
panel2.Size = new Size(1024, 500);
|
||||
panel2.TabIndex = 1;
|
||||
panel2.Text = "panel2";
|
||||
//
|
||||
// panel4
|
||||
//
|
||||
panel4.Controls.Add(panel6);
|
||||
panel4.Dock = DockStyle.Fill;
|
||||
panel4.Location = new Point(0, 0);
|
||||
panel4.Name = "panel4";
|
||||
panel4.Size = new Size(1024, 500);
|
||||
panel4.TabIndex = 1;
|
||||
panel4.Text = "panel4";
|
||||
//
|
||||
// panel6
|
||||
//
|
||||
panel6.Controls.Add(splitContainer1);
|
||||
panel6.Dock = DockStyle.Fill;
|
||||
panel6.Location = new Point(0, 0);
|
||||
panel6.Name = "panel6";
|
||||
panel6.Size = new Size(1024, 500);
|
||||
panel6.TabIndex = 1;
|
||||
panel6.Text = "panel6";
|
||||
//
|
||||
// splitContainer1
|
||||
//
|
||||
splitContainer1.BackColor = SystemColors.Control;
|
||||
splitContainer1.Dock = DockStyle.Fill;
|
||||
splitContainer1.Location = new Point(0, 0);
|
||||
splitContainer1.Name = "splitContainer1";
|
||||
//
|
||||
// splitContainer1.Panel1
|
||||
//
|
||||
splitContainer1.Panel1.Controls.Add(splitContainer2);
|
||||
//
|
||||
// splitContainer1.Panel2
|
||||
//
|
||||
splitContainer1.Panel2.BackColor = SystemColors.ButtonFace;
|
||||
splitContainer1.Panel2.Controls.Add(tabsConfig);
|
||||
splitContainer1.Size = new Size(1024, 500);
|
||||
splitContainer1.SplitterDistance = 580;
|
||||
splitContainer1.SplitterIncrement = 2;
|
||||
splitContainer1.SplitterWidth = 10;
|
||||
splitContainer1.TabIndex = 0;
|
||||
//
|
||||
// splitContainer2
|
||||
//
|
||||
splitContainer2.Dock = DockStyle.Fill;
|
||||
splitContainer2.Location = new Point(0, 0);
|
||||
splitContainer2.Name = "splitContainer2";
|
||||
splitContainer2.Orientation = Orientation.Horizontal;
|
||||
//
|
||||
// splitContainer2.Panel1
|
||||
//
|
||||
splitContainer2.Panel1.Controls.Add(tabImgDisplay);
|
||||
//
|
||||
// splitContainer2.Panel2
|
||||
//
|
||||
splitContainer2.Panel2.Controls.Add(tabsStas);
|
||||
splitContainer2.Size = new Size(580, 500);
|
||||
splitContainer2.SplitterDistance = 320;
|
||||
splitContainer2.TabIndex = 0;
|
||||
//
|
||||
// tabImgDisplay
|
||||
//
|
||||
tabImgDisplay.Controls.Add(tabMain);
|
||||
tabImgDisplay.Dock = DockStyle.Fill;
|
||||
tabImgDisplay.Location = new Point(0, 0);
|
||||
tabImgDisplay.Name = "tabImgDisplay";
|
||||
tabImgDisplay.Pages.Add(tabMain);
|
||||
tabImgDisplay.Size = new Size(580, 320);
|
||||
tabImgDisplay.Style = styleCard1;
|
||||
tabImgDisplay.TabIndex = 1;
|
||||
tabImgDisplay.Text = "tabs1";
|
||||
panel7.Dock = DockStyle.Fill;
|
||||
panel7.Location = new Point(0, 0);
|
||||
panel7.Name = "panel7";
|
||||
panel7.Size = new Size(574, 170);
|
||||
panel7.TabIndex = 2;
|
||||
//
|
||||
// tabMain
|
||||
//
|
||||
@ -259,59 +159,294 @@
|
||||
tabMain.TabIndex = 0;
|
||||
tabMain.Text = "检测";
|
||||
//
|
||||
// tabsStas
|
||||
// panelmain
|
||||
//
|
||||
tabsStas.Controls.Add(tabPage3);
|
||||
tabsStas.Dock = DockStyle.Fill;
|
||||
tabsStas.Location = new Point(0, 0);
|
||||
tabsStas.Name = "tabsStas";
|
||||
tabsStas.Pages.Add(tabPage3);
|
||||
tabsStas.Size = new Size(580, 176);
|
||||
tabsStas.Style = styleCard2;
|
||||
tabsStas.TabIndex = 3;
|
||||
tabsStas.Text = "tabs3";
|
||||
panelmain.Controls.Add(splitter2);
|
||||
panelmain.Controls.Add(panel2);
|
||||
panelmain.Controls.Add(panel1);
|
||||
panelmain.Dock = DockStyle.Fill;
|
||||
panelmain.Location = new Point(0, 40);
|
||||
panelmain.Margin = new Padding(0);
|
||||
panelmain.Name = "panelmain";
|
||||
panelmain.Size = new Size(1024, 631);
|
||||
panelmain.TabIndex = 8;
|
||||
//
|
||||
// tabPage3
|
||||
// splitter2
|
||||
//
|
||||
tabPage3.Controls.Add(richTextBox1);
|
||||
tabPage3.Location = new Point(3, 28);
|
||||
tabPage3.Name = "tabPage3";
|
||||
tabPage3.Size = new Size(574, 145);
|
||||
tabPage3.TabIndex = 0;
|
||||
tabPage3.Text = "日志";
|
||||
splitter2.Dock = DockStyle.Fill;
|
||||
splitter2.Location = new Point(0, 68);
|
||||
splitter2.Name = "splitter2";
|
||||
splitter2.Orientation = Orientation.Horizontal;
|
||||
//
|
||||
// richTextBox1
|
||||
// splitter2.Panel1
|
||||
//
|
||||
richTextBox1.Dock = DockStyle.Fill;
|
||||
richTextBox1.Location = new Point(0, 0);
|
||||
richTextBox1.Name = "richTextBox1";
|
||||
richTextBox1.Size = new Size(574, 145);
|
||||
richTextBox1.TabIndex = 0;
|
||||
richTextBox1.Text = "";
|
||||
splitter2.Panel1.Controls.Add(tabImgDisplay);
|
||||
//
|
||||
// tabsConfig
|
||||
// splitter2.Panel2
|
||||
//
|
||||
tabsConfig.Controls.Add(tabPage2);
|
||||
tabsConfig.Dock = DockStyle.Fill;
|
||||
tabsConfig.Location = new Point(0, 0);
|
||||
tabsConfig.Name = "tabsConfig";
|
||||
tabsConfig.Pages.Add(tabPage2);
|
||||
tabsConfig.Size = new Size(434, 500);
|
||||
tabsConfig.Style = styleCard3;
|
||||
tabsConfig.TabIndex = 2;
|
||||
tabsConfig.Text = "tabs2";
|
||||
splitter2.Panel2.Controls.Add(splitter1);
|
||||
splitter2.Size = new Size(1024, 563);
|
||||
splitter2.SplitterDistance = 442;
|
||||
splitter2.TabIndex = 4;
|
||||
//
|
||||
// tabPage2
|
||||
// tabImgDisplay
|
||||
//
|
||||
tabPage2.Location = new Point(3, 28);
|
||||
tabPage2.Name = "tabPage2";
|
||||
tabPage2.Size = new Size(428, 469);
|
||||
tabPage2.TabIndex = 0;
|
||||
tabPage2.Text = "配置";
|
||||
tabImgDisplay.Dock = DockStyle.Fill;
|
||||
tabImgDisplay.Location = new Point(0, 0);
|
||||
tabImgDisplay.Name = "tabImgDisplay";
|
||||
tabImgDisplay.Size = new Size(1024, 442);
|
||||
tabImgDisplay.Style = styleCard2;
|
||||
tabImgDisplay.TabIndex = 3;
|
||||
tabImgDisplay.Text = "tabs1";
|
||||
//
|
||||
// splitter1
|
||||
//
|
||||
splitter1.Dock = DockStyle.Fill;
|
||||
splitter1.Location = new Point(0, 0);
|
||||
splitter1.Name = "splitter1";
|
||||
//
|
||||
// splitter1.Panel1
|
||||
//
|
||||
splitter1.Panel1.Controls.Add(pnlLog);
|
||||
//
|
||||
// splitter1.Panel2
|
||||
//
|
||||
splitter1.Panel2.Controls.Add(panel6);
|
||||
splitter1.Size = new Size(1024, 117);
|
||||
splitter1.SplitterDistance = 332;
|
||||
splitter1.TabIndex = 3;
|
||||
//
|
||||
// pnlLog
|
||||
//
|
||||
pnlLog.Dock = DockStyle.Fill;
|
||||
pnlLog.Location = new Point(0, 0);
|
||||
pnlLog.Name = "pnlLog";
|
||||
pnlLog.Size = new Size(332, 117);
|
||||
pnlLog.TabIndex = 2;
|
||||
pnlLog.Text = "panel8";
|
||||
//
|
||||
// panel6
|
||||
//
|
||||
panel6.Controls.Add(tableLayoutstatistics);
|
||||
panel6.Dock = DockStyle.Fill;
|
||||
panel6.Location = new Point(0, 0);
|
||||
panel6.Name = "panel6";
|
||||
panel6.Size = new Size(688, 117);
|
||||
panel6.TabIndex = 0;
|
||||
panel6.Text = "panel6";
|
||||
//
|
||||
// tableLayoutstatistics
|
||||
//
|
||||
tableLayoutstatistics.ColumnCount = 2;
|
||||
tableLayoutstatistics.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 50F));
|
||||
tableLayoutstatistics.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 50F));
|
||||
tableLayoutstatistics.Controls.Add(dgvCamreaNums, 0, 0);
|
||||
tableLayoutstatistics.Controls.Add(panelNums, 1, 0);
|
||||
tableLayoutstatistics.Dock = DockStyle.Fill;
|
||||
tableLayoutstatistics.Location = new Point(0, 0);
|
||||
tableLayoutstatistics.Name = "tableLayoutstatistics";
|
||||
tableLayoutstatistics.RowCount = 1;
|
||||
tableLayoutstatistics.RowStyles.Add(new RowStyle(SizeType.Percent, 50F));
|
||||
tableLayoutstatistics.Size = new Size(688, 117);
|
||||
tableLayoutstatistics.TabIndex = 9;
|
||||
//
|
||||
// dgvCamreaNums
|
||||
//
|
||||
dgvCamreaNums.AllowUserToAddRows = false;
|
||||
dgvCamreaNums.AllowUserToDeleteRows = false;
|
||||
dgvCamreaNums.AllowUserToResizeColumns = false;
|
||||
dgvCamreaNums.AllowUserToResizeRows = false;
|
||||
dgvCamreaNums.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill;
|
||||
dgvCamreaNums.AutoSizeRowsMode = DataGridViewAutoSizeRowsMode.AllCells;
|
||||
dgvCamreaNums.BackgroundColor = SystemColors.Control;
|
||||
dgvCamreaNums.BorderStyle = BorderStyle.None;
|
||||
dgvCamreaNums.CellBorderStyle = DataGridViewCellBorderStyle.SunkenHorizontal;
|
||||
dgvCamreaNums.ColumnHeadersHeight = 4;
|
||||
dgvCamreaNums.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.DisableResizing;
|
||||
dgvCamreaNums.ColumnHeadersVisible = false;
|
||||
dgvCamreaNums.Dock = DockStyle.Fill;
|
||||
dgvCamreaNums.Location = new Point(3, 3);
|
||||
dgvCamreaNums.MultiSelect = false;
|
||||
dgvCamreaNums.Name = "dgvCamreaNums";
|
||||
dgvCamreaNums.ReadOnly = true;
|
||||
dgvCamreaNums.RowHeadersVisible = false;
|
||||
dgvCamreaNums.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
|
||||
dgvCamreaNums.Size = new Size(338, 111);
|
||||
dgvCamreaNums.TabIndex = 9;
|
||||
//
|
||||
// panelNums
|
||||
//
|
||||
panelNums.Controls.Add(tableLayoutNums);
|
||||
panelNums.Dock = DockStyle.Fill;
|
||||
panelNums.Location = new Point(347, 3);
|
||||
panelNums.Name = "panelNums";
|
||||
panelNums.Size = new Size(338, 111);
|
||||
panelNums.TabIndex = 8;
|
||||
panelNums.Text = "panel4";
|
||||
//
|
||||
// tableLayoutNums
|
||||
//
|
||||
tableLayoutNums.ColumnCount = 1;
|
||||
tableLayoutNums.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100F));
|
||||
tableLayoutNums.Controls.Add(dgvProductNums, 0, 0);
|
||||
tableLayoutNums.Controls.Add(tableLayoutPanel3, 0, 1);
|
||||
tableLayoutNums.Dock = DockStyle.Fill;
|
||||
tableLayoutNums.Location = new Point(0, 0);
|
||||
tableLayoutNums.Name = "tableLayoutNums";
|
||||
tableLayoutNums.RowCount = 2;
|
||||
tableLayoutNums.RowStyles.Add(new RowStyle(SizeType.Percent, 50F));
|
||||
tableLayoutNums.RowStyles.Add(new RowStyle(SizeType.Percent, 50F));
|
||||
tableLayoutNums.Size = new Size(338, 111);
|
||||
tableLayoutNums.TabIndex = 8;
|
||||
//
|
||||
// dgvProductNums
|
||||
//
|
||||
dgvProductNums.AllowUserToAddRows = false;
|
||||
dgvProductNums.AllowUserToDeleteRows = false;
|
||||
dgvProductNums.AllowUserToResizeColumns = false;
|
||||
dgvProductNums.AllowUserToResizeRows = false;
|
||||
dgvProductNums.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill;
|
||||
dgvProductNums.AutoSizeRowsMode = DataGridViewAutoSizeRowsMode.AllCells;
|
||||
dgvProductNums.BackgroundColor = SystemColors.Control;
|
||||
dgvProductNums.BorderStyle = BorderStyle.None;
|
||||
dgvProductNums.CellBorderStyle = DataGridViewCellBorderStyle.SunkenHorizontal;
|
||||
dgvProductNums.ColumnHeadersHeight = 4;
|
||||
dgvProductNums.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.DisableResizing;
|
||||
dgvProductNums.ColumnHeadersVisible = false;
|
||||
dgvProductNums.Dock = DockStyle.Fill;
|
||||
dgvProductNums.Location = new Point(3, 3);
|
||||
dgvProductNums.MultiSelect = false;
|
||||
dgvProductNums.Name = "dgvProductNums";
|
||||
dgvProductNums.ReadOnly = true;
|
||||
dgvProductNums.RowHeadersVisible = false;
|
||||
dgvProductNums.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
|
||||
dgvProductNums.Size = new Size(332, 49);
|
||||
dgvProductNums.TabIndex = 10;
|
||||
//
|
||||
// tableLayoutPanel3
|
||||
//
|
||||
tableLayoutPanel3.ColumnCount = 4;
|
||||
tableLayoutPanel3.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 50F));
|
||||
tableLayoutPanel3.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 50F));
|
||||
tableLayoutPanel3.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 81F));
|
||||
tableLayoutPanel3.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 75F));
|
||||
tableLayoutPanel3.Controls.Add(lblTotalTime, 1, 1);
|
||||
tableLayoutPanel3.Controls.Add(label1, 2, 1);
|
||||
tableLayoutPanel3.Controls.Add(label12, 0, 1);
|
||||
tableLayoutPanel3.Controls.Add(lblUPH, 3, 1);
|
||||
tableLayoutPanel3.Controls.Add(lblStartTime, 1, 0);
|
||||
tableLayoutPanel3.Controls.Add(lblOEE_Total, 3, 0);
|
||||
tableLayoutPanel3.Controls.Add(label10, 0, 0);
|
||||
tableLayoutPanel3.Controls.Add(label7, 2, 0);
|
||||
tableLayoutPanel3.Dock = DockStyle.Fill;
|
||||
tableLayoutPanel3.Location = new Point(3, 58);
|
||||
tableLayoutPanel3.Name = "tableLayoutPanel3";
|
||||
tableLayoutPanel3.RowCount = 2;
|
||||
tableLayoutPanel3.RowStyles.Add(new RowStyle(SizeType.Percent, 50F));
|
||||
tableLayoutPanel3.RowStyles.Add(new RowStyle(SizeType.Percent, 50F));
|
||||
tableLayoutPanel3.Size = new Size(332, 50);
|
||||
tableLayoutPanel3.TabIndex = 11;
|
||||
//
|
||||
// lblTotalTime
|
||||
//
|
||||
lblTotalTime.AutoSize = true;
|
||||
lblTotalTime.Dock = DockStyle.Fill;
|
||||
lblTotalTime.Location = new Point(91, 25);
|
||||
lblTotalTime.Name = "lblTotalTime";
|
||||
lblTotalTime.Size = new Size(82, 25);
|
||||
lblTotalTime.TabIndex = 15;
|
||||
lblTotalTime.Text = "0";
|
||||
lblTotalTime.TextAlign = ContentAlignment.MiddleCenter;
|
||||
//
|
||||
// label1
|
||||
//
|
||||
label1.AutoSize = true;
|
||||
label1.Dock = DockStyle.Fill;
|
||||
label1.Location = new Point(179, 25);
|
||||
label1.Name = "label1";
|
||||
label1.Size = new Size(75, 25);
|
||||
label1.TabIndex = 8;
|
||||
label1.Text = "UPH";
|
||||
label1.TextAlign = ContentAlignment.MiddleCenter;
|
||||
//
|
||||
// label12
|
||||
//
|
||||
label12.AutoSize = true;
|
||||
label12.Dock = DockStyle.Fill;
|
||||
label12.Location = new Point(3, 25);
|
||||
label12.Name = "label12";
|
||||
label12.Size = new Size(82, 25);
|
||||
label12.TabIndex = 14;
|
||||
label12.Text = "运行时间";
|
||||
label12.TextAlign = ContentAlignment.MiddleCenter;
|
||||
//
|
||||
// lblUPH
|
||||
//
|
||||
lblUPH.AutoSize = true;
|
||||
lblUPH.Dock = DockStyle.Fill;
|
||||
lblUPH.Location = new Point(260, 25);
|
||||
lblUPH.Name = "lblUPH";
|
||||
lblUPH.Size = new Size(69, 25);
|
||||
lblUPH.TabIndex = 9;
|
||||
lblUPH.Text = "0";
|
||||
lblUPH.TextAlign = ContentAlignment.MiddleCenter;
|
||||
//
|
||||
// lblStartTime
|
||||
//
|
||||
lblStartTime.AutoSize = true;
|
||||
lblStartTime.Dock = DockStyle.Fill;
|
||||
lblStartTime.Location = new Point(91, 0);
|
||||
lblStartTime.Name = "lblStartTime";
|
||||
lblStartTime.Size = new Size(82, 25);
|
||||
lblStartTime.TabIndex = 11;
|
||||
lblStartTime.Text = "0";
|
||||
lblStartTime.TextAlign = ContentAlignment.MiddleCenter;
|
||||
//
|
||||
// lblOEE_Total
|
||||
//
|
||||
lblOEE_Total.AutoSize = true;
|
||||
lblOEE_Total.Dock = DockStyle.Fill;
|
||||
lblOEE_Total.Location = new Point(260, 0);
|
||||
lblOEE_Total.Name = "lblOEE_Total";
|
||||
lblOEE_Total.Size = new Size(69, 25);
|
||||
lblOEE_Total.TabIndex = 13;
|
||||
lblOEE_Total.Text = "0";
|
||||
lblOEE_Total.TextAlign = ContentAlignment.MiddleCenter;
|
||||
//
|
||||
// label10
|
||||
//
|
||||
label10.AutoSize = true;
|
||||
label10.Dock = DockStyle.Fill;
|
||||
label10.Location = new Point(3, 0);
|
||||
label10.Name = "label10";
|
||||
label10.Size = new Size(82, 25);
|
||||
label10.TabIndex = 12;
|
||||
label10.Text = "开始时间";
|
||||
label10.TextAlign = ContentAlignment.MiddleCenter;
|
||||
//
|
||||
// label7
|
||||
//
|
||||
label7.AutoSize = true;
|
||||
label7.Dock = DockStyle.Fill;
|
||||
label7.Location = new Point(179, 0);
|
||||
label7.Name = "label7";
|
||||
label7.Size = new Size(75, 25);
|
||||
label7.TabIndex = 10;
|
||||
label7.Text = "总计数";
|
||||
label7.TextAlign = ContentAlignment.MiddleCenter;
|
||||
//
|
||||
// panel2
|
||||
//
|
||||
panel2.Location = new Point(511, 86);
|
||||
panel2.Name = "panel2";
|
||||
panel2.Size = new Size(814, 364);
|
||||
panel2.TabIndex = 3;
|
||||
panel2.Text = "panel2";
|
||||
//
|
||||
// panel1
|
||||
//
|
||||
panel1.Back = SystemColors.MenuHighlight;
|
||||
panel1.Back = Color.FromArgb(46, 108, 227);
|
||||
panel1.Controls.Add(panel3);
|
||||
panel1.Controls.Add(segmented1);
|
||||
panel1.Dock = DockStyle.Top;
|
||||
panel1.Location = new Point(0, 0);
|
||||
@ -322,6 +457,61 @@
|
||||
panel1.TabIndex = 0;
|
||||
panel1.Text = "panel1";
|
||||
//
|
||||
// panel3
|
||||
//
|
||||
panel3.Back = Color.FromArgb(46, 108, 227);
|
||||
panel3.Controls.Add(btnDeleteProject);
|
||||
panel3.Controls.Add(btnAddProject);
|
||||
panel3.Controls.Add(btnLoadProject);
|
||||
panel3.Controls.Add(sltProjects);
|
||||
panel3.Dock = DockStyle.Right;
|
||||
panel3.Location = new Point(553, 0);
|
||||
panel3.Name = "panel3";
|
||||
panel3.Padding = new Padding(30);
|
||||
panel3.Radius = 0;
|
||||
panel3.ShadowOpacity = 0F;
|
||||
panel3.ShadowOpacityHover = 0F;
|
||||
panel3.Size = new Size(471, 68);
|
||||
panel3.TabIndex = 16;
|
||||
panel3.Text = "panel3";
|
||||
//
|
||||
// btnDeleteProject
|
||||
//
|
||||
btnDeleteProject.Location = new Point(400, 18);
|
||||
btnDeleteProject.Name = "btnDeleteProject";
|
||||
btnDeleteProject.Size = new Size(68, 40);
|
||||
btnDeleteProject.TabIndex = 19;
|
||||
btnDeleteProject.Text = "删除";
|
||||
btnDeleteProject.Visible = false;
|
||||
//
|
||||
// btnAddProject
|
||||
//
|
||||
btnAddProject.Location = new Point(326, 18);
|
||||
btnAddProject.Name = "btnAddProject";
|
||||
btnAddProject.Size = new Size(68, 40);
|
||||
btnAddProject.TabIndex = 18;
|
||||
btnAddProject.Text = "新增";
|
||||
btnAddProject.Visible = false;
|
||||
//
|
||||
// btnLoadProject
|
||||
//
|
||||
btnLoadProject.Location = new Point(252, 18);
|
||||
btnLoadProject.Name = "btnLoadProject";
|
||||
btnLoadProject.Size = new Size(68, 40);
|
||||
btnLoadProject.TabIndex = 17;
|
||||
btnLoadProject.Text = "载入";
|
||||
btnLoadProject.Visible = false;
|
||||
//
|
||||
// sltProjects
|
||||
//
|
||||
sltProjects.List = true;
|
||||
sltProjects.Location = new Point(25, 18);
|
||||
sltProjects.Margin = new Padding(10);
|
||||
sltProjects.MaxCount = 10;
|
||||
sltProjects.Name = "sltProjects";
|
||||
sltProjects.Size = new Size(214, 40);
|
||||
sltProjects.TabIndex = 16;
|
||||
//
|
||||
// segmented1
|
||||
//
|
||||
segmented1.BackActive = Color.FromArgb(100, 255, 87, 34);
|
||||
@ -330,66 +520,56 @@
|
||||
segmented1.Font = new Font("Microsoft YaHei UI", 9F);
|
||||
segmented1.ForeColor = Color.White;
|
||||
segmented1.Full = true;
|
||||
segmentedItem1.Badge = null;
|
||||
segmentedItem1.BadgeAlign = AntdUI.TAlignFrom.TR;
|
||||
segmentedItem1.BadgeBack = null;
|
||||
segmentedItem1.BadgeMode = false;
|
||||
segmentedItem1.BadgeOffsetX = 0;
|
||||
segmentedItem1.BadgeOffsetY = 0;
|
||||
segmentedItem1.BadgeSize = 0.6F;
|
||||
segmentedItem1.BadgeSvg = null;
|
||||
segmentedItem1.IconActiveSvg = resources.GetString("segmentedItem1.IconActiveSvg");
|
||||
segmentedItem1.IconSvg = resources.GetString("segmentedItem1.IconSvg");
|
||||
segmentedItem1.Text = "启动";
|
||||
segmentedItem2.Badge = null;
|
||||
segmentedItem2.BadgeAlign = AntdUI.TAlignFrom.TR;
|
||||
segmentedItem2.BadgeBack = null;
|
||||
segmentedItem2.BadgeMode = false;
|
||||
segmentedItem2.BadgeOffsetX = 0;
|
||||
segmentedItem2.BadgeOffsetY = 0;
|
||||
segmentedItem2.BadgeSize = 0.6F;
|
||||
segmentedItem2.BadgeSvg = null;
|
||||
segmentedItem2.IconActiveSvg = resources.GetString("segmentedItem2.IconActiveSvg");
|
||||
segmentedItem2.IconSvg = resources.GetString("segmentedItem2.IconSvg");
|
||||
segmentedItem2.Text = "停止";
|
||||
segmentedItem3.Badge = null;
|
||||
segmentedItem3.BadgeAlign = AntdUI.TAlignFrom.TR;
|
||||
segmentedItem3.BadgeBack = null;
|
||||
segmentedItem3.BadgeMode = false;
|
||||
segmentedItem3.BadgeOffsetX = 0;
|
||||
segmentedItem3.BadgeOffsetY = 0;
|
||||
segmentedItem3.BadgeSize = 0.6F;
|
||||
segmentedItem3.BadgeSvg = null;
|
||||
segmentedItem3.IconActiveSvg = resources.GetString("segmentedItem3.IconActiveSvg");
|
||||
segmentedItem3.IconSvg = resources.GetString("segmentedItem3.IconSvg");
|
||||
segmentedItem3.Text = "复位";
|
||||
segmentedItem4.Badge = null;
|
||||
segmentedItem4.BadgeAlign = AntdUI.TAlignFrom.TR;
|
||||
segmentedItem4.BadgeBack = null;
|
||||
segmentedItem4.BadgeMode = false;
|
||||
segmentedItem4.BadgeOffsetX = 0;
|
||||
segmentedItem4.BadgeOffsetY = 0;
|
||||
segmentedItem4.BadgeSize = 0.6F;
|
||||
segmentedItem4.BadgeSvg = null;
|
||||
segmentedItem4.IconActiveSvg = resources.GetString("segmentedItem4.IconActiveSvg");
|
||||
segmentedItem4.IconSvg = resources.GetString("segmentedItem4.IconSvg");
|
||||
segmentedItem4.Text = "设置";
|
||||
segmentedItem5.Badge = null;
|
||||
segmentedItem5.BadgeAlign = AntdUI.TAlignFrom.TR;
|
||||
segmentedItem5.BadgeBack = null;
|
||||
segmentedItem5.BadgeMode = false;
|
||||
segmentedItem5.BadgeOffsetX = 0;
|
||||
segmentedItem5.BadgeOffsetY = 0;
|
||||
segmentedItem5.BadgeSize = 0.6F;
|
||||
segmentedItem5.BadgeSvg = null;
|
||||
segmentedItem5.IconActiveSvg = resources.GetString("segmentedItem5.IconActiveSvg");
|
||||
segmentedItem5.IconSvg = resources.GetString("segmentedItem5.IconSvg");
|
||||
segmentedItem5.Text = "登录";
|
||||
segmented1.Items.Add(segmentedItem1);
|
||||
segmented1.Items.Add(segmentedItem2);
|
||||
segmented1.Items.Add(segmentedItem3);
|
||||
segmented1.Items.Add(segmentedItem4);
|
||||
segmented1.Items.Add(segmentedItem5);
|
||||
segmentedItem6.Badge = null;
|
||||
segmentedItem6.BadgeAlign = AntdUI.TAlignFrom.TR;
|
||||
segmentedItem6.BadgeBack = null;
|
||||
segmentedItem6.BadgeMode = false;
|
||||
segmentedItem6.BadgeOffsetX = 0;
|
||||
segmentedItem6.BadgeOffsetY = 0;
|
||||
segmentedItem6.BadgeSize = 0.6F;
|
||||
segmentedItem6.BadgeSvg = null;
|
||||
segmentedItem6.Text = "启动";
|
||||
segmentedItem7.Badge = null;
|
||||
segmentedItem7.BadgeAlign = AntdUI.TAlignFrom.TR;
|
||||
segmentedItem7.BadgeBack = null;
|
||||
segmentedItem7.BadgeMode = false;
|
||||
segmentedItem7.BadgeOffsetX = 0;
|
||||
segmentedItem7.BadgeOffsetY = 0;
|
||||
segmentedItem7.BadgeSize = 0.6F;
|
||||
segmentedItem7.BadgeSvg = null;
|
||||
segmentedItem7.Text = "停止";
|
||||
segmentedItem8.Badge = null;
|
||||
segmentedItem8.BadgeAlign = AntdUI.TAlignFrom.TR;
|
||||
segmentedItem8.BadgeBack = null;
|
||||
segmentedItem8.BadgeMode = false;
|
||||
segmentedItem8.BadgeOffsetX = 0;
|
||||
segmentedItem8.BadgeOffsetY = 0;
|
||||
segmentedItem8.BadgeSize = 0.6F;
|
||||
segmentedItem8.BadgeSvg = null;
|
||||
segmentedItem8.Text = "复位";
|
||||
segmentedItem9.Badge = null;
|
||||
segmentedItem9.BadgeAlign = AntdUI.TAlignFrom.TR;
|
||||
segmentedItem9.BadgeBack = null;
|
||||
segmentedItem9.BadgeMode = false;
|
||||
segmentedItem9.BadgeOffsetX = 0;
|
||||
segmentedItem9.BadgeOffsetY = 0;
|
||||
segmentedItem9.BadgeSize = 0.6F;
|
||||
segmentedItem9.BadgeSvg = null;
|
||||
segmentedItem9.Text = "登录";
|
||||
segmentedItem10.Badge = null;
|
||||
segmentedItem10.BadgeAlign = AntdUI.TAlignFrom.TR;
|
||||
segmentedItem10.BadgeBack = null;
|
||||
segmentedItem10.BadgeMode = false;
|
||||
segmentedItem10.BadgeOffsetX = 0;
|
||||
segmentedItem10.BadgeOffsetY = 0;
|
||||
segmentedItem10.BadgeSize = 0.6F;
|
||||
segmentedItem10.BadgeSvg = null;
|
||||
segmentedItem10.Text = "设置";
|
||||
segmented1.Items.Add(segmentedItem6);
|
||||
segmented1.Items.Add(segmentedItem7);
|
||||
segmented1.Items.Add(segmentedItem8);
|
||||
segmented1.Items.Add(segmentedItem9);
|
||||
segmented1.Items.Add(segmentedItem10);
|
||||
segmented1.Location = new Point(0, 0);
|
||||
segmented1.Name = "segmented1";
|
||||
segmented1.Size = new Size(491, 68);
|
||||
@ -399,65 +579,88 @@
|
||||
//
|
||||
// MainWindow
|
||||
//
|
||||
ClientSize = new Size(1024, 648);
|
||||
ClientSize = new Size(1024, 671);
|
||||
ControlBox = false;
|
||||
Controls.Add(panelmain);
|
||||
Controls.Add(pageHeader1);
|
||||
Controls.Add(titlebar);
|
||||
Font = new Font("Microsoft YaHei UI", 9F, FontStyle.Regular, GraphicsUnit.Point, 134);
|
||||
Icon = (Icon)resources.GetObject("$this.Icon");
|
||||
Name = "MainWindow";
|
||||
StartPosition = FormStartPosition.CenterScreen;
|
||||
Text = "AntdUI Demo";
|
||||
Text = "CCD光学筛选系统";
|
||||
WindowState = FormWindowState.Maximized;
|
||||
FormClosed += MainWindow_FormClosed;
|
||||
FormClosing += MainWindow_FormClosing;
|
||||
Load += MainWindow_Load;
|
||||
titlebar.ResumeLayout(false);
|
||||
pageHeader1.ResumeLayout(false);
|
||||
pageHeader1.PerformLayout();
|
||||
panelmain.ResumeLayout(false);
|
||||
panel2.ResumeLayout(false);
|
||||
panel4.ResumeLayout(false);
|
||||
panel6.ResumeLayout(false);
|
||||
splitContainer1.Panel1.ResumeLayout(false);
|
||||
splitContainer1.Panel2.ResumeLayout(false);
|
||||
((System.ComponentModel.ISupportInitialize)splitContainer1).EndInit();
|
||||
splitContainer1.ResumeLayout(false);
|
||||
splitContainer2.Panel1.ResumeLayout(false);
|
||||
splitContainer2.Panel2.ResumeLayout(false);
|
||||
((System.ComponentModel.ISupportInitialize)splitContainer2).EndInit();
|
||||
splitContainer2.ResumeLayout(false);
|
||||
tabImgDisplay.ResumeLayout(false);
|
||||
tabsStas.ResumeLayout(false);
|
||||
tabPage3.ResumeLayout(false);
|
||||
tabsConfig.ResumeLayout(false);
|
||||
panelmain.ResumeLayout(false);
|
||||
splitter2.Panel1.ResumeLayout(false);
|
||||
splitter2.Panel2.ResumeLayout(false);
|
||||
((System.ComponentModel.ISupportInitialize)splitter2).EndInit();
|
||||
splitter2.ResumeLayout(false);
|
||||
splitter1.Panel1.ResumeLayout(false);
|
||||
splitter1.Panel2.ResumeLayout(false);
|
||||
((System.ComponentModel.ISupportInitialize)splitter1).EndInit();
|
||||
splitter1.ResumeLayout(false);
|
||||
panel6.ResumeLayout(false);
|
||||
tableLayoutstatistics.ResumeLayout(false);
|
||||
((System.ComponentModel.ISupportInitialize)dgvCamreaNums).EndInit();
|
||||
panelNums.ResumeLayout(false);
|
||||
tableLayoutNums.ResumeLayout(false);
|
||||
((System.ComponentModel.ISupportInitialize)dgvProductNums).EndInit();
|
||||
tableLayoutPanel3.ResumeLayout(false);
|
||||
tableLayoutPanel3.PerformLayout();
|
||||
panel1.ResumeLayout(false);
|
||||
panel3.ResumeLayout(false);
|
||||
ResumeLayout(false);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private AntdUI.PageHeader titlebar;
|
||||
private AntdUI.Button buttonSZ;
|
||||
private AntdUI.Button button_color;
|
||||
private AntdUI.PageHeader pageHeader1;
|
||||
private AntdUI.Divider divider2;
|
||||
private AntdUI.Panel panelmain;
|
||||
private AntdUI.Panel panel1;
|
||||
private AntdUI.Segmented segmented1;
|
||||
private AntdUI.Panel panel2;
|
||||
private AntdUI.Panel panel4;
|
||||
private AntdUI.Panel panel6;
|
||||
private Label label1;
|
||||
private AntdUI.Splitter splitter1;
|
||||
private SplitContainer splitContainer1;
|
||||
private SplitContainer splitContainer2;
|
||||
private AntdUI.Tabs tabImgDisplay;
|
||||
|
||||
private AntdUI.Label lbName;
|
||||
private AntdUI.Panel panel3;
|
||||
private AntdUI.Button btnDeleteProject;
|
||||
private AntdUI.Button btnAddProject;
|
||||
private AntdUI.Button btnLoadProject;
|
||||
public AntdUI.Select sltProjects;
|
||||
private Panel panel7;
|
||||
// private Panel panel5;
|
||||
// private Label lblNum;
|
||||
// private Label label2;
|
||||
// private Label lblNowtime;
|
||||
// private Label label8;
|
||||
// private Label lblstarttime;
|
||||
// private Label label6;
|
||||
// private Label lblUPH;
|
||||
private Label label4;
|
||||
private AntdUI.TabPage tabPage3;
|
||||
private AntdUI.TabPage tabMain;
|
||||
private AntdUI.Tabs tabsStas;
|
||||
private AntdUI.TabPage tabPage3;
|
||||
private RichTextBox richTextBox1;
|
||||
private AntdUI.Tabs tabsConfig;
|
||||
private AntdUI.TabPage tabPage2;
|
||||
private AntdUI.Panel panel2;
|
||||
private AntdUI.Tabs tabImgDisplay;
|
||||
private AntdUI.Panel panel6;
|
||||
private AntdUI.Panel pnlLog;
|
||||
private AntdUI.Splitter splitter2;
|
||||
private TableLayoutPanel tableLayoutstatistics;
|
||||
private AntdUI.Panel panelNums;
|
||||
private DataGridView dgvCamreaNums;
|
||||
private TableLayoutPanel tableLayoutNums;
|
||||
private Label label1;
|
||||
private Label lblTotalTime;
|
||||
private Label lblUPH;
|
||||
private Label label12;
|
||||
private Label label7;
|
||||
private Label lblOEE_Total;
|
||||
private Label lblStartTime;
|
||||
private Label label10;
|
||||
private DataGridView dgvProductNums;
|
||||
private TableLayoutPanel tableLayoutPanel3;
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -117,39 +117,6 @@
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<data name="buttonSZ.IconSvg" xml:space="preserve">
|
||||
<value><svg t="1724122928419" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2893" width="200" height="200"><path d="M920.5 435.9c-7.6-40.3-36.1-66.8-69.8-66.2h-3.4c-36.6 0-66.3-29.7-66.3-66.3 0-7.8 3.6-19.1 6-24.9 15.4-35.1 3.3-78.1-28.9-100.6l-102-56.9-4.2-2c-31.7-13.7-72.7-5.4-96.4 19.2-15.1 15.6-42.2 33.7-54.6 33.7-12.5 0-39.8-18.5-54.9-34.3-23.6-24.9-62.2-34.4-97.4-19.5l-105.4 57.7-4.2 2.7c-31.7 22-43.8 65.3-28.3 100.1 1.9 4.6 6 16.7 6 24.9 0 36.6-29.7 66.3-66.3 66.3h-2.6c-34.9-0.6-63.1 25.8-70.7 66.2-0.9 4.8-8.9 48.2-8.9 84s8 79.2 8.9 84c7.5 39.6 35.3 66.2 69.2 66.2h4.1c36.6 0 66.3 29.7 66.3 66.3 0 8.2-4 20.3-5.8 24.5-15.6 35.2-3.6 78.4 28.9 101.2l99.8 56 4.1 2c10.5 4.6 21.8 6.9 33.6 6.9 24.5 0 47.8-9.9 63.7-27.3 14.8-16.1 43.5-35.8 55.8-35.8 12.8 0 40.8 19.7 56.1 36.5 15.8 17.4 39.8 27.8 64.2 27.8 11.6 0 22.6-2.2 34.3-7.3l103.2-56.9 4.2-2.7c31.6-22 43.7-65.2 28.1-100.4-1.9-4.6-5.9-16.5-5.9-24.6 0-36.6 29.7-66.3 66.3-66.3h4c34 0 61.7-26.4 69.2-65.9 0.1-0.5 9-46.3 9-84.4-0.1-35.9-8.1-79.1-9-83.9z m-71.3 154.6c-0.6 3.3-1.5 5.6-2.2 7.1-76.4 0.1-138.6 62.4-138.6 138.8 0 23 8.4 45.7 12.1 53.9 1.6 3.5 0.4 8.4-3.3 11.5l-96.4 53.3c-4.7 1.6-11.9-0.9-14.3-3.5-5.6-6.2-56.5-60.3-109.8-60.3-54 0-106.9 56.8-109.1 59.2-2.2 2.4-7.4 5.7-14.6 3.1l-93.1-52.1c-3.1-2.5-4.5-7.7-2.8-11.6 1.2-2.8 12-28.1 12-53.7 0-76.5-62.1-138.7-138.6-138.8-0.7-1.5-1.6-3.8-2.3-7.1-0.3-1.6-7.6-40.9-7.6-70.6 0-29.7 7.3-69 7.6-70.6 0.6-3.3 1.5-5.7 2.3-7.1 76.4-0.1 138.6-62.3 138.6-138.8 0-25-9.9-49.1-12.1-54-1.5-3.5-0.4-8.3 3.2-11.4l98.2-53.9c4.8-1.7 12.5 0.8 15 3.4 5.5 5.8 55.7 56.8 107.4 56.8 51.2 0 101.2-50 106.7-55.8 2.4-2.4 8.3-5.6 15.1-3.1l94.9 52.7c3.2 2.5 4.5 7.7 2.9 11.3l-0.7 1.8c-3.1 7.6-11.3 29.8-11.3 52.2 0 76.5 62.1 138.7 138.6 138.8 0.7 1.5 1.6 3.8 2.3 7.1 0.1 0.4 7.6 40.6 7.6 70.6-0.1 25.6-5.7 60.4-7.7 70.8z" p-id="2894"></path><path d="M498.7 355.9c-90.3 0-163.8 73.5-163.8 163.8 0 90.3 73.5 163.8 163.8 163.8 90.3 0 163.8-73.5 163.8-163.8 0-90.4-73.5-163.8-163.8-163.8z m0 273.1c-60.3 0-109.4-49.1-109.4-109.4 0-60.3 49.1-109.4 109.4-109.4 60.3 0 109.4 49.1 109.4 109.4 0 60.3-49.1 109.4-109.4 109.4z" p-id="2895"></path></svg></value>
|
||||
</data>
|
||||
<data name="segmentedItem1.IconActiveSvg" xml:space="preserve">
|
||||
<value><svg viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg" width="200" height="200"><path d="M731.818667 500.280889L386.844444 239.729778a14.677333 14.677333 0 0 0-23.495111 11.719111v521.159111a14.677333 14.677333 0 0 0 23.495111 11.662222l344.860445-260.608a14.677333 14.677333 0 0 0 0.113778-23.381333z" fill="#FFFFFF"/><path d="M512 1024a512 512 0 1 1 512-512 512.568889 512.568889 0 0 1-512 512z m0-946.915556A434.915556 434.915556 0 1 0 946.915556 512 435.427556 435.427556 0 0 0 512 77.084444z" fill="#FFFFFF"/></svg></value>
|
||||
</data>
|
||||
<data name="segmentedItem1.IconSvg" xml:space="preserve">
|
||||
<value><svg viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg" width="200" height="200"><path d="M731.818667 500.280889L386.844444 239.729778a14.677333 14.677333 0 0 0-23.495111 11.719111v521.159111a14.677333 14.677333 0 0 0 23.495111 11.662222l344.860445-260.608a14.677333 14.677333 0 0 0 0.113778-23.381333z" fill="#FFFFFF"/><path d="M512 1024a512 512 0 1 1 512-512 512.568889 512.568889 0 0 1-512 512z m0-946.915556A434.915556 434.915556 0 1 0 946.915556 512 435.427556 435.427556 0 0 0 512 77.084444z" fill="#FFFFFF"/></svg></value>
|
||||
</data>
|
||||
<data name="segmentedItem2.IconActiveSvg" xml:space="preserve">
|
||||
<value><svg viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg" width="200" height="200"><path d="M365.014704 657.815846H657.084939V365.74561H365.014704V657.815846zm584.140471-146.035118c0-240.906781-197.125482-438.105353-438.105353-438.105353-240.979872 0-438.105353 197.198572-438.105354 438.105353 0 240.979872 197.125482 438.178444 438.105354 438.178444 240.979872 0 438.105353-197.198572 438.105353-438.178444zM511.634547 0.730906c281.399001 0 511.634547 230.235546 511.634547 511.634547s-230.235546 511.634547-511.634547 511.634547-511.634547-230.235546-511.634547-511.634547 230.235546-511.634547 511.634547-511.634547z" fill="#FFFFFF"/></svg></value>
|
||||
</data>
|
||||
<data name="segmentedItem2.IconSvg" xml:space="preserve">
|
||||
<value><svg viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg" width="200" height="200"><path d="M365.014704 657.815846H657.084939V365.74561H365.014704V657.815846zm584.140471-146.035118c0-240.906781-197.125482-438.105353-438.105353-438.105353-240.979872 0-438.105353 197.198572-438.105354 438.105353 0 240.979872 197.125482 438.178444 438.105354 438.178444 240.979872 0 438.105353-197.198572 438.105353-438.178444zM511.634547 0.730906c281.399001 0 511.634547 230.235546 511.634547 511.634547s-230.235546 511.634547-511.634547 511.634547-511.634547-230.235546-511.634547-511.634547 230.235546-511.634547 511.634547-511.634547z" fill="#FFFFFF"/></svg></value>
|
||||
</data>
|
||||
<data name="segmentedItem3.IconActiveSvg" xml:space="preserve">
|
||||
<value><svg viewBox="0 0 1027 1024" xmlns="http://www.w3.org/2000/svg" width="200" height="200"><path d="M512 0C229.376 0 0 229.376 0 512s229.376 512 512 512 512-229.376 512-512S794.624 0 512 0zm0 963.584c-249.344 0-451.584-202.24-451.584-451.584S262.656 60.416 512 60.416s451.584 202.24 451.584 451.584-202.24 451.584-451.584 451.584z" fill="#FFFFFF"/><path d="M527.36 351.744V292.864L410.624 380.416 527.36 468.48V410.624c72.192 8.192 124.416 73.216 116.224 145.408-8.192 72.192-73.216 124.416-145.408 116.224-66.56-7.168-117.248-64-117.248-131.072-0.512-5.12-0.512-9.728 0-14.848H323.584c-0.512 5.12-0.512 9.728 0 14.848 0 104.96 85.504 189.952 190.464 189.952s189.952-85.504 189.952-190.464c-0.512-99.328-77.312-181.76-176.64-188.928z" fill="#FFFFFF"/></svg></value>
|
||||
</data>
|
||||
<data name="segmentedItem3.IconSvg" xml:space="preserve">
|
||||
<value><svg viewBox="0 0 1027 1024" xmlns="http://www.w3.org/2000/svg" width="200" height="200"><path d="M512 0C229.376 0 0 229.376 0 512s229.376 512 512 512 512-229.376 512-512S794.624 0 512 0zm0 963.584c-249.344 0-451.584-202.24-451.584-451.584S262.656 60.416 512 60.416s451.584 202.24 451.584 451.584-202.24 451.584-451.584 451.584z" fill="#FFFFFF"/><path d="M527.36 351.744V292.864L410.624 380.416 527.36 468.48V410.624c72.192 8.192 124.416 73.216 116.224 145.408-8.192 72.192-73.216 124.416-145.408 116.224-66.56-7.168-117.248-64-117.248-131.072-0.512-5.12-0.512-9.728 0-14.848H323.584c-0.512 5.12-0.512 9.728 0 14.848 0 104.96 85.504 189.952 190.464 189.952s189.952-85.504 189.952-190.464c-0.512-99.328-77.312-181.76-176.64-188.928z" fill="#FFFFFF"/></svg></value>
|
||||
</data>
|
||||
<data name="segmentedItem4.IconActiveSvg" xml:space="preserve">
|
||||
<value><svg viewBox="0 0 1027 1024" xmlns="http://www.w3.org/2000/svg" width="200" height="200"><path d="M512 0C229.376 0 0 229.376 0 512s229.376 512 512 512 512-229.376 512-512S794.624 0 512 0zm0 963.584c-249.344 0-451.584-202.24-451.584-451.584S262.656 60.416 512 60.416s451.584 202.24 451.584 451.584-202.24 451.584-451.584 451.584z" fill="#FFFFFF"/><path d="M437.314 840.84l-18.967-5.795c-43.935-13.425-84.182-35.551-119.623-65.767l-15.203-12.962 11.199-16.544c17.376-25.668 17.938-59.158 1.433-85.319-14.356-22.787-39.028-36.385-66.006-36.385-4.102 0-8.229 0.328-12.267 0.974l-19.752 3.158-5.301-19.288c-8.196-29.823-12.353-59.896-12.353-89.381 0-19.675 1.863-39.491 5.694-60.582l3.652-20.105 20.349 1.862c2.343 0.214 4.726 0.323 7.081 0.323 29.007 0 55.436-15.908 68.974-41.516 14.941-28.2 11.264-62.223-9.356-86.694l-13.166-15.625L278.1 276.7c38.694-38.954 86.677-68.095 138.76-84.273l19.741-6.132 7.631 19.211c11.88 29.908 40.312 49.234 72.432 49.234 32.097 0 60.521-19.328 72.413-49.241l7.632-19.197 19.73 6.122c43.968 13.642 84.295 36.164 119.862 66.938l15.414 13.337-11.883 16.561c-18.636 25.975-19.684 60.166-2.671 87.105 14.369 22.78 39.055 36.373 66.04 36.372 4.344 0 8.71-0.366 12.978-1.087l20.143-3.403 5.176 19.762c7.539 28.792 11.362 57.566 11.362 85.522 0 21.328-2.143 43.048-6.365 64.554l-3.859 19.65-19.952-1.709a77.999 77.999 0 0 0-6.612-0.281c-28.998 0-55.44 15.917-69.009 41.542-14.47 27.405-11.311 60.816 8.063 85.095l12.496 15.661-14.222 14.111c-38.674 38.378-86.551 67.041-138.455 82.892l-18.968 5.792-7.988-18.152c-12.462-28.318-40.459-46.617-71.325-46.617-30.883 0-58.893 18.299-71.36 46.619l-7.99 18.152zm-95.455-94.18c22.324 16.82 46.59 30.174 72.469 39.881 22.445-34.023 60.731-55.125 102.336-55.125 41.59 0 79.862 21.1 102.303 55.12 32.745-12.298 63.249-30.557 89.663-53.667-19.709-35.774-20.525-79.555-1.04-116.455 19.699-37.203 56.634-61.386 98.053-64.883 1.705-12.731 2.565-25.453 2.565-38 0-18.339-1.923-37.155-5.729-56.144-42.123-0.241-80.616-21.581-103.077-57.189-22.944-36.331-25.024-81.029-6.697-118.768-22.165-16.932-46.203-30.4-71.788-40.221-8.847 14.328-20.577 26.719-34.618 36.447-20.522 14.219-44.602 21.735-69.635 21.735-25.044 0-49.131-7.516-69.657-21.734-14.042-9.727-25.773-22.116-34.618-36.441-32.551 12.503-62.856 30.935-89.106 54.196 21.198 36.233 22.547 80.974 2.407 118.987-19.71 37.285-56.808 61.499-98.402 64.875-1.45 11.713-2.161 23.035-2.161 34.255 0 19.715 2.166 39.792 6.449 59.894 41.851 0.474 80.029 21.785 102.35 57.214 22.218 35.217 24.782 78.871 7.933 116.023z" fill="#FFFFFF"/><path d="M516.664 633.864c-66.246 0-120.141-53.897-120.141-120.147 0-66.249 53.895-120.146 120.141-120.146 66.237 0 120.127 53.897 120.127 120.146 0 66.25-53.89 120.147-120.127 120.147zm0-195.641c-41.625 0-75.488 33.866-75.488 75.494s33.863 75.495 75.488 75.495c41.617 0 75.475-33.867 75.475-75.495s-33.858-75.494-75.475-75.494z" fill="#FFFFFF"/></svg></value>
|
||||
</data>
|
||||
<data name="segmentedItem4.IconSvg" xml:space="preserve">
|
||||
<value><svg viewBox="0 0 1027 1024" xmlns="http://www.w3.org/2000/svg" width="200" height="200"><path d="M512 0C229.376 0 0 229.376 0 512s229.376 512 512 512 512-229.376 512-512S794.624 0 512 0zm0 963.584c-249.344 0-451.584-202.24-451.584-451.584S262.656 60.416 512 60.416s451.584 202.24 451.584 451.584-202.24 451.584-451.584 451.584z" fill="#FFFFFF"/><path d="M437.314 840.84l-18.967-5.795c-43.935-13.425-84.182-35.551-119.623-65.767l-15.203-12.962 11.199-16.544c17.376-25.668 17.938-59.158 1.433-85.319-14.356-22.787-39.028-36.385-66.006-36.385-4.102 0-8.229 0.328-12.267 0.974l-19.752 3.158-5.301-19.288c-8.196-29.823-12.353-59.896-12.353-89.381 0-19.675 1.863-39.491 5.694-60.582l3.652-20.105 20.349 1.862c2.343 0.214 4.726 0.323 7.081 0.323 29.007 0 55.436-15.908 68.974-41.516 14.941-28.2 11.264-62.223-9.356-86.694l-13.166-15.625L278.1 276.7c38.694-38.954 86.677-68.095 138.76-84.273l19.741-6.132 7.631 19.211c11.88 29.908 40.312 49.234 72.432 49.234 32.097 0 60.521-19.328 72.413-49.241l7.632-19.197 19.73 6.122c43.968 13.642 84.295 36.164 119.862 66.938l15.414 13.337-11.883 16.561c-18.636 25.975-19.684 60.166-2.671 87.105 14.369 22.78 39.055 36.373 66.04 36.372 4.344 0 8.71-0.366 12.978-1.087l20.143-3.403 5.176 19.762c7.539 28.792 11.362 57.566 11.362 85.522 0 21.328-2.143 43.048-6.365 64.554l-3.859 19.65-19.952-1.709a77.999 77.999 0 0 0-6.612-0.281c-28.998 0-55.44 15.917-69.009 41.542-14.47 27.405-11.311 60.816 8.063 85.095l12.496 15.661-14.222 14.111c-38.674 38.378-86.551 67.041-138.455 82.892l-18.968 5.792-7.988-18.152c-12.462-28.318-40.459-46.617-71.325-46.617-30.883 0-58.893 18.299-71.36 46.619l-7.99 18.152zm-95.455-94.18c22.324 16.82 46.59 30.174 72.469 39.881 22.445-34.023 60.731-55.125 102.336-55.125 41.59 0 79.862 21.1 102.303 55.12 32.745-12.298 63.249-30.557 89.663-53.667-19.709-35.774-20.525-79.555-1.04-116.455 19.699-37.203 56.634-61.386 98.053-64.883 1.705-12.731 2.565-25.453 2.565-38 0-18.339-1.923-37.155-5.729-56.144-42.123-0.241-80.616-21.581-103.077-57.189-22.944-36.331-25.024-81.029-6.697-118.768-22.165-16.932-46.203-30.4-71.788-40.221-8.847 14.328-20.577 26.719-34.618 36.447-20.522 14.219-44.602 21.735-69.635 21.735-25.044 0-49.131-7.516-69.657-21.734-14.042-9.727-25.773-22.116-34.618-36.441-32.551 12.503-62.856 30.935-89.106 54.196 21.198 36.233 22.547 80.974 2.407 118.987-19.71 37.285-56.808 61.499-98.402 64.875-1.45 11.713-2.161 23.035-2.161 34.255 0 19.715 2.166 39.792 6.449 59.894 41.851 0.474 80.029 21.785 102.35 57.214 22.218 35.217 24.782 78.871 7.933 116.023z" fill="#FFFFFF"/><path d="M516.664 633.864c-66.246 0-120.141-53.897-120.141-120.147 0-66.249 53.895-120.146 120.141-120.146 66.237 0 120.127 53.897 120.127 120.146 0 66.25-53.89 120.147-120.127 120.147zm0-195.641c-41.625 0-75.488 33.866-75.488 75.494s33.863 75.495 75.488 75.495c41.617 0 75.475-33.867 75.475-75.495s-33.858-75.494-75.475-75.494z" fill="#FFFFFF"/></svg></value>
|
||||
</data>
|
||||
<data name="segmentedItem5.IconActiveSvg" xml:space="preserve">
|
||||
<value><svg viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg" width="200" height="200"><path d="M512 0C229.376 0 0 229.376 0 512s229.376 512 512 512 512-229.376 512-512S794.624 0 512 0zm0 963.584c-249.344 0-451.584-202.24-451.584-451.584S262.656 60.416 512 60.416s451.584 202.24 451.584 451.584-202.24 451.584-451.584 451.584z" fill="#FFFFFF"/><path transform="scale(0.8) translate(128,128)" d="M960.853333 903.816533a463.633067 463.633067 0 0 0-11.264-39.185066c-1.536-4.539733-3.413333-8.942933-5.051733-13.448534a484.078933 484.078933 0 0 0-9.557333-24.4736c-2.2528-5.188267-4.881067-10.274133-7.338667-15.394133-3.413333-7.099733-6.8608-14.165333-10.6496-21.0944-2.901333-5.3248-6.075733-10.513067-9.181867-15.701333-2.423467-4.061867-4.573867-8.226133-7.133866-12.219734-1.604267-2.4576-3.413333-4.778667-5.0176-7.202133-1.501867-2.218667-2.730667-4.608-4.266667-6.792533-0.4096-0.6144-1.058133-0.887467-1.501867-1.4336a461.482667 461.482667 0 0 0-90.385066-96.768c-13.5168-10.786133-27.7504-20.48-42.257067-29.5936-0.477867-0.341333-0.7168-0.8192-1.194667-1.1264-3.6864-2.286933-7.509333-4.3008-11.264-6.485334-4.266667-2.491733-8.4992-5.051733-12.868266-7.441066-6.826667-3.6864-13.789867-7.099733-20.753067-10.478934-3.618133-1.7408-7.202133-3.618133-10.8544-5.290666a449.194667 449.194667 0 0 0-31.607467-12.731734c-0.7168-0.273067-1.365333-0.6144-2.082133-0.8192-3.140267-1.1264-6.417067-1.911467-9.557333-2.935466-4.164267-1.399467-8.328533-2.833067-12.561067-4.096a259.9936 259.9936 0 0 0 129.194667-225.450667 260.061867 260.061867 0 0 0-76.629334-185.002667 259.9936 259.9936 0 0 0-185.002666-76.629333H512h-0.034133a259.857067 259.857067 0 0 0-185.002667 76.629333 259.925333 259.925333 0 0 0-76.629333 185.002667 259.584 259.584 0 0 0 76.629333 185.002667c15.906133 15.940267 33.655467 29.2864 52.565333 40.448-4.266667 1.262933-8.430933 2.730667-12.663466 4.096-3.140267 1.058133-6.3488 1.8432-9.489067 2.935466-0.7168 0.238933-1.365333 0.580267-2.048 0.8192-10.683733 3.822933-21.265067 8.0896-31.675733 12.765867-3.584 1.604267-7.0656 3.4816-10.615467 5.154133-7.099733 3.413333-14.165333 6.826667-21.0944 10.615467-4.266667 2.321067-8.3968 4.8128-12.561067 7.2704-3.822933 2.218667-7.748267 4.266667-11.502933 6.621867-0.512 0.3072-0.750933 0.8192-1.2288 1.160533-14.506667 9.147733-28.706133 18.807467-42.222933 29.559467a459.6736 459.6736 0 0 0-90.385067 96.768c-0.443733 0.546133-1.092267 0.8192-1.501867 1.4336-1.536 2.184533-2.7648 4.573867-4.266666 6.792533-1.604267 2.423467-3.447467 4.744533-5.0176 7.202133-2.56 3.9936-4.7104 8.157867-7.133867 12.219734-3.106133 5.188267-6.280533 10.376533-9.181867 15.701333-3.7888 6.929067-7.202133 13.994667-10.6496 21.0944-2.4576 5.12-5.051733 10.205867-7.338666 15.394133-3.515733 8.021333-6.519467 16.247467-9.557334 24.4736-1.672533 4.5056-3.549867 8.9088-5.051733 13.448534-4.3008 12.868267-8.0896 25.941333-11.264 39.185066-3.072 12.970667 2.594133 25.770667 13.073067 32.802134a31.3344 31.3344 0 0 0 9.966933 4.608 30.9248 30.9248 0 0 0 34.030933-15.2576 30.446933 30.446933 0 0 0 3.345067-7.7824c2.833067-11.844267 6.178133-23.483733 10.0352-34.9184 0.6144-1.8432 1.399467-3.549867 2.013867-5.358934 3.447467-9.762133 7.133867-19.456 11.332266-28.945066 0.512-1.160533 1.1264-2.2528 1.6384-3.447467 4.7104-10.308267 9.728-20.48 15.291734-30.344533l0.068266-0.1024a402.773333 402.773333 0 0 1 19.694934-31.4368l0.136533-0.375467a397.4144 397.4144 0 0 1 116.599467-111.2064c0.136533-0.1024 0.3072-0.068267 0.443733-0.170667a397.824 397.824 0 0 1 94.993067-42.973866c2.7648-0.8192 5.495467-1.7408 8.2944-2.491734 5.7344-1.604267 11.5712-3.003733 17.373866-4.334933a367.8208 367.8208 0 0 1 47.342934-7.953067c3.8912-0.443733 7.7824-0.9216 11.6736-1.2288 10.410667-0.785067 20.8896-1.3312 31.505066-1.3312s21.060267 0.546133 31.505067 1.3312c3.8912 0.3072 7.816533 0.785067 11.707733 1.2288a361.3696 361.3696 0 0 1 47.240534 7.953067c5.870933 1.3312 11.707733 2.730667 17.5104 4.334933 2.696533 0.750933 5.358933 1.6384 8.021333 2.4576 33.348267 10.103467 65.365333 24.405333 95.197867 43.008 0.136533 0.1024 0.3072 0.068267 0.443733 0.170667a396.151467 396.151467 0 0 1 116.599467 111.2064c0.1024 0.136533 0.1024 0.273067 0.170666 0.375467 13.687467 19.7632 25.3952 40.5504 35.191467 62.1568l1.467733 3.037866c4.3008 9.659733 8.055467 19.592533 11.605334 29.5936 0.546133 1.604267 1.2288 3.106133 1.774933 4.7104 3.822933 11.4688 7.236267 23.176533 10.0352 35.0208a31.061333 31.061333 0 0 0 60.450133-14.336zm-249.275733-560.2304A199.850667 199.850667 0 0 1 512 543.197867a199.850667 199.850667 0 0 1-199.5776-199.611734A199.816533 199.816533 0 0 1 512 144.008533a199.816533 199.816533 0 0 1 199.5776 199.5776z" fill="#FFFFFF"/></svg></value>
|
||||
</data>
|
||||
<data name="segmentedItem5.IconSvg" xml:space="preserve">
|
||||
<value><svg viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg" width="200" height="200"><path d="M512 0C229.376 0 0 229.376 0 512s229.376 512 512 512 512-229.376 512-512S794.624 0 512 0zm0 963.584c-249.344 0-451.584-202.24-451.584-451.584S262.656 60.416 512 60.416s451.584 202.24 451.584 451.584-202.24 451.584-451.584 451.584z" fill="#FFFFFF"/><path transform="scale(0.8) translate(128,128)" d="M960.853333 903.816533a463.633067 463.633067 0 0 0-11.264-39.185066c-1.536-4.539733-3.413333-8.942933-5.051733-13.448534a484.078933 484.078933 0 0 0-9.557333-24.4736c-2.2528-5.188267-4.881067-10.274133-7.338667-15.394133-3.413333-7.099733-6.8608-14.165333-10.6496-21.0944-2.901333-5.3248-6.075733-10.513067-9.181867-15.701333-2.423467-4.061867-4.573867-8.226133-7.133866-12.219734-1.604267-2.4576-3.413333-4.778667-5.0176-7.202133-1.501867-2.218667-2.730667-4.608-4.266667-6.792533-0.4096-0.6144-1.058133-0.887467-1.501867-1.4336a461.482667 461.482667 0 0 0-90.385066-96.768c-13.5168-10.786133-27.7504-20.48-42.257067-29.5936-0.477867-0.341333-0.7168-0.8192-1.194667-1.1264-3.6864-2.286933-7.509333-4.3008-11.264-6.485334-4.266667-2.491733-8.4992-5.051733-12.868266-7.441066-6.826667-3.6864-13.789867-7.099733-20.753067-10.478934-3.618133-1.7408-7.202133-3.618133-10.8544-5.290666a449.194667 449.194667 0 0 0-31.607467-12.731734c-0.7168-0.273067-1.365333-0.6144-2.082133-0.8192-3.140267-1.1264-6.417067-1.911467-9.557333-2.935466-4.164267-1.399467-8.328533-2.833067-12.561067-4.096a259.9936 259.9936 0 0 0 129.194667-225.450667 260.061867 260.061867 0 0 0-76.629334-185.002667 259.9936 259.9936 0 0 0-185.002666-76.629333H512h-0.034133a259.857067 259.857067 0 0 0-185.002667 76.629333 259.925333 259.925333 0 0 0-76.629333 185.002667 259.584 259.584 0 0 0 76.629333 185.002667c15.906133 15.940267 33.655467 29.2864 52.565333 40.448-4.266667 1.262933-8.430933 2.730667-12.663466 4.096-3.140267 1.058133-6.3488 1.8432-9.489067 2.935466-0.7168 0.238933-1.365333 0.580267-2.048 0.8192-10.683733 3.822933-21.265067 8.0896-31.675733 12.765867-3.584 1.604267-7.0656 3.4816-10.615467 5.154133-7.099733 3.413333-14.165333 6.826667-21.0944 10.615467-4.266667 2.321067-8.3968 4.8128-12.561067 7.2704-3.822933 2.218667-7.748267 4.266667-11.502933 6.621867-0.512 0.3072-0.750933 0.8192-1.2288 1.160533-14.506667 9.147733-28.706133 18.807467-42.222933 29.559467a459.6736 459.6736 0 0 0-90.385067 96.768c-0.443733 0.546133-1.092267 0.8192-1.501867 1.4336-1.536 2.184533-2.7648 4.573867-4.266666 6.792533-1.604267 2.423467-3.447467 4.744533-5.0176 7.202133-2.56 3.9936-4.7104 8.157867-7.133867 12.219734-3.106133 5.188267-6.280533 10.376533-9.181867 15.701333-3.7888 6.929067-7.202133 13.994667-10.6496 21.0944-2.4576 5.12-5.051733 10.205867-7.338666 15.394133-3.515733 8.021333-6.519467 16.247467-9.557334 24.4736-1.672533 4.5056-3.549867 8.9088-5.051733 13.448534-4.3008 12.868267-8.0896 25.941333-11.264 39.185066-3.072 12.970667 2.594133 25.770667 13.073067 32.802134a31.3344 31.3344 0 0 0 9.966933 4.608 30.9248 30.9248 0 0 0 34.030933-15.2576 30.446933 30.446933 0 0 0 3.345067-7.7824c2.833067-11.844267 6.178133-23.483733 10.0352-34.9184 0.6144-1.8432 1.399467-3.549867 2.013867-5.358934 3.447467-9.762133 7.133867-19.456 11.332266-28.945066 0.512-1.160533 1.1264-2.2528 1.6384-3.447467 4.7104-10.308267 9.728-20.48 15.291734-30.344533l0.068266-0.1024a402.773333 402.773333 0 0 1 19.694934-31.4368l0.136533-0.375467a397.4144 397.4144 0 0 1 116.599467-111.2064c0.136533-0.1024 0.3072-0.068267 0.443733-0.170667a397.824 397.824 0 0 1 94.993067-42.973866c2.7648-0.8192 5.495467-1.7408 8.2944-2.491734 5.7344-1.604267 11.5712-3.003733 17.373866-4.334933a367.8208 367.8208 0 0 1 47.342934-7.953067c3.8912-0.443733 7.7824-0.9216 11.6736-1.2288 10.410667-0.785067 20.8896-1.3312 31.505066-1.3312s21.060267 0.546133 31.505067 1.3312c3.8912 0.3072 7.816533 0.785067 11.707733 1.2288a361.3696 361.3696 0 0 1 47.240534 7.953067c5.870933 1.3312 11.707733 2.730667 17.5104 4.334933 2.696533 0.750933 5.358933 1.6384 8.021333 2.4576 33.348267 10.103467 65.365333 24.405333 95.197867 43.008 0.136533 0.1024 0.3072 0.068267 0.443733 0.170667a396.151467 396.151467 0 0 1 116.599467 111.2064c0.1024 0.136533 0.1024 0.273067 0.170666 0.375467 13.687467 19.7632 25.3952 40.5504 35.191467 62.1568l1.467733 3.037866c4.3008 9.659733 8.055467 19.592533 11.605334 29.5936 0.546133 1.604267 1.2288 3.106133 1.774933 4.7104 3.822933 11.4688 7.236267 23.176533 10.0352 35.0208a31.061333 31.061333 0 0 0 60.450133-14.336zm-249.275733-560.2304A199.850667 199.850667 0 0 1 512 543.197867a199.850667 199.850667 0 0 1-199.5776-199.611734A199.816533 199.816533 0 0 1 512 144.008533a199.816533 199.816533 0 0 1 199.5776 199.5776z" fill="#FFFFFF"/></svg></value>
|
||||
</data>
|
||||
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
|
||||
<data name="$this.Icon" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user