using System;
using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using HalconDotNet;
namespace Plugins.Halcon.Views
{
/// HALCON 画面框的显示结果类型(OK/NG/无)。
public enum HalconResultType { Null, OK, NG }
/// 双击放大回调(与 VppWindow.MouseDoubleDelegate 对等)。
public delegate void HalconMouseDoubleDelegate(HalconWindow window, int number);
///
/// 单个 HALCON 画面框(镜像 VppWindow/VmWindow 的角色):标题、状态圆点、图像区。
/// 图像区用 HALCON 原生 WPF 控件 (内置缩放/平移):
/// - RefreshImage(image, overlay):经典模式——单底图 + 单叠加(主页画面框用);
/// - ShowLayers(layers):图层模式——底图 + 多彩色叠加(编辑器大显示窗按图层筛选渲染);
/// - 鼠标移动实时读取 行/列/灰度;支持拖入图片文件、右键保存图片、适应窗体;
/// - 右键菜单可交互绘制 矩形/旋转矩形/圆形 ROI(HDrawingObject),结果存 。
/// 所有 HALCON 调用集中在 或本类;显示操作统一切到 UI 线程。
/// 所有权规则:外部传入的 HObject 只引用不释放;由本窗体从 GenImage 转换出的副本(owned)在本窗体负责释放。
///
public partial class HalconWindow : UserControl
{
/// 双击放大/还原回调(由 UCDispHalcon 挂接)。
public HalconMouseDoubleDelegate MouseDouble { get; set; }
/// 画面框编号(1 起)。
public int Number { get; }
// HALCON 显示面与右键菜单改为 code-behind 防御式创建(见 InitHalconSurface):
// 机器缺 halcon.dll 等原生运行库时,XAML 声明式创建 + WPF 渲染期会抛出
// DllNotFoundException(首次可被吞掉,二次渲染异常直接致命闪退)。
private HSmartWindowControlWPF MyHwindow;
private ContextMenu MyMenu;
// —— 经典模式状态(单图 + 单叠加) ——
private HObject _image;
private bool _imageOwned;
private HObject _overlay;
private bool _overlayOwned;
private int _imgW, _imgH;
private bool _hasImage;
// —— 图层模式状态(底图 + 多叠加) ——
private readonly List _layerOwnedCopies = new List(); // 本窗体自有的转换副本(释放责任在本窗体)
private HObject _layerBaseImage;
private bool _layerBaseOwned;
private readonly List> _layerOverlays = new List>();
private int _layerImgW, _layerImgH;
private bool _layerMode;
/// 图层缺省配色(按叠加顺序取色,可用 LayerItem.Color 覆盖)。
private static readonly string[] LayerPalette = { "red", "green", "blue", "yellow", "cyan", "magenta", "orange" };
// ROI 交互绘制
private HDrawingObject _drawing;
private bool _drawingBusy;
/// 最近一次交互绘制得到的 ROI(供节点读取;未绘制时为 null)。
public Models.HalconRoi LastRoi { get; private set; }
public HalconWindow() : this(1) { }
public HalconWindow(int number)
{
Number = number;
InitializeComponent();
CaptionText.Text = $"画面 {number}";
InitHalconSurface();
SizeChanged += (s, e) => { if (e.NewSize.Width > 1) { FitCurrent(); } };
}
///
/// 防御式创建 HALCON 显示面:先做一次原生调用探测(缺 halcon.dll 等运行库时立即失败),
/// 可用才创建 HSmartWindowControlWPF 并挂事件/右键菜单;不可用则显示错误占位。
/// 保证 Halcon 流程编辑器等宿主在无原生运行库的机器上照常打开,不闪退。
///
private void InitHalconSurface()
{
if (!TryProbeHalconNative(out var probeError))
{
NativeErrorText.Text = "HALCON 原生运行库不可用\n\n" +
$"原因:{probeError}\n\n" +
"请检查 Runtime\\dll\\x64 下的 halcon.dll 及配套运行库是否完整," +
"或安装 HALCON 运行时。流程画布与属性编辑不受影响。";
NativeErrorText.Visibility = Visibility.Visible;
return;
}
try
{
var hw = new HSmartWindowControlWPF
{
HDoubleClickToFitContent = false,
AllowDrop = true,
Cursor = Cursors.Cross
};
hw.HMouseMove += MyHwindow_HMouseMove;
hw.MouseLeave += MyHwindow_MouseLeave;
hw.MouseRightButtonDown += MyHwindow_MouseRightButtonDown;
hw.Drop += MyHwindow_Drop;
hw.DragEnter += MyHwindow_DragEnter;
MyMenu = BuildContextMenu();
hw.ContextMenu = MyMenu;
MyHwindow = hw;
HwindowHost.Content = hw;
}
catch (Exception ex)
{
MyHwindow = null;
NativeErrorText.Text = $"HALCON 显示控件创建失败:{ex.Message}";
NativeErrorText.Visibility = Visibility.Visible;
}
}
/// 原生运行库探测:一次无副作用的 HALCON 调用,失败=缺原生 DLL。
private static bool TryProbeHalconNative(out string error)
{
try
{
HOperatorSet.GetSystem("version", out HTuple version);
error = null;
return true;
}
catch (Exception ex)
{
error = ex.Message;
return false;
}
}
/// 构建显示区右键菜单(缩放/适应/保存/ROI 绘制)。
private ContextMenu BuildContextMenu()
{
var menu = new ContextMenu();
void AddHandler(string header, RoutedEventHandler onClick)
{
var mi = new MenuItem { Header = header };
mi.Click += onClick;
menu.Items.Add(mi);
}
AddHandler("放大", MenuZoomIn_Click);
AddHandler("缩小", MenuZoomOut_Click);
AddHandler("适应窗体", MenuFit_Click);
AddHandler("保存图片", MenuSave_Click);
menu.Items.Add(new Separator());
AddHandler("绘制矩形ROI", MenuRoiRect1_Click);
AddHandler("绘制旋转矩形ROI", MenuRoiRect2_Click);
AddHandler("绘制圆形ROI", MenuRoiCircle_Click);
AddHandler("清除ROI", MenuRoiClear_Click);
return menu;
}
/// HALCON 窗口句柄(控件初始化后才有效;用前判空)。
private HWindow Hwn
{
get { try { return MyHwindow?.HalconWindow; } catch { return null; } }
}
#region 引擎/显示插件调用的公共接口(与 VmWindow 对齐)
public void SetCaption(string caption)
{
if (!Dispatcher.CheckAccess()) { Dispatcher.Invoke(() => SetCaption(caption)); return; }
CaptionText.Text = string.IsNullOrWhiteSpace(caption) ? $"画面 {Number}" : caption;
}
public void SetStatusDotVisible(bool visible)
{
if (!Dispatcher.CheckAccess()) { Dispatcher.Invoke(() => SetStatusDotVisible(visible)); return; }
StatusDot.Visibility = visible ? Visibility.Visible : Visibility.Collapsed;
}
/// 按 OK/NG 刷状态圆点颜色(并置为可见)。
public void SetLable(HalconResultType type)
{
if (!Dispatcher.CheckAccess()) { Dispatcher.Invoke(() => SetLable(type)); return; }
StatusDot.Visibility = Visibility.Visible;
switch (type)
{
case HalconResultType.OK: StatusDot.Fill = new SolidColorBrush(Color.FromRgb(0x4C, 0xAF, 0x50)); break;
case HalconResultType.NG: StatusDot.Fill = new SolidColorBrush(Color.FromRgb(0xF4, 0x43, 0x36)); break;
default: StatusDot.Fill = new SolidColorBrush(Color.FromRgb(0x88, 0x88, 0x88)); break;
}
}
///
/// 【经典模式】刷新显示:image=图像(HObject/GenImage/Bitmap),overlay=可选叠加对象(区域/XLD,红色边界绘制)。
/// 从流程传入的 HObject 只引用不释放;从 GenImage 转换的副本由本窗体负责释放。
///
public void RefreshImage(object image, object overlay = null)
{
if (!Dispatcher.CheckAccess()) { Dispatcher.Invoke(() => RefreshImage(image, overlay)); return; }
// 经典调用接管显示:退出图层模式
ExitLayerMode();
var hw = Hwn;
if (hw == null) return;
// image 为 null:仅更新叠加层(保留当前底图),供只产出区域的节点使用
if (image == null)
{
if (overlay == null) return;
try
{
bool ovOwned = !(overlay is HObject);
var hover = HalconRuntime.ToHObject(overlay);
if (_overlayOwned) HalconRuntime.Dispose(_overlay);
_overlay = hover; _overlayOwned = ovOwned;
Redraw();
}
catch { }
return;
}
try
{
bool imgOwned = !(image is HObject);
var himg = HalconRuntime.ToHObject(image);
HObject hover = null;
bool overOwned = false;
if (overlay != null)
{
overOwned = !(overlay is HObject);
try { hover = HalconRuntime.ToHObject(overlay); } catch { hover = null; }
}
HOperatorSet.GetImageSize(himg, out HTuple wT, out HTuple hT);
int w = wT.I, h = hT.I;
// 释放上一帧「本窗体自有」的副本(流程对象不动)
if (_imageOwned) HalconRuntime.Dispose(_image);
if (_overlayOwned) HalconRuntime.Dispose(_overlay);
_image = himg; _imageOwned = imgOwned;
_overlay = hover; _overlayOwned = overOwned;
_hasImage = true;
bool needFit = w != _imgW || h != _imgH;
_imgW = w; _imgH = h;
if (needFit) FitPart();
Redraw();
}
catch { /* 显示失败不影响流程 */ }
}
/// 清空画面显示。
public void ClearImage()
{
if (!Dispatcher.CheckAccess()) { Dispatcher.Invoke(new Action(ClearImage)); return; }
try
{
ExitLayerMode();
if (_imageOwned) HalconRuntime.Dispose(_image);
if (_overlayOwned) HalconRuntime.Dispose(_overlay);
_image = null; _overlay = null; _hasImage = false; _imgW = _imgH = 0;
Hwn?.ClearWindow();
}
catch { }
}
#endregion
#region 图层显示(编辑器大显示窗 / 图层筛选)
///
/// 【图层模式】按图层集渲染:首个 Image 图层作底图,其余按 LayerItem.Color(缺省调色板)叠加。
/// 图层对象的「注册表自有」部分只引用不释放;本窗体从 GenImage 转换出的副本在下次刷新/清理时释放。
///
public void ShowLayers(IReadOnlyList layers)
{
if (!Dispatcher.CheckAccess()) { Dispatcher.Invoke(() => ShowLayers(layers)); return; }
ExitLayerMode();
var hw = Hwn;
if (hw == null || layers == null || layers.Count == 0) return;
try
{
foreach (var layer in layers)
{
if (layer == null || layer.Content == null) continue;
if (layer.Kind == TeamAAS.Vision.LayerKind.Image)
{
bool owned = !(layer.Content is HObject);
var himg = HalconRuntime.ToHObject(layer.Content);
if (owned) _layerOwnedCopies.Add(himg);
if (_layerBaseOwned && _layerBaseImage != null) HalconRuntime.Dispose(_layerBaseImage);
_layerBaseImage = himg;
_layerBaseOwned = owned;
}
else
{
bool owned = !(layer.Content is HObject);
var hobj = HalconRuntime.ToHObject(layer.Content);
if (owned) _layerOwnedCopies.Add(hobj);
var color = string.IsNullOrWhiteSpace(layer.Color)
? LayerPalette[_layerOverlays.Count % LayerPalette.Length]
: layer.Color;
_layerOverlays.Add(new KeyValuePair(hobj, color));
}
}
if (_layerBaseImage != null && _layerBaseImage.IsInitialized())
{
HOperatorSet.GetImageSize(_layerBaseImage, out HTuple wT, out HTuple hT);
int w = wT.I, h = hT.I;
bool needFit = w != _layerImgW || h != _layerImgH;
_layerImgW = w; _layerImgH = h;
if (needFit) FitPart();
}
_layerMode = true;
Redraw();
}
catch
{
ExitLayerMode();
}
}
/// 退出图层模式:释放本窗体自有的图层副本,恢复经典状态。
private void ExitLayerMode()
{
_layerMode = false;
foreach (var copy in _layerOwnedCopies)
HalconRuntime.Dispose(copy);
_layerOwnedCopies.Clear();
if (_layerBaseOwned) HalconRuntime.Dispose(_layerBaseImage);
_layerBaseImage = null; _layerBaseOwned = false;
_layerOverlays.Clear();
_layerImgW = _layerImgH = 0;
}
/// 图层模式重绘:底图 + 多彩叠加。
private void RedrawLayers()
{
var hw = Hwn;
if (hw == null) return;
try
{
HOperatorSet.SetSystem("flush_graphic", "false");
hw.ClearWindow();
bool hasBase = _layerBaseImage != null && _layerBaseImage.IsInitialized();
HObject dispBase = hasBase ? ToDisplayImage(_layerBaseImage) : null; // 位深归一化显示
if (hasBase) { hw.SetColor("default"); hw.SetDraw("fill"); hw.DispObj(dispBase); }
foreach (var kv in _layerOverlays)
{
if (kv.Key == null || !kv.Key.IsInitialized()) continue;
hw.SetColor(string.IsNullOrWhiteSpace(kv.Value) ? "red" : kv.Value);
hw.SetDraw("margin");
hw.SetLineWidth(2.0);
hw.DispObj(kv.Key);
}
HOperatorSet.SetSystem("flush_graphic", "true");
if (dispBase != null && !ReferenceEquals(dispBase, _layerBaseImage)) dispBase.Dispose();
}
catch { }
}
#endregion
#region 显示绘制
/// 按当前模式重绘(保持当前缩放/平移的 part)。
private void Redraw()
{
if (_layerMode) { RedrawLayers(); return; }
var hw = Hwn;
if (hw == null) return;
bool hasImg = _image != null && _image.IsInitialized();
bool hasOv = _overlay != null && _overlay.IsInitialized();
if (!hasImg && !hasOv) return;
try
{
HOperatorSet.SetSystem("flush_graphic", "false");
hw.ClearWindow();
HObject dispImg = hasImg ? ToDisplayImage(_image) : null; // 位深归一化显示
if (hasImg) { hw.SetDraw("fill"); hw.DispObj(dispImg); }
if (hasOv)
{
hw.SetColor("red");
hw.SetDraw("margin");
hw.SetLineWidth(2.0);
hw.DispObj(_overlay);
}
HOperatorSet.SetSystem("flush_graphic", "true");
if (dispImg != null && !ReferenceEquals(dispImg, _image)) dispImg.Dispose();
}
catch { }
}
/// 按当前模式的图像尺寸做等比适配。
private void FitCurrent()
{
if (_layerMode) { FitImage(_layerImgW, _layerImgH); return; }
FitImage(_imgW, _imgH);
}
/// 按图像尺寸与控件尺寸做等比适配(set_part),不拉伸变形。
private void FitPart()
{
FitImage(_layerMode ? _layerImgW : _imgW, _layerMode ? _layerImgH : _imgH);
}
// 首次显示时控件可能尚未完成布局(ActualWidth=0),此时 Fit 只能挂起,
// 等布局完成补做 —— 否则显示区域(part)停在默认值,大图只露出某个角落,肉眼上"全黑"
private bool _pendingFit;
private void FitImage(int imgW, int imgH)
{
var hw = Hwn;
if (hw == null || imgW <= 0 || imgH <= 0) return;
double W = MyHwindow?.ActualWidth ?? 0, H = MyHwindow?.ActualHeight ?? 0;
if (W <= 1 || H <= 1)
{
if (!_pendingFit)
{
_pendingFit = true;
MyHwindow.LayoutUpdated += OnLayoutPendingFit;
}
return;
}
_pendingFit = false;
try
{
double winAspect = W / H;
double imgAspect = (double)imgW / imgH;
double partW, partH;
if (imgAspect > winAspect) { partW = imgW; partH = imgW / winAspect; }
else { partH = imgH; partW = imgH * winAspect; }
double r1 = -(partH - imgH) / 2.0;
double c1 = -(partW - imgW) / 2.0;
hw.SetPart(r1, c1, r1 + partH - 1, c1 + partW - 1);
}
catch { }
}
/// 布局完成后补做挂起的适配(回到正确显示区域)。
private void OnLayoutPendingFit(object sender, EventArgs e)
{
if (!_pendingFit) { MyHwindow.LayoutUpdated -= OnLayoutPendingFit; return; }
int imgW = _layerMode ? _layerImgW : _imgW;
int imgH = _layerMode ? _layerImgH : _imgH;
if (imgW <= 0 || MyHwindow == null || MyHwindow.ActualWidth <= 1) return;
_pendingFit = false;
MyHwindow.LayoutUpdated -= OnLayoutPendingFit;
FitCurrent();
Redraw();
}
///
/// 显示用规范化:uint2/int2/int4/real 图像按实际灰度范围拉伸到 0-255 再转 byte。
/// 背景:HALCON 显示 uint2 时灰度 100 只相当于位深的 0.15%,肉眼上"整幅是黑的",
/// 而灰度读数(直接取像素值)完全正常 —— 16 位相机图像黑屏即此原因。byte 原样返回。
///
private static HObject ToDisplayImage(HObject img)
{
try
{
HOperatorSet.GetImageType(img, out HTuple t);
var type = t.S;
if (type == "byte" || type == "complex" || type == "vector_field") return img;
HOperatorSet.MinMaxGray(img, img, 0, out HTuple mn, out HTuple mx, out HTuple _);
double min = mn.D, range = mx.D - min;
if (range < 1) range = 1;
double scale = 255.0 / range;
HOperatorSet.ScaleImage(img, out HObject scaled, scale, -min * scale);
HOperatorSet.ConvertImageType(scaled, out HObject byteImg, "byte");
scaled.Dispose();
return byteImg;
}
catch { return img; }
}
#endregion
#region 鼠标读取 / 拖放 / 双击
private void MyHwindow_HMouseMove(object sender, HSmartWindowControlWPF.HMouseEventArgsWPF e)
{
try
{
int row = (int)e.Row, col = (int)e.Column;
string txt = $"行:{row} 列:{col}";
var img = _layerMode ? _layerBaseImage : _image;
int imgH = _layerMode ? _layerImgH : _imgH;
int imgW = _layerMode ? _layerImgW : _imgW;
if (img != null && img.IsInitialized() &&
row >= 0 && col >= 0 && row < imgH && col < imgW)
{
try
{
HOperatorSet.GetGrayval(img, row, col, out HTuple gray);
txt += $" 灰度:{gray.D:F0}";
}
catch { }
}
CoordText.Text = txt;
CoordText.Visibility = Visibility.Visible;
}
catch { }
}
private void MyHwindow_MouseLeave(object sender, MouseEventArgs e) => CoordText.Visibility = Visibility.Collapsed;
private void MyHwindow_DragEnter(object sender, DragEventArgs e)
=> e.Effects = e.Data.GetDataPresent(DataFormats.FileDrop) ? DragDropEffects.Copy : DragDropEffects.None;
private void MyHwindow_Drop(object sender, DragEventArgs e)
{
try
{
if (e.Data.GetData(DataFormats.FileDrop) is string[] files && files.Length > 0)
{
HOperatorSet.ReadImage(out HObject img, files[0]);
RefreshImage(img); // 拖入的图像由本窗体持有
_imageOwned = true;
}
}
catch { }
}
private void UserControl_MouseDoubleClick(object sender, MouseButtonEventArgs e)
=> MouseDouble?.Invoke(this, Number);
// 绘制 ROI 时右键用于「确认」,此时抑制右键菜单;非绘制态恢复菜单
private void MyHwindow_MouseRightButtonDown(object sender, MouseButtonEventArgs e)
{
if (_drawingBusy) MyHwindow.ContextMenu = null;
else MyHwindow.ContextMenu = MyMenu;
}
#endregion
#region 右键菜单:适应 / 保存
private void MenuFit_Click(object sender, RoutedEventArgs e) { FitCurrent(); Redraw(); }
private void MenuZoomIn_Click(object sender, RoutedEventArgs e) => ZoomBy(0.8); // part 变小 = 放大
private void MenuZoomOut_Click(object sender, RoutedEventArgs e) => ZoomBy(1.25); // part 变大 = 缩小
///
/// 以画面中心为基准缩放:factor<1 放大、>1 缩小。读写窗口 part(GetPart/SetPart),
/// 与 HSmartWindowControlWPF 内置的鼠标滚轮缩放共用同一 part 状态,不冲突。
///
public void ZoomBy(double factor)
{
var hw = Hwn;
int refH = _layerMode ? _layerImgH : _imgH;
int refW = _layerMode ? _layerImgW : _imgW;
bool hasAny = _layerMode ? (_layerBaseImage != null && _layerBaseImage.IsInitialized()) : _hasImage;
if (hw == null || !hasAny) return;
try
{
hw.GetPart(out int r1, out int c1, out int r2, out int c2);
double h = r2 - r1, w = c2 - c1;
double nh = h * factor, nw = w * factor;
if (nh < 4 || nw < 4) return; // 放大上限保护
if (nh > refH * 20 || nw > refW * 20) return; // 缩小上限保护
double cr = (r1 + r2) / 2.0, cc = (c1 + c2) / 2.0;
hw.SetPart(cr - nh / 2, cc - nw / 2, cr + nh / 2, cc + nw / 2);
Redraw();
}
catch { }
}
private void MenuSave_Click(object sender, RoutedEventArgs e)
{
var img = _layerMode ? _layerBaseImage : _image;
if (img == null || !img.IsInitialized()) return;
var sfd = new Microsoft.Win32.SaveFileDialog
{
Filter = "PNG 图像|*.png|BMP 图像|*.bmp|TIFF 图像|*.tif|JPEG 图像|*.jpg",
FileName = "halcon_image"
};
if (sfd.ShowDialog() != true) return;
try
{
string ext = Path.GetExtension(sfd.FileName).ToLowerInvariant();
string fmt = ext == ".bmp" ? "bmp" : ext == ".tif" || ext == ".tiff" ? "tiff" : ext == ".jpg" || ext == ".jpeg" ? "jpeg" : "png";
string noExt = Path.Combine(Path.GetDirectoryName(sfd.FileName) ?? "", Path.GetFileNameWithoutExtension(sfd.FileName));
HOperatorSet.WriteImage(img, fmt, 0, noExt);
}
catch (Exception ex) { MessageBox.Show($"保存失败:{ex.Message}"); }
}
#endregion
#region 交互 ROI 绘制(HDrawingObject:左键拖动调整,右键确认)
private void MenuRoiRect1_Click(object sender, RoutedEventArgs e) => _ = DrawAsync(Models.HalconRoiType.Rectangle1);
private void MenuRoiRect2_Click(object sender, RoutedEventArgs e) => _ = DrawAsync(Models.HalconRoiType.Rectangle2);
private void MenuRoiCircle_Click(object sender, RoutedEventArgs e) => _ = DrawAsync(Models.HalconRoiType.Circle);
private void MenuRoiClear_Click(object sender, RoutedEventArgs e)
{
LastRoi = null;
DetachDrawing();
Redraw();
}
private async Task DrawAsync(Models.HalconRoiType type)
{
var hw = Hwn;
var baseImg = _layerMode ? _layerBaseImage : _image;
if (_drawingBusy || hw == null || baseImg == null || !baseImg.IsInitialized()) return;
_drawingBusy = true;
MyHwindow.ContextMenu = null;
try
{
DetachDrawing();
_drawing = new HDrawingObject();
double h = _layerMode ? _layerImgH : _imgH;
double w = _layerMode ? _layerImgW : _imgW;
switch (type)
{
case Models.HalconRoiType.Rectangle1:
_drawing.CreateDrawingObjectRectangle1(h * 0.25, w * 0.25, h * 0.75, w * 0.75);
break;
case Models.HalconRoiType.Rectangle2:
_drawing.CreateDrawingObjectRectangle2(h * 0.5, w * 0.5, 0, Math.Min(w, h) * 0.25, Math.Min(w, h) * 0.15);
break;
case Models.HalconRoiType.Circle:
_drawing.CreateDrawingObjectCircle(h * 0.5, w * 0.5, Math.Min(w, h) * 0.25);
break;
}
_drawing.SetDrawingObjectParams("line_width", 2.5);
_drawing.SetDrawingObjectParams("color", "green");
hw.AttachDrawingObjectToWindow(_drawing);
// 后台等待右键确认(左键用于拖动 ROI 的控制点)
await Task.Run(() =>
{
int button = 0;
while (true)
{
hw.GetMbutton(out int r, out int c, out button);
if (button == 1) { while (button == 1) hw.GetMposition(out r, out c, out button); }
else break;
}
});
LastRoi = ReadRoi(type);
}
catch { }
finally
{
DetachDrawing();
_drawingBusy = false;
MyHwindow.ContextMenu = MyMenu;
Redraw();
}
}
private Models.HalconRoi ReadRoi(Models.HalconRoiType type)
{
if (_drawing == null) return null;
var roi = new Models.HalconRoi { Type = type };
switch (type)
{
case Models.HalconRoiType.Rectangle1:
roi.Row1 = _drawing.GetDrawingObjectParams("row1").D;
roi.Col1 = _drawing.GetDrawingObjectParams("column1").D;
roi.Row2 = _drawing.GetDrawingObjectParams("row2").D;
roi.Col2 = _drawing.GetDrawingObjectParams("column2").D;
break;
case Models.HalconRoiType.Rectangle2:
roi.Row = _drawing.GetDrawingObjectParams("row").D;
roi.Col = _drawing.GetDrawingObjectParams("column").D;
roi.Phi = _drawing.GetDrawingObjectParams("phi").D;
roi.Length1 = _drawing.GetDrawingObjectParams("length1").D;
roi.Length2 = _drawing.GetDrawingObjectParams("length2").D;
break;
case Models.HalconRoiType.Circle:
roi.Row = _drawing.GetDrawingObjectParams("row").D;
roi.Col = _drawing.GetDrawingObjectParams("column").D;
roi.Radius = _drawing.GetDrawingObjectParams("radius").D;
break;
}
return roi;
}
private void DetachDrawing()
{
try
{
if (_drawing != null)
{
Hwn?.DetachDrawingObjectFromWindow(_drawing);
_drawing.Dispose();
}
}
catch { }
finally { _drawing = null; }
}
#endregion
}
}