winform pictureBox绘制矩形框
版本1:绘制矩形框在pictureBox
using Newtonsoft.Json.Linq;
using ReaLTaiizor.Forms;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using static 抽图软件.FrmMain;
namespace 抽图软件
{
public partial class FrmExtractImages : MaterialForm
{
// 图像移动,放大缩小参数
Point mouseDownPoint = new Point(); // 记录拖拽过程鼠标位置
bool isMove = false; // 判断鼠标在picturebox上移动时,是否处于拖拽过程(鼠标左键是否按下)
int zoomStep = 120; // 缩放步长 比例
double zoomStepUR = 1.2; // 放大步长 比例
double zoomStepDR = 0.8; // 缩小步长 比例
// 图像绘制参数
Point start, end;//绘制矩形框的起点和终点
bool blnDraw;//在MouseMove事件中判断是否绘制矩形框
List<PictureBox> pictureBoxes = null;
public class StartAndEndPoint
{
public Point Start;
public Point End;
}
//绘制矩形起始点和终止点的集合
//List<StartAndEndPoint> multiAreaPoint_pictureBox1 = new List<StartAndEndPoint>();
//List<StartAndEndPoint> multiAreaPoint_pictureBox2 = new List<StartAndEndPoint>();
//List<StartAndEndPoint> multiAreaPoint_pictureBox3 = new List<StartAndEndPoint>();
//List<StartAndEndPoint> multiAreaPoint_pictureBox4 = new List<StartAndEndPoint>();
//List<StartAndEndPoint> multiAreaPoint_pictureBox5 = new List<StartAndEndPoint>();
Dictionary<string, List<StartAndEndPoint>> pictureBox_multiDrawAreaPoint_Dict = new Dictionary<string, List<StartAndEndPoint>>();
public FrmExtractImages()
{
InitializeComponent();
this.pictureBoxes = FindControls<PictureBox>(this);
// 遍历所有pictureBox控件
foreach (PictureBox pictureBox in this.pictureBoxes)
{
pictureBox.MouseWheel += new System.Windows.Forms.MouseEventHandler(this.pictureBox_MouseWheel);
pictureBox.Paint += new System.Windows.Forms.PaintEventHandler(this.pictureBox_Paint);
pictureBox.DoubleClick += new System.EventHandler(this.pictureBox_DoubleClick);
pictureBox.MouseDown += new System.Windows.Forms.MouseEventHandler(this.pictureBox_MouseDown);
pictureBox.MouseMove += new System.Windows.Forms.MouseEventHandler(this.pictureBox_MouseMove);
pictureBox.MouseUp += new System.Windows.Forms.MouseEventHandler(this.pictureBox_MouseUp);
pictureBox_multiDrawAreaPoint_Dict[pictureBox.Name] = new List<StartAndEndPoint>();
pictureBox.Image = Image.FromFile(@"C:\Users\29939\Desktop\test\hix2.png");
}
}
private void pictureBox_DoubleClick(object sender, EventArgs e)
{
// 获取组件
PictureBox pictureBox = sender as PictureBox;
// 清空绘制点位
pictureBox_multiDrawAreaPoint_Dict[pictureBox.Name].Clear();
// 清空内容
pictureBox.Refresh();
}
/// <summary>
/// pictureBox 鼠标按下
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void pictureBox_MouseDown(object sender, MouseEventArgs e)
{
PictureBox pictureBox = sender as PictureBox;
// 右键移动图像
if (e.Button == MouseButtons.Right)
{
//
mouseDownPoint.X = Cursor.Position.X;
mouseDownPoint.Y = Cursor.Position.Y;
isMove = true;
pictureBox.Focus();
}
// 左键绘制矩形框
if (e.Button == MouseButtons.Left)
{
// 矩形框起点
start = e.Location;
// 启动绘制
blnDraw = true;
}
}
/// <summary>
/// 鼠标移动,绘制矩形
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void pictureBox_MouseMove(object sender, MouseEventArgs e)
{
PictureBox pictureBox = sender as PictureBox;
if (blnDraw)
{
if (e.Button != MouseButtons.Left)//判断是否按下左键
return;
end = e.Location;
pictureBox.Invalidate();
}
pictureBox.Focus();
if (isMove)
{
int x, y;
int moveX, moveY;
// 计算移动距离XY
moveX = Cursor.Position.X - mouseDownPoint.X;
moveY = Cursor.Position.Y - mouseDownPoint.Y;
// 计算pictureBox新的位置点
x = pictureBox.Location.X + moveX;
y = pictureBox.Location.Y + moveY;
// 改变图像位置
pictureBox.Location = new Point(x, y);
// 赋值新的鼠标下落点
mouseDownPoint.X = Cursor.Position.X;
mouseDownPoint.Y = Cursor.Position.Y;
}
}
/// <summary>
/// 鼠标抬起
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void pictureBox_MouseUp(object sender, MouseEventArgs e)
{
PictureBox pictureBox = sender as PictureBox;
// 右键抬起,停止移动
if (e.Button == MouseButtons.Right)
{
isMove = false;
}
// 左键抬起,停止绘画,同时添加绘制矩形框到全局变量
if (e.Button == MouseButtons.Left)
{
// 左键抬起,确定终点
end = e.Location;
// 停止绘画
blnDraw = false;
// 如果图像不为空,则添加矩形框坐标点
if (pictureBox.Image != null)
{
// 起点不等于终点
if (start != end)
{
// 赋值矩形框坐标点
StartAndEndPoint rectpoint = new StartAndEndPoint();
rectpoint.Start = start;
rectpoint.End = end;
if ((!pictureBox_multiDrawAreaPoint_Dict[pictureBox.Name].Contains(rectpoint)))
{
// 添加不同区域起始和终止点的结构体数组
pictureBox_multiDrawAreaPoint_Dict[pictureBox.Name].Add(rectpoint);
// 将坐标点直接绘制到图像上
// 坐标转到0-1之间
double x1 = Math.Round((double)rectpoint.Start.X / (double)pictureBox.Width, 10);
double y1 = Math.Round((double)rectpoint.Start.Y / (double)pictureBox.Height, 10); ;
double x2 = Math.Round((double)rectpoint.End.X / (double)pictureBox.Width, 10); ;
double y2 = Math.Round((double)rectpoint.End.Y / (double)pictureBox.Height, 10); ;
Bitmap rawImg = new Bitmap(pictureBox.Image);
int x1Int = (int)(x1 * (double)rawImg.Width);
int y1Int = (int)(y1 * (double)rawImg.Height);
int x2Int = (int)(x2 * (double)rawImg.Width);
int y2Int = (int)(y2 * (double)rawImg.Height);
OpenCvSharp.Mat img1 = OpenCvSharp.Extensions.BitmapConverter.ToMat(rawImg); //Bitmap转Mat
OpenCvSharp.Point truck_a = new OpenCvSharp.Point(x1Int, y1Int);
OpenCvSharp.Point truck_b = new OpenCvSharp.Point(x2Int, y2Int);
OpenCvSharp.Cv2.Rectangle(img1, truck_a, truck_b, OpenCvSharp.Scalar.Red, 2);
// 把Mat格式的图片转换成Bitmap
Bitmap bitmap = OpenCvSharp.Extensions.BitmapConverter.ToBitmap(img1);
// 显示图片
pictureBox.Image = bitmap;
// 弹出缺陷选择框
//FrmSelectDefectCategory frmSelectDefectCategory = new FrmSelectDefectCategory();
//frmSelectDefectCategory.ShowDialog();
//string defectName = GlobalParams.CurrentDefectName;
//rectDefectNameList1.Add(defectName);
//rectDefectNameDict1[rectpoint] = defectName;
//MessageBox.Show("缺陷名称");
}
}
}
}
}
/// <summary>
/// pictureBox绘制
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void pictureBox_Paint(object sender, PaintEventArgs e)
{
PictureBox pictureBox = sender as PictureBox;
Pen pen = new Pen(Color.Red, 3);
pen.DashStyle = System.Drawing.Drawing2D.DashStyle.Dot;//绘制线的格式
// 是否绘制标志位,是,则进行绘制
if (blnDraw)
{
if (pictureBox.Image != null)
{
//此处是为了在绘制时可以由上向下绘制,也可以由下向上绘
e.Graphics.DrawRectangle(pen, Math.Min(start.X, end.X), Math.Min(start.Y, end.Y), Math.Abs(start.X - end.X), Math.Abs(start.Y - end.Y));
}
}
//将之前绘制的矩形框再次绘制
//foreach (StartAndEndPoint points in pictureBox_multiDrawAreaPoint_Dict[pictureBox.Name])
//{
// Point p1 = points.Start;
// Point p2 = points.End;
// //int x = 100;
// //int y = 100;
// //int h = 10;
// //int w = 10;
// // 左上点,w, h
// e.Graphics.DrawRectangle(pen, Math.Min(p1.X, p2.X), Math.Min(p1.Y, p2.Y), Math.Abs(p1.X - p2.X), Math.Abs(p1.Y - p2.Y));
//}
pen.Dispose();
}
/// <summary>
/// pictureBox 滚轮放大缩小图像
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void pictureBox_MouseWheel(object sender, MouseEventArgs e)
{
// 获取当前对象
System.Windows.Forms.PictureBox pictureBox = sender as System.Windows.Forms.PictureBox;
// 获取当前 xy wh
int x = e.Location.X;
int y = e.Location.Y;
int ow = pictureBox.Width;
int oh = pictureBox.Height;
int VX, VY;
// 放大
if (e.Delta > 0)
{
// 更新矩形框的坐标点
// 放大图像时,重新绘制矩形框
for (int i = 0; i < pictureBox_multiDrawAreaPoint_Dict[pictureBox.Name].Count; i++)
{
// 将起点的xy坐标进行变换
pictureBox_multiDrawAreaPoint_Dict[pictureBox.Name][i].Start.X = (int)((float)pictureBox_multiDrawAreaPoint_Dict[pictureBox.Name][i].Start.X * zoomStepUR);
// Console.WriteLine(pictureBox_multiDrawAreaPoint_Dict[pictureBox.Name][i].Start.X);
pictureBox_multiDrawAreaPoint_Dict[pictureBox.Name][i].Start.Y = (int)((float)pictureBox_multiDrawAreaPoint_Dict[pictureBox.Name][i].Start.Y * zoomStepUR);
// 将终点的xy坐标进行变换
pictureBox_multiDrawAreaPoint_Dict[pictureBox.Name][i].End.X = (int)((float)pictureBox_multiDrawAreaPoint_Dict[pictureBox.Name][i].End.X * zoomStepUR);
pictureBox_multiDrawAreaPoint_Dict[pictureBox.Name][i].End.Y = (int)((float)pictureBox_multiDrawAreaPoint_Dict[pictureBox.Name][i].End.Y * zoomStepUR);
}
// pictureBox图像的宽高进行等比例变换
pictureBox.Width = (int)((double)pictureBox.Width * zoomStepUR);
pictureBox.Height = (int)((double)pictureBox.Height * zoomStepUR);
//PropertyInfo pInfo = pictureBox.GetType().GetProperty("ImageRectangle", BindingFlags.Instance |
// BindingFlags.NonPublic);
//Rectangle rect = (Rectangle)pInfo.GetValue(pictureBox, null);
// 获取当前pictureBox的宽高
//pictureBox.Width = rect.Width;
//pictureBox.Height = rect.Height;
}
// 缩小
if (e.Delta < 0)
{
// 不能缩放小于原图10分之一
if (pictureBox.Width < pictureBox.Image.Width / 10)
return;
// 更新矩形框的坐标点
// 先算比例,再将绘制矩形框坐标乘以比例
for (int i = 0; i < pictureBox_multiDrawAreaPoint_Dict[pictureBox.Name].Count; i++)
{
// item.Start
// 计算一个比例值,来进行缩放矩形框坐标点
double dx1 = (float)pictureBox_multiDrawAreaPoint_Dict[pictureBox.Name][i].Start.X / (float)pictureBox.Width;
double dy1 = (float)pictureBox_multiDrawAreaPoint_Dict[pictureBox.Name][i].Start.Y / (float)pictureBox.Height;
double dx2 = (float)pictureBox_multiDrawAreaPoint_Dict[pictureBox.Name][i].End.X / (float)pictureBox.Width;
double dy2 = (float)pictureBox_multiDrawAreaPoint_Dict[pictureBox.Name][i].End.Y / (float)pictureBox.Height;
pictureBox_multiDrawAreaPoint_Dict[pictureBox.Name][i].Start.X = (int)(dx1 * zoomStepDR * (float)pictureBox.Width);
pictureBox_multiDrawAreaPoint_Dict[pictureBox.Name][i].Start.Y = (int)(dy1 * zoomStepDR * (float)pictureBox.Height);
pictureBox_multiDrawAreaPoint_Dict[pictureBox.Name][i].End.X = (int)(dx2 * zoomStepDR * (float)pictureBox.Width);
pictureBox_multiDrawAreaPoint_Dict[pictureBox.Name][i].End.Y = (int)(dy2 * zoomStepDR * (float)pictureBox.Height);
//pictureBox_multiDrawAreaPoint_Dict[pictureBox.Name][i].Start.X = (int)((float)pictureBox_multiDrawAreaPoint_Dict[pictureBox.Name][i].Start.X * zoomStepDR);
//pictureBox_multiDrawAreaPoint_Dict[pictureBox.Name][i].Start.Y = (int)((float)pictureBox_multiDrawAreaPoint_Dict[pictureBox.Name][i].Start.Y * zoomStepDR);
//pictureBox_multiDrawAreaPoint_Dict[pictureBox.Name][i].End.X = (int)((float)pictureBox_multiDrawAreaPoint_Dict[pictureBox.Name][i].End.X * zoomStepDR);
//pictureBox_multiDrawAreaPoint_Dict[pictureBox.Name][i].End.Y = (int)((float)pictureBox_multiDrawAreaPoint_Dict[pictureBox.Name][i].End.Y * zoomStepDR);
}
// pictureBox图像的宽高进行等比例变换
pictureBox.Width = (int)((double)pictureBox.Width * zoomStepDR);
pictureBox.Height = (int)((double)pictureBox.Height * zoomStepDR);
获取高宽,用于确定pictureBox显示位置
//PropertyInfo pInfo = pictureBox.GetType().GetProperty("ImageRectangle", BindingFlags.Instance |
// BindingFlags.NonPublic);
//Rectangle rect = (Rectangle)pInfo.GetValue(pictureBox, null);
//pictureBox.Width = rect.Width;
//pictureBox.Height = rect.Height;
}
// 确定显示位置偏移量
// ow 放缩前的pictureBox宽度
// oh 放缩前的pictureBox高度
VX = (int)((double)x * (ow - pictureBox.Width) / ow);
VY = (int)((double)y * (oh - pictureBox.Height) / oh);
// 确定pictureBox的显示位置
pictureBox.Location = new Point(pictureBox.Location.X + VX, pictureBox.Location.Y + VY);
}
private void FrmExtractImages_Load(object sender, EventArgs e)
{
// 读取json参数
JObject para = JSONHelper.ReadJSON("./param.json");
materialTextBoxEdit1.Text = (string)para["s1_path"];
materialTextBoxEdit2.Text = (string)para["s2_path"];
materialTextBoxEdit3.Text = (string)para["s3_path"];
/*
对panel1和panel2中的所有按钮 右击绑定 job、点位、序列号
*/
// 遍历panel1中所有button控件
foreach (Control ctrl in panel1.Controls)
{
// 按钮控件
if (ctrl is System.Windows.Forms.Button)
{
// 绑定右击事件,弹出窗口,填入 job、点位、序列号
ctrl.MouseDown += new System.Windows.Forms.MouseEventHandler(this.showBtnClick);
}
}
}
void showBtnClick(object sender, MouseEventArgs e)
{
// 右击事件
if (e.Button == MouseButtons.Right)
{
//获取当前点击的Button
System.Windows.Forms.Button thisClickedButton = sender as System.Windows.Forms.Button;
//MessageBox.Show(thisClickedButton.Name);
FrmShowSelectedTool form1 = new FrmShowSelectedTool();
form1.ShowDialog();
}
// 左击事件
if (e.Button == MouseButtons.Left)
{
// 转换类型为button
System.Windows.Forms.Button thisClickedButton = sender as System.Windows.Forms.Button;
// 1.查找是否有该按钮键值,有则显示图像,没有就提醒
JObject res = JSONHelper.ReadJSON("DianWei.json");
if (res.ContainsKey(thisClickedButton.Name))
{
1.获取job、点位、序列号
//JToken item = res[thisClickedButton.Name];
//string job = (string)item["job"];
//string rawDianWei = (string)item["rawDianWei"];
//string resDianWei = (string)item["resDianWei"];
可以用;和,切割多个job,切割多个点位,;可以达到不同job对应不同多个点位
//string[] jobList = job.Split(',');
//string[] rawDianWeiList = rawDianWei.Split(',');
//string[] resDianWeiList = resDianWei.Split(',');
// 2.根据job、点位、序列号、原图还是结果图获取图像路径
// 3.利用图像路径进行原图和结果图的显示
//for (int i = 0; i < ImageShowList.Count; i++)
//{
// //MessageBox.Show(pictureBoxes[i].Name);
// //pictureBoxes[i].Image = Image.FromFile(ImageShowList[i]);
// // 限制:显示图像数量不能超过picturebox数量
// // 显示图像
// // 显示图像路径
// // 清空绘制矩形
//}
}
// 未设置点位
else
{
ReaLTaiizor.Controls.MaterialDialog materialDialog = new ReaLTaiizor.Controls.MaterialDialog(this, "提醒", "未设置点位", "确认", true, "取消");
DialogResult result = materialDialog.ShowDialog(this);
}
}
}
private void tabPage2_Click(object sender, EventArgs e)
{
}
/// <summary>
/// 保存参数
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void materialButton1_Click(object sender, EventArgs e)
{
string s1 = materialTextBoxEdit1.Text.Trim();
string s2 = materialTextBoxEdit2.Text.Trim();
string s3 = materialTextBoxEdit3.Text.Trim();
JSONHelper.AppendStringJSON("s1_path", s1, "param.json");
JSONHelper.AppendStringJSON("s2_path", s2, "param.json");
JSONHelper.AppendStringJSON("s3_path", s3, "param.json");
MessageBox.Show("保存参数成功!");
}
/// <summary>
/// 遍历所有控件树递,归所有子控件,查找所有包含指定控件类型的控件,并返回所有包含指定控件类型的控件的列表。调用该方法,获取所有按钮控件:var buttons = FindControls<Button>(this);
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="control"></param>
/// <returns></returns>
public static List<T> FindControls<T>(Control control) where T : Control
{
List<T> controls = new List<T>();
// 遍历控件集合
foreach (Control ctrl in control.Controls)
{
// 判断控件类型是否为指定类型
if (ctrl is T tControl)
{
// 添加符合条件的控件
controls.Add(tControl);
}
// 如果控件还有子控件,则递归调用此方法
if (ctrl.HasChildren)
{
controls.AddRange(FindControls<T>(ctrl));
}
}
// 返回符合条件的控件列表
return controls;
}
}
}
版本2:直接使用opencv绘制在图像上
using Newtonsoft.Json.Linq;
using ReaLTaiizor.Forms;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using static 抽图软件.FrmMain;
namespace 抽图软件
{
public partial class FrmExtractImages : MaterialForm
{
// 图像移动,放大缩小参数
Point mouseDownPoint = new Point(); // 记录拖拽过程鼠标位置
bool isMove = false; // 判断鼠标在picturebox上移动时,是否处于拖拽过程(鼠标左键是否按下)
int zoomStep = 120; // 缩放步长 比例
double zoomStepUR = 1.2; // 放大步长 比例
double zoomStepDR = 0.8; // 缩小步长 比例
// 图像绘制参数
Point start, end;//绘制矩形框的起点和终点
bool blnDraw;//在MouseMove事件中判断是否绘制矩形框
List<PictureBox> pictureBoxes = null;
public class StartAndEndPoint
{
public Point Start;
public Point End;
}
//绘制矩形起始点和终止点的集合
//List<StartAndEndPoint> multiAreaPoint_pictureBox1 = new List<StartAndEndPoint>();
//List<StartAndEndPoint> multiAreaPoint_pictureBox2 = new List<StartAndEndPoint>();
//List<StartAndEndPoint> multiAreaPoint_pictureBox3 = new List<StartAndEndPoint>();
//List<StartAndEndPoint> multiAreaPoint_pictureBox4 = new List<StartAndEndPoint>();
//List<StartAndEndPoint> multiAreaPoint_pictureBox5 = new List<StartAndEndPoint>();
Dictionary<string, List<StartAndEndPoint>> pictureBox_multiDrawAreaPoint_Dict = new Dictionary<string, List<StartAndEndPoint>>();
public FrmExtractImages()
{
InitializeComponent();
this.pictureBoxes = FindControls<PictureBox>(this);
// 遍历所有pictureBox控件
foreach (PictureBox pictureBox in this.pictureBoxes)
{
pictureBox.MouseWheel += new System.Windows.Forms.MouseEventHandler(this.pictureBox_MouseWheel);
pictureBox.Paint += new System.Windows.Forms.PaintEventHandler(this.pictureBox_Paint);
pictureBox.DoubleClick += new System.EventHandler(this.pictureBox_DoubleClick);
pictureBox.MouseDown += new System.Windows.Forms.MouseEventHandler(this.pictureBox_MouseDown);
pictureBox.MouseMove += new System.Windows.Forms.MouseEventHandler(this.pictureBox_MouseMove);
pictureBox.MouseUp += new System.Windows.Forms.MouseEventHandler(this.pictureBox_MouseUp);
pictureBox_multiDrawAreaPoint_Dict[pictureBox.Name] = new List<StartAndEndPoint>();
pictureBox.Image = Image.FromFile(@"C:\Users\29939\Desktop\test\hix2.png");
}
}
private void pictureBox_DoubleClick(object sender, EventArgs e)
{
// 获取组件
PictureBox pictureBox = sender as PictureBox;
// 清空绘制点位
pictureBox_multiDrawAreaPoint_Dict[pictureBox.Name].Clear();
pictureBox.Image = Image.FromFile(@"C:\Users\29939\Desktop\test\hix2.png");
// 清空内容
pictureBox.Refresh();
}
/// <summary>
/// pictureBox 鼠标按下
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void pictureBox_MouseDown(object sender, MouseEventArgs e)
{
PictureBox pictureBox = sender as PictureBox;
// 右键移动图像
if (e.Button == MouseButtons.Right)
{
//
mouseDownPoint.X = Cursor.Position.X;
mouseDownPoint.Y = Cursor.Position.Y;
isMove = true;
pictureBox.Focus();
}
// 左键绘制矩形框
if (e.Button == MouseButtons.Left)
{
// 矩形框起点
start = e.Location;
// 启动绘制
blnDraw = true;
}
}
/// <summary>
/// 鼠标移动,绘制矩形
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void pictureBox_MouseMove(object sender, MouseEventArgs e)
{
PictureBox pictureBox = sender as PictureBox;
if (blnDraw)
{
if (e.Button != MouseButtons.Left)//判断是否按下左键
return;
end = e.Location;
pictureBox.Invalidate();
}
pictureBox.Focus();
if (isMove)
{
int x, y;
int moveX, moveY;
// 计算移动距离XY
moveX = Cursor.Position.X - mouseDownPoint.X;
moveY = Cursor.Position.Y - mouseDownPoint.Y;
// 计算pictureBox新的位置点
x = pictureBox.Location.X + moveX;
y = pictureBox.Location.Y + moveY;
// 改变图像位置
pictureBox.Location = new Point(x, y);
// 赋值新的鼠标下落点
mouseDownPoint.X = Cursor.Position.X;
mouseDownPoint.Y = Cursor.Position.Y;
}
}
/// <summary>
/// 鼠标抬起
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void pictureBox_MouseUp(object sender, MouseEventArgs e)
{
PictureBox pictureBox = sender as PictureBox;
// 右键抬起,停止移动
if (e.Button == MouseButtons.Right)
{
isMove = false;
}
// 左键抬起,停止绘画,同时添加绘制矩形框到全局变量
if (e.Button == MouseButtons.Left)
{
// 左键抬起,确定终点
end = e.Location;
// 停止绘画
blnDraw = false;
// 如果图像不为空,则添加矩形框坐标点
if (pictureBox.Image != null)
{
// 起点不等于终点
if (start != end)
{
// 赋值矩形框坐标点
StartAndEndPoint rectpoint = new StartAndEndPoint();
rectpoint.Start = start;
rectpoint.End = end;
if ((!pictureBox_multiDrawAreaPoint_Dict[pictureBox.Name].Contains(rectpoint)))
{
// 添加不同区域起始和终止点的结构体数组
pictureBox_multiDrawAreaPoint_Dict[pictureBox.Name].Add(rectpoint);
// 将坐标点直接绘制到图像上
// 坐标转到0-1之间
double x1 = Math.Round((double)rectpoint.Start.X / (double)pictureBox.Width, 10);
double y1 = Math.Round((double)rectpoint.Start.Y / (double)pictureBox.Height, 10); ;
double x2 = Math.Round((double)rectpoint.End.X / (double)pictureBox.Width, 10); ;
double y2 = Math.Round((double)rectpoint.End.Y / (double)pictureBox.Height, 10); ;
Bitmap rawImg = new Bitmap(pictureBox.Image);
int x1Int = (int)(x1 * (double)rawImg.Width);
int y1Int = (int)(y1 * (double)rawImg.Height);
int x2Int = (int)(x2 * (double)rawImg.Width);
int y2Int = (int)(y2 * (double)rawImg.Height);
OpenCvSharp.Mat img1 = OpenCvSharp.Extensions.BitmapConverter.ToMat(rawImg); //Bitmap转Mat
OpenCvSharp.Point truck_a = new OpenCvSharp.Point(x1Int, y1Int);
OpenCvSharp.Point truck_b = new OpenCvSharp.Point(x2Int, y2Int);
OpenCvSharp.Cv2.Rectangle(img1, truck_a, truck_b, OpenCvSharp.Scalar.Red, 2);
// 把Mat格式的图片转换成Bitmap
Bitmap bitmap = OpenCvSharp.Extensions.BitmapConverter.ToBitmap(img1);
// 显示图片
pictureBox.Image = bitmap;
// 弹出缺陷选择框
//FrmSelectDefectCategory frmSelectDefectCategory = new FrmSelectDefectCategory();
//frmSelectDefectCategory.ShowDialog();
//string defectName = GlobalParams.CurrentDefectName;
//rectDefectNameList1.Add(defectName);
//rectDefectNameDict1[rectpoint] = defectName;
//MessageBox.Show("缺陷名称");
// 保存数据到本地
JObject data = new JObject();
data["x1"] = x1Int;
data["y1"] = y1Int;
data["x2"] = x2Int;
data["y2"] = y2Int;
string ProStartTime = DateTime.Now.ToString("yyyy:MM:dd:HH:mm:ss:fff");
JSONHelper.AppendJSON(ProStartTime, data, "test123.json");
}
}
}
}
}
/// <summary>
/// pictureBox绘制
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void pictureBox_Paint(object sender, PaintEventArgs e)
{
PictureBox pictureBox = sender as PictureBox;
Pen pen = new Pen(Color.Red, 3);
pen.DashStyle = System.Drawing.Drawing2D.DashStyle.Dot;//绘制线的格式
// 是否绘制标志位,是,则进行绘制
if (blnDraw)
{
if (pictureBox.Image != null)
{
//此处是为了在绘制时可以由上向下绘制,也可以由下向上绘
e.Graphics.DrawRectangle(pen, Math.Min(start.X, end.X), Math.Min(start.Y, end.Y), Math.Abs(start.X - end.X), Math.Abs(start.Y - end.Y));
}
}
pen.Dispose();
}
/// <summary>
/// pictureBox 滚轮放大缩小图像
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void pictureBox_MouseWheel(object sender, MouseEventArgs e)
{
// 获取当前对象
System.Windows.Forms.PictureBox pictureBox = sender as System.Windows.Forms.PictureBox;
// 获取当前 xy wh
int x = e.Location.X;
int y = e.Location.Y;
int ow = pictureBox.Width;
int oh = pictureBox.Height;
int VX, VY;
// 放大
if (e.Delta > 0)
{
// pictureBox图像的宽高进行等比例变换
pictureBox.Width = (int)((double)pictureBox.Width * zoomStepUR);
pictureBox.Height = (int)((double)pictureBox.Height * zoomStepUR);
}
// 缩小
if (e.Delta < 0)
{
// 不能缩放小于原图10分之一
if (pictureBox.Width < pictureBox.Image.Width / 10)
return;
// pictureBox图像的宽高进行等比例变换
pictureBox.Width = (int)((double)pictureBox.Width * zoomStepDR);
pictureBox.Height = (int)((double)pictureBox.Height * zoomStepDR);
}
// 确定显示位置偏移量
// ow 放缩前的pictureBox宽度
// oh 放缩前的pictureBox高度
VX = (int)((double)x * (ow - pictureBox.Width) / ow);
VY = (int)((double)y * (oh - pictureBox.Height) / oh);
// 确定pictureBox的显示位置
pictureBox.Location = new Point(pictureBox.Location.X + VX, pictureBox.Location.Y + VY);
}
private void FrmExtractImages_Load(object sender, EventArgs e)
{
// 读取json参数
JObject para = JSONHelper.ReadJSON("./param.json");
materialTextBoxEdit1.Text = (string)para["s1_path"];
materialTextBoxEdit2.Text = (string)para["s2_path"];
materialTextBoxEdit3.Text = (string)para["s3_path"];
/*
对panel1和panel2中的所有按钮 右击绑定 job、点位、序列号
*/
// 遍历panel1中所有button控件
foreach (Control ctrl in panel1.Controls)
{
// 按钮控件
if (ctrl is System.Windows.Forms.Button)
{
// 绑定右击事件,弹出窗口,填入 job、点位、序列号
ctrl.MouseDown += new System.Windows.Forms.MouseEventHandler(this.showBtnClick);
}
}
}
void showBtnClick(object sender, MouseEventArgs e)
{
// 右击事件
if (e.Button == MouseButtons.Right)
{
//获取当前点击的Button
System.Windows.Forms.Button thisClickedButton = sender as System.Windows.Forms.Button;
//MessageBox.Show(thisClickedButton.Name);
FrmShowSelectedTool form1 = new FrmShowSelectedTool();
form1.ShowDialog();
}
// 左击事件
if (e.Button == MouseButtons.Left)
{
// 转换类型为button
System.Windows.Forms.Button thisClickedButton = sender as System.Windows.Forms.Button;
// 1.查找是否有该按钮键值,有则显示图像,没有就提醒
JObject res = JSONHelper.ReadJSON("DianWei.json");
if (res.ContainsKey(thisClickedButton.Name))
{
1.获取job、点位、序列号
//JToken item = res[thisClickedButton.Name];
//string job = (string)item["job"];
//string rawDianWei = (string)item["rawDianWei"];
//string resDianWei = (string)item["resDianWei"];
可以用;和,切割多个job,切割多个点位,;可以达到不同job对应不同多个点位
//string[] jobList = job.Split(',');
//string[] rawDianWeiList = rawDianWei.Split(',');
//string[] resDianWeiList = resDianWei.Split(',');
// 2.根据job、点位、序列号、原图还是结果图获取图像路径
// 3.利用图像路径进行原图和结果图的显示
//for (int i = 0; i < ImageShowList.Count; i++)
//{
// //MessageBox.Show(pictureBoxes[i].Name);
// //pictureBoxes[i].Image = Image.FromFile(ImageShowList[i]);
// // 限制:显示图像数量不能超过picturebox数量
// // 显示图像
// // 显示图像路径
// // 清空绘制矩形
//}
}
// 未设置点位
else
{
ReaLTaiizor.Controls.MaterialDialog materialDialog = new ReaLTaiizor.Controls.MaterialDialog(this, "提醒", "未设置点位", "确认", true, "取消");
DialogResult result = materialDialog.ShowDialog(this);
}
}
}
private void tabPage2_Click(object sender, EventArgs e)
{
}
/// <summary>
/// 保存参数
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void materialButton1_Click(object sender, EventArgs e)
{
string s1 = materialTextBoxEdit1.Text.Trim();
string s2 = materialTextBoxEdit2.Text.Trim();
string s3 = materialTextBoxEdit3.Text.Trim();
JSONHelper.AppendStringJSON("s1_path", s1, "param.json");
JSONHelper.AppendStringJSON("s2_path", s2, "param.json");
JSONHelper.AppendStringJSON("s3_path", s3, "param.json");
MessageBox.Show("保存参数成功!");
}
private void materialButton2_Click(object sender, EventArgs e)
{
// 展示图像
}
/// <summary>
/// 遍历所有控件树递,归所有子控件,查找所有包含指定控件类型的控件,并返回所有包含指定控件类型的控件的列表。调用该方法,获取所有按钮控件:var buttons = FindControls<Button>(this);
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="control"></param>
/// <returns></returns>
public static List<T> FindControls<T>(Control control) where T : Control
{
List<T> controls = new List<T>();
// 遍历控件集合
foreach (Control ctrl in control.Controls)
{
// 判断控件类型是否为指定类型
if (ctrl is T tControl)
{
// 添加符合条件的控件
controls.Add(tControl);
}
// 如果控件还有子控件,则递归调用此方法
if (ctrl.HasChildren)
{
controls.AddRange(FindControls<T>(ctrl));
}
}
// 返回符合条件的控件列表
return controls;
}
}
}