尺寸测量功能界面

This commit is contained in:
2025-03-16 17:32:09 +08:00
parent 0ac00af0ad
commit 25cd61c5cb
63 changed files with 12697 additions and 36 deletions

View 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
View 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
View 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));
}
}
}
}

View 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

Binary file not shown.

After

Width:  |  Height:  |  Size: 836 B

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
View 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
View File

@ -0,0 +1,53 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace CanFly.UI
{
public partial class BaseFrmGuide : Form
{
public BaseFrmGuide()
{
InitializeComponent();
// 处理 Panel 的大小变化事件,以动态更新控件宽度
panelMain.SizeChanged += PanelMain_SizeChanged; ;
}
private void PanelMain_SizeChanged(object? sender, EventArgs e)
{
foreach (Control control in flowPanelContent.Controls)
{
control.Width = panelMain.Width - 6; // 根据 Panel 的宽度调整控件
}
}
public void SetTitle(string title)
{
this.lblTitle.Text = title;
}
public void SetLogo(Image logo)
{
this.pbLogo.BackgroundImage = logo;
this.pbLogo.SizeMode = PictureBoxSizeMode.StretchImage;
this.pbLogo.Refresh();
}
private void BaseFrmGuide_Load(object sender, EventArgs e)
{
}
}
}

120
CanFly/UI/BaseFrmGuide.resx Normal file
View File

@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

279
CanFly/UI/FrmMain.Designer.cs generated Normal file
View 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
View 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
View 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
View 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
View 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
View 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>

View 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();
}
}
}

View 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>

View 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;
}
}

View 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();
}
}
}

View 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>

View 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;
}
}

View 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);
}
}
}

View 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>

View 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;
}
}

View 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)
{
}
}
}

View 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>

View 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;
}
}

View 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);
}
}
}

View 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>

View 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;
}
}

View 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);
}
}
}

View 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>

View 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;
}
}

View 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);
}
}
}

View 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
View 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
View 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>