HSmartWindowControl 滚轮缩放 交互式绘制ROI 可修改 存储
一直想达到这个效果,奈何智商简单;今天来做一下记录;
个人习惯 Winform 新建以后删除xxx.designer.cs再双击Form1.cs设计器;就会在该 文件下
自动生成InitializeComponent() 且可 由设计器生成的所有winform界面程序则会出现在InitializeComponent()里面;
这样的好处很多,所有设计器的操作都可以以单一文件程序的方式呈现在面前
想要一个这样的功能:
可以自适应图片缩放在不同图像宽高比和窗口宽高比 的 情况下 保证图像完整显示并居中
缩放的同时绘制ROI ROI可以记录 位置下次修改 可以存储ROI位置 存储 ROI抠的图
算了 虽然这个不完善: 但最近流行一句话 一个粗糙的开始就是最好的开始.
算了算了 上程序.
using HalconDotNet;
using System;
using System.Diagnostics;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.IO;
using System.CodeDom;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Media.Media3D;
namespace hsmart
{
public partial class Form1 : Form
{
private Button button1;
private Button button2;
private Label label1;
private Button button3;
private HalconDotNet.HSmartWindowControl hSmartWindowControl1;
HWindow hwindow;
private Button button4;
private Button button5;
string Getcwd = System.Environment.CurrentDirectory;
private Sunisoft.IrisSkin.SkinEngine skinEngine1;// MacOS 风格
private bool 黑魔法_Load(string S= "MacOS")// 应用
{
// skinEngine1
this.skinEngine1 = new Sunisoft.IrisSkin.SkinEngine(); // MacOS
this.skinEngine1.@__DrawButtonFocusRectangle = true;
this.skinEngine1.DisabledButtonTextColor = System.Drawing.Color.Gray;
this.skinEngine1.DisabledMenuFontColor = System.Drawing.SystemColors.GrayText;
this.skinEngine1.InactiveCaptionColor = System.Drawing.SystemColors.InactiveCaptionText;
this.skinEngine1.SerialNumber = "";
this.skinEngine1.SkinFile = null;
skinEngine1.SkinFile = System.Environment.CurrentDirectory + $@"\Skins\{S}.ssk";
return true;
}
public Form1()
{
InitializeComponent();
黑魔法_Load();
displayResult_Load();
hwindow = hSmartWindowControl1.HalconWindow;//从初始化窗口变量
}
private void InitializeComponent()
{
this.hSmartWindowControl1 = new HalconDotNet.HSmartWindowControl();
this.button1 = new System.Windows.Forms.Button();
this.button2 = new System.Windows.Forms.Button();
this.label1 = new System.Windows.Forms.Label();
this.button3 = new System.Windows.Forms.Button();
this.button4 = new System.Windows.Forms.Button();
this.button5 = new System.Windows.Forms.Button();
this.SuspendLayout();
//
// hSmartWindowControl1
//
this.hSmartWindowControl1.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink;
this.hSmartWindowControl1.AutoValidate = System.Windows.Forms.AutoValidate.EnableAllowFocusChange;
this.hSmartWindowControl1.HDoubleClickToFitContent = true;
this.hSmartWindowControl1.HDrawingObjectsModifier = HalconDotNet.HSmartWindowControl.DrawingObjectsModifier.None;
this.hSmartWindowControl1.HImagePart = new System.Drawing.Rectangle(0, 0, 640, 480);
this.hSmartWindowControl1.HKeepAspectRatio = true;
this.hSmartWindowControl1.HMoveContent = true;
this.hSmartWindowControl1.HZoomContent = HalconDotNet.HSmartWindowControl.ZoomContent.WheelForwardZoomsIn;
this.hSmartWindowControl1.Location = new System.Drawing.Point(232, 61);
this.hSmartWindowControl1.Margin = new System.Windows.Forms.Padding(0);
this.hSmartWindowControl1.Name = "hSmartWindowControl1";
this.hSmartWindowControl1.Size = new System.Drawing.Size(547, 432);
this.hSmartWindowControl1.TabIndex = 0;
this.hSmartWindowControl1.WindowSize = new System.Drawing.Size(547, 432);
//
// button1
//
this.button1.Location = new System.Drawing.Point(40, 61);
this.button1.Name = "button1";
this.button1.Size = new System.Drawing.Size(109, 59);
this.button1.TabIndex = 1;
this.button1.Text = "打开图像";
this.button1.UseVisualStyleBackColor = true;
this.button1.Click += new System.EventHandler(this.button1_Click);
//
// button2
//
this.button2.Location = new System.Drawing.Point(40, 256);
this.button2.Name = "button2";
this.button2.Size = new System.Drawing.Size(109, 59);
this.button2.TabIndex = 2;
this.button2.Text = "draw_roi";
this.button2.UseVisualStyleBackColor = true;
this.button2.Click += new System.EventHandler(this.button2_Click);
//
// label1
//
this.label1.AutoSize = true;
this.label1.Location = new System.Drawing.Point(230, 505);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(41, 12);
this.label1.TabIndex = 3;
this.label1.Text = "label1";
//
// button3
//
this.button3.Location = new System.Drawing.Point(40, 155);
this.button3.Name = "button3";
this.button3.Size = new System.Drawing.Size(109, 59);
this.button3.TabIndex = 4;
this.button3.Text = "恢复大小";
this.button3.UseVisualStyleBackColor = true;
this.button3.Click += new System.EventHandler(this.button3_Click);
//
// button4
//
this.button4.Location = new System.Drawing.Point(40, 346);
this.button4.Name = "button4";
this.button4.Size = new System.Drawing.Size(109, 59);
this.button4.TabIndex = 5;
this.button4.Text = "save_roi";
this.button4.UseVisualStyleBackColor = true;
this.button4.Click += new System.EventHandler(this.button4_Click);
//
// button5
//
this.button5.Location = new System.Drawing.Point(696, 12);
this.button5.Name = "button5";
this.button5.Size = new System.Drawing.Size(83, 40);
this.button5.TabIndex = 6;
this.button5.Text = "打开目录";
this.button5.UseVisualStyleBackColor = true;
this.button5.Click += new System.EventHandler(this.button5_Click);
//
// Form1
//
this.ClientSize = new System.Drawing.Size(798, 596);
this.Controls.Add(this.button5);
this.Controls.Add(this.button4);
this.Controls.Add(this.button3);
this.Controls.Add(this.label1);
this.Controls.Add(this.button2);
this.Controls.Add(this.button1);
this.Controls.Add(this.hSmartWindowControl1);
this.Name = "Form1";
this.ResumeLayout(false);
this.PerformLayout();
}
/// <summary>
/// // 手动添加事件
/// </summary>
private void displayResult_Load()
{
this.MouseWheel += new System.Windows.Forms.MouseEventHandler(this.my_MouseWheel);
this.hSmartWindowControl1.HMouseMove += new HalconDotNet.HMouseEventHandler(this.HSmartWindowControl1_HMouseMove);
}
/// <summary>
/// 滚轮事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void my_MouseWheel(object sender, MouseEventArgs e)
{
if (true)
{
System.Drawing.Point pt = this.Location;
int LeftBorder = hSmartWindowControl1.Location.X;
int rightBorder = hSmartWindowControl1.Location.X + hSmartWindowControl1.Size.Width;
int topBorder = hSmartWindowControl1.Location.Y;
int bottomBorder = hSmartWindowControl1.Location.Y + hSmartWindowControl1.Size.Height;
if (e.X > LeftBorder && e.X < rightBorder && e.Y > topBorder && e.Y < bottomBorder)
{
MouseEventArgs newe = new MouseEventArgs(e.Button, e.Clicks, e.X - pt.X, e.Y - pt.Y, e.Delta);
hSmartWindowControl1.HSmartWindowControl_MouseWheel(sender, newe);
}
}
else
{
//HSmartWindowControl控件的区域
Rectangle rect = hSmartWindowControl1.RectangleToScreen(hSmartWindowControl1.ClientRectangle);
if (rect.Contains(Cursor.Position))//滚动时,鼠标悬停在在HSmartWindowControl控件上
{
hSmartWindowControl1.HSmartWindowControl_MouseWheel(sender, e);//缩放
}
}
}
/// <summary>
/// 鼠标移动事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void HSmartWindowControl1_HMouseMove(object sender, HMouseEventArgs e)
{
HTuple pointGray;
int Row, Column, Button;
try{
hSmartWindowControl1.HalconWindow.GetMposition(out Row, out Column, out Button);
if (imgHeight != null && (Row > 0 && Row < imgHeight) && (Column > 0 && Column < imgWidth))//设置3个条件项,防止程序崩溃。
{
HOperatorSet.GetGrayval(image, Row, Column, out pointGray); //获取当前点的灰度值
}
else
{
pointGray = "_";
}
String str = String.Format("Row:{0} Column:{1} Gray:{2}", Row, Column, pointGray); //格式化字符串
label1.Text = str;
}catch (Exception){ /* throw;*/ }
}
HTuple imgWidth, imgHeight;
private void openpic()
{
OpenFileDialog openFileDialog = new OpenFileDialog();
//openFileDialog.Filter = "JPEG文件|*.jpg*|BMP文件|*.bmp*|TIFF文件|*.tiff*";
openFileDialog.Filter = "所有图像文件 | *.bmp; *.pcx; *.png; *.jpg; *.gif;*.tif; *.ico; *.dxf; *.cgm; *.cdr; *.wmf; *.eps; *.emf";
openFileDialog.InitialDirectory = Application.StartupPath;
if (openFileDialog.ShowDialog() == DialogResult.OK)
{
HTuple ImagePath = openFileDialog.FileName;
HOperatorSet.ReadImage(out image, ImagePath);
}
/* HOperatorSet.GetImageSize(ho_image, out ImageWidth, out ImageHeight);
HOperatorSet.SetPart(WindowID, 0, 0, ImageHeight, ImageWidth);
HOperatorSet.DispObj(ho_image, WindowID);*/
//获取图像及显示窗口长宽
HOperatorSet.GetImageSize(image, out imgWidth, out imgHeight);
int wndWidth = hSmartWindowControl1.ClientRectangle.Width;
int wndHeight = hSmartWindowControl1.ClientRectangle.Height;
//计算比例
double scale = Math.Max(1.0 * imgWidth.I / wndWidth, 1.0 * imgHeight / wndHeight);
double w = wndWidth * scale;
double h = wndHeight * scale;
//居中时,Part的区域
hSmartWindowControl1.HalconWindow.SetPart(-(h - imgHeight) / 2, -(w - imgWidth) / 2, imgHeight + (h - imgHeight.D) / 2, imgWidth + (w - imgWidth) / 2);
//背景色
hSmartWindowControl1.HalconWindow.SetWindowParam("background_color", "black");
hSmartWindowControl1.HalconWindow.ClearWindow();
hSmartWindowControl1.HalconWindow.DispObj(image);
}
HObject image;
private void button1_Click(object sender, EventArgs e)
{
openpic();
}
private void button3_Click(object sender, EventArgs e)
{
//恢复大小
// hSmartWindowControl1.HalconWindow.SetPart(0, 0,-1, -1);
//获取图像及显示窗口长宽
HOperatorSet.GetImageSize(image, out imgWidth, out imgHeight);
int wndWidth = hSmartWindowControl1.ClientRectangle.Width;
int wndHeight = hSmartWindowControl1.ClientRectangle.Height;
//在不同图像宽高比和窗口宽高比 的 情况下 保证图像完整显示并居中
// 保持纵横比 全屏显示并剧中; 这对于图像尺寸和显示控件比例不等的时候很有用;
// 他能在 控件和图像任意尺寸 任意比例 的情况下 保持纵横比 ;
//计算比例
double scale = Math.Max(1.0 * imgWidth.I / wndWidth, 1.0 * imgHeight / wndHeight);
double w = wndWidth * scale;
double h = wndHeight * scale;
//居中时,Part的区域
hSmartWindowControl1.HalconWindow.SetPart(-(h - imgHeight) / 2, -(w - imgWidth) / 2, imgHeight + (h - imgHeight.D) / 2, imgWidth + (w - imgWidth) / 2);
//背景色
hSmartWindowControl1.HalconWindow.SetWindowParam("background_color", "black");
hSmartWindowControl1.HalconWindow.ClearWindow();
hSmartWindowControl1.HalconWindow.DispObj(image);
}
HDrawingObject doRoi = null; // 1.定义用于在HSmartWindowControl控件上显示Region的HDrawingObject实例
/// <summary>
/// 2.建立和删除HDrawingObject
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void button2_Click(object sender, EventArgs e)
{
HTuple val = null;
//路径
bool YN_save;
if (File.Exists($@"{Getcwd}/_ROI.tup"))
{
YN_save = true; /*存在*/
}
else
{
YN_save = false;/*不存在*/
}
try
{
HOperatorSet.ReadTuple("_ROI.tup", out val); // 目的是把ROI 参数存到_ROI.tup
}
catch (Exception)
{
// 删除 _ROI.tup
}
//我想判断一下合法
if (val[0] != null || val[1] != null || val[2] != null || val[3] != null)
{
}
if (doRoi == null)
{
//创建一个矩形的显示实例
doRoi = HDrawingObject.CreateDrawingObject(HDrawingObject.HDrawingObjectType.RECTANGLE1, val[0], val[1], val[2],val[3]);
doRoi.SetDrawingObjectParams("color", "green");
//挂靠实例到HSmartWindowControl控件
hSmartWindowControl1.HalconWindow.AttachDrawingObjectToWindow(doRoi);
}
else
{
hSmartWindowControl1.HalconWindow.DetachDrawingObjectFromWindow(doRoi);//这里这句可以不要
doRoi = null;
}
}
private void button5_Click(object sender, EventArgs e)
{
// 启动应用程序并等待它关闭
Process.Start("Explorer.exe", Getcwd);
// 执行其他任务...
// 当需要时,可以调用 WaitForExit() 来等待进程结束
}
// 3. 3,HDrawingObject转Region
private void button4_Click(object sender, EventArgs e)
{
if (doRoi != null)
{
//获取矩形参数
string[] str = { "row1", "column1", "row2", "column2" };
HTuple val = doRoi.GetDrawingObjectParams(str);
//生成ROI
HOperatorSet.GenRectangle1(out HObject roi, val[0], val[1], val[2], val[3]);
HRegion rectangle1 = new HRegion(roi);
HObject reducedImg;
HOperatorSet.ReduceDomain(image , rectangle1,out reducedImg);
HOperatorSet.WriteImage(reducedImg,"png", 0, Getcwd+"\\ROI.png");
HOperatorSet.WriteTuple(val, Getcwd + "\\_ROI.tup");
// png 是 8位4通道 32位图
// doRoi.ClearDrawingObject();
// ...
RWINI.RWini测试();
}
}
//C:\Program Files\MVTec\HALCON-23.05-Progress\bin\dotnet35
/// <summary>
/// INI文件操作辅助类
/// </summary>
public class RWINI
{
[DllImport("kernel32")]
private static extern long WritePrivateProfileString(string section, string key, string val, string filePath);
[DllImport("kernel32")]
private static extern int GetPrivateProfileString(string section, string key, string def, StringBuilder retVal, int size, string filePath);
string path = AppDomain.CurrentDomain.BaseDirectory + "CFG.ini";
public static string Getcwd = System.Environment.CurrentDirectory;
/// <summary>
/// 写INI文件
/// </summary>
/// <param name="path">path</param>
/// <param name="Section">分组节点</param>
/// <param name="Key">关键字</param>
/// <param name="Value">值</param>
static public void Wini(string path, string Section, string Key, string Value)
{
WritePrivateProfileString(Section, Key, Value, path);
}
/// <summary>
/// 读取INI文件
/// </summary>
/// <param name="path">path</param>
/// <param name="Section">分组节点</param>
/// <param name="Key">关键字</param>
/// <param name="def">缺省值</param>
/// <returns></returns>
static public string Rini(string path, string Section, string Key, string def="")
{
StringBuilder temp = new StringBuilder(255);
int i = GetPrivateProfileString(Section, Key, def, temp, 255, path);
return temp.ToString();
}
/// <summary>
/// 删除ini文件下所有段落
/// </summary>
public void ClearAllSection(string path)
{
Wini(path, null, null, null);
}
/// <summary>
/// 删除ini文件下指定段落下的所有键
/// </summary>
/// <param name="Section"></param>
public void ClearSection(string path, string Section)
{
Wini(path, Section, null, null);
}
static public string RWini测试()
{
Wini(Getcwd + "\\CFG.ini", "Section", "Key", "Value");
string x = Rini(Getcwd + "\\CFG.ini", "Section", "Key", "def");
MessageBox.Show(x.ToString());
return "";
}
/********
*
_minThreshold = Convert.ToInt32( );
********/
}
}
}