diff --git a/App.config b/App.config
index 7bdf230..327f312 100644
--- a/App.config
+++ b/App.config
@@ -41,6 +41,9 @@
+
+
+
diff --git a/ConfigHelper.cs b/ConfigHelper.cs
new file mode 100644
index 0000000..4ec4a63
--- /dev/null
+++ b/ConfigHelper.cs
@@ -0,0 +1,66 @@
+using Newtonsoft.Json;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace videoGather
+{
+ public static class ConfigHelper
+ {
+
+ private static readonly string ConfigFolder =
+ Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Config");
+
+ ///
+ /// 保存配置到指定名称的配置文件
+ ///
+ /// 配置数据类型
+ /// 配置文件名(无需扩展名)
+ /// 配置数据
+ public static void Save(string configName, T data)
+ {
+ if (!Directory.Exists(ConfigFolder))
+ {
+ Directory.CreateDirectory(ConfigFolder);
+ }
+
+ var filePath = GetConfigPath(configName);
+ var json = JsonConvert.SerializeObject(data, Formatting.Indented);
+ File.WriteAllText(filePath, json);
+ }
+
+ ///
+ /// 读取指定配置文件的配置数据
+ ///
+ /// 配置数据类型
+ /// 配置文件名(无需扩展名)
+ /// 当配置不存在时的默认值
+ public static T Load(string configName, T defaultValue = default)
+ {
+ var filePath = GetConfigPath(configName);
+
+ if (!File.Exists(filePath))
+ {
+ return defaultValue;
+ }
+
+ try
+ {
+ var json = File.ReadAllText(filePath);
+ return JsonConvert.DeserializeObject(json);
+ }
+ catch
+ {
+ return defaultValue;
+ }
+ }
+
+ private static string GetConfigPath(string configName)
+ {
+ return Path.Combine(ConfigFolder, $"{configName}.config.json");
+ }
+ }
+}
diff --git a/DoubleBufferedPanel.cs b/DoubleBufferedPanel.cs
new file mode 100644
index 0000000..4052d62
--- /dev/null
+++ b/DoubleBufferedPanel.cs
@@ -0,0 +1,66 @@
+using System;
+using System.Collections.Generic;
+using System.Drawing;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Forms;
+
+namespace videoGather
+{
+ public class DoubleBufferedPanel : Panel
+ {
+
+ private Bitmap _backImage;
+ // 新增背景图属性
+ public Bitmap BackImage
+ {
+ get => _backImage;
+ set
+ {
+ if (_backImage != null)
+ {
+ _backImage.Dispose();
+ }
+ _backImage = value;
+ Invalidate(); // 触发重绘
+ }
+ }
+ // 构造函数
+ public DoubleBufferedPanel()
+ {
+ // 启用双缓冲
+ this.DoubleBuffered = true; // 内置支持
+ // 设置样式以避免闪烁
+ this.SetStyle(ControlStyles.OptimizedDoubleBuffer |
+ ControlStyles.AllPaintingInWmPaint |
+ ControlStyles.UserPaint, true);
+ }
+
+ protected override void OnPaintBackground(PaintEventArgs e)
+ {
+ // 禁用默认背景绘制(关键!)
+ // base.OnPaintBackground(e); // 注释掉这行
+ }
+
+ protected override void OnPaint(PaintEventArgs e)
+ {
+ // 绘制自定义背景图
+ if (_backImage != null)
+ {
+ e.Graphics.DrawImage(_backImage, ClientRectangle);
+ }
+
+ base.OnPaint(e); // 保持原有绘制逻辑
+ }
+
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing)
+ {
+ _backImage?.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+ }
+}
diff --git a/SelectionConfig .cs b/SelectionConfig .cs
new file mode 100644
index 0000000..5144ca6
--- /dev/null
+++ b/SelectionConfig .cs
@@ -0,0 +1,20 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace videoGather
+{
+ public class SelectionConfig
+ {
+
+ public int X { get; set; }
+ public int Y { get; set; }
+ public int Width { get; set; }
+ public int Height { get; set; }
+
+ // 添加时间戳用于校验
+ public DateTime LastModified { get; set; } = DateTime.Now;
+ }
+}
diff --git a/video.Designer.cs b/video.Designer.cs
index fd9c122..120ba6c 100644
--- a/video.Designer.cs
+++ b/video.Designer.cs
@@ -34,6 +34,7 @@ namespace videoGather
this.btn_Capture = new System.Windows.Forms.Button();
this.btn_Close = new System.Windows.Forms.Button();
this.gb_ButtonBox = new System.Windows.Forms.GroupBox();
+ this.button7 = new System.Windows.Forms.Button();
this.textBox1 = new System.Windows.Forms.TextBox();
this.label7 = new System.Windows.Forms.Label();
this.button6 = new System.Windows.Forms.Button();
@@ -73,7 +74,7 @@ namespace videoGather
this.jianchamingcheng = new System.Windows.Forms.DataGridViewTextBoxColumn();
this.kaifangsi = new System.Windows.Forms.DataGridViewTextBoxColumn();
this.gb_CameraPanel = new System.Windows.Forms.GroupBox();
- this.vsp_Panel = new AForge.Controls.VideoSourcePlayer();
+ this.pictureBox1 = new System.Windows.Forms.PictureBox();
this.backgroundWorker1 = new System.ComponentModel.BackgroundWorker();
this.gb_ButtonBox.SuspendLayout();
this.groupBox2.SuspendLayout();
@@ -81,6 +82,7 @@ namespace videoGather
this.groupBox1.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.dGVPatient)).BeginInit();
this.gb_CameraPanel.SuspendLayout();
+ ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit();
this.SuspendLayout();
//
// cb_CameraSelect
@@ -118,6 +120,7 @@ namespace videoGather
//
// gb_ButtonBox
//
+ this.gb_ButtonBox.Controls.Add(this.button7);
this.gb_ButtonBox.Controls.Add(this.textBox1);
this.gb_ButtonBox.Controls.Add(this.label7);
this.gb_ButtonBox.Controls.Add(this.button6);
@@ -141,12 +144,22 @@ namespace videoGather
this.gb_ButtonBox.Margin = new System.Windows.Forms.Padding(2);
this.gb_ButtonBox.Name = "gb_ButtonBox";
this.gb_ButtonBox.Padding = new System.Windows.Forms.Padding(2);
- this.gb_ButtonBox.Size = new System.Drawing.Size(556, 235);
+ this.gb_ButtonBox.Size = new System.Drawing.Size(503, 235);
this.gb_ButtonBox.TabIndex = 16;
this.gb_ButtonBox.TabStop = false;
this.gb_ButtonBox.Text = "功能区";
this.gb_ButtonBox.Enter += new System.EventHandler(this.gb_ButtonBox_Enter);
//
+ // button7
+ //
+ this.button7.Location = new System.Drawing.Point(255, 60);
+ this.button7.Name = "button7";
+ this.button7.Size = new System.Drawing.Size(111, 30);
+ this.button7.TabIndex = 33;
+ this.button7.Text = "选中区域";
+ this.button7.UseVisualStyleBackColor = true;
+ this.button7.Click += new System.EventHandler(this.button7_Click_1);
+ //
// textBox1
//
this.textBox1.Location = new System.Drawing.Point(123, 175);
@@ -168,7 +181,7 @@ namespace videoGather
// button6
//
this.button6.Font = new System.Drawing.Font("宋体", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
- this.button6.Location = new System.Drawing.Point(400, 173);
+ this.button6.Location = new System.Drawing.Point(371, 173);
this.button6.Margin = new System.Windows.Forms.Padding(2);
this.button6.Name = "button6";
this.button6.Size = new System.Drawing.Size(127, 31);
@@ -205,7 +218,7 @@ namespace videoGather
// button1
//
this.button1.Font = new System.Drawing.Font("宋体", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
- this.button1.Location = new System.Drawing.Point(400, 139);
+ this.button1.Location = new System.Drawing.Point(371, 139);
this.button1.Margin = new System.Windows.Forms.Padding(2);
this.button1.Name = "button1";
this.button1.Size = new System.Drawing.Size(127, 31);
@@ -227,7 +240,7 @@ namespace videoGather
// button4
//
this.button4.Font = new System.Drawing.Font("宋体", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
- this.button4.Location = new System.Drawing.Point(400, 23);
+ this.button4.Location = new System.Drawing.Point(371, 23);
this.button4.Margin = new System.Windows.Forms.Padding(2);
this.button4.Name = "button4";
this.button4.Size = new System.Drawing.Size(127, 112);
@@ -255,6 +268,7 @@ namespace videoGather
this.lab_Time.Size = new System.Drawing.Size(87, 16);
this.lab_Time.TabIndex = 13;
this.lab_Time.Text = "00:00:00";
+ this.lab_Time.Visible = false;
//
// label2
//
@@ -265,6 +279,7 @@ namespace videoGather
this.label2.Size = new System.Drawing.Size(87, 16);
this.label2.TabIndex = 12;
this.label2.Text = "录制时间:";
+ this.label2.Visible = false;
//
// btn_EndVideo
//
@@ -275,6 +290,7 @@ namespace videoGather
this.btn_EndVideo.TabIndex = 11;
this.btn_EndVideo.Text = "停止录像(F8)";
this.btn_EndVideo.UseVisualStyleBackColor = true;
+ this.btn_EndVideo.Visible = false;
this.btn_EndVideo.Click += new System.EventHandler(this.btn_EndVideo_Click);
//
// btn_PauseVideo
@@ -286,6 +302,7 @@ namespace videoGather
this.btn_PauseVideo.TabIndex = 10;
this.btn_PauseVideo.Text = "暂停录像(F7)";
this.btn_PauseVideo.UseVisualStyleBackColor = true;
+ this.btn_PauseVideo.Visible = false;
this.btn_PauseVideo.Click += new System.EventHandler(this.btn_PauseVideo_Click);
//
// btn_StartVideo
@@ -297,6 +314,7 @@ namespace videoGather
this.btn_StartVideo.TabIndex = 9;
this.btn_StartVideo.Text = "开始录像(F6)";
this.btn_StartVideo.UseVisualStyleBackColor = true;
+ this.btn_StartVideo.Visible = false;
this.btn_StartVideo.Click += new System.EventHandler(this.btn_StartVideo_Click);
//
// groupBox2
@@ -320,7 +338,7 @@ namespace videoGather
this.groupBox2.Font = new System.Drawing.Font("宋体", 12F);
this.groupBox2.Location = new System.Drawing.Point(3, 17);
this.groupBox2.Name = "groupBox2";
- this.groupBox2.Size = new System.Drawing.Size(556, 153);
+ this.groupBox2.Size = new System.Drawing.Size(503, 153);
this.groupBox2.TabIndex = 18;
this.groupBox2.TabStop = false;
this.groupBox2.Text = "病理";
@@ -328,7 +346,7 @@ namespace videoGather
// button5
//
this.button5.Font = new System.Drawing.Font("宋体", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
- this.button5.Location = new System.Drawing.Point(388, 98);
+ this.button5.Location = new System.Drawing.Point(371, 98);
this.button5.Margin = new System.Windows.Forms.Padding(2);
this.button5.Name = "button5";
this.button5.Size = new System.Drawing.Size(127, 31);
@@ -465,7 +483,7 @@ namespace videoGather
this.groupBox3.Dock = System.Windows.Forms.DockStyle.Left;
this.groupBox3.Location = new System.Drawing.Point(0, 0);
this.groupBox3.Name = "groupBox3";
- this.groupBox3.Size = new System.Drawing.Size(562, 994);
+ this.groupBox3.Size = new System.Drawing.Size(509, 994);
this.groupBox3.TabIndex = 19;
this.groupBox3.TabStop = false;
this.groupBox3.Text = "操作";
@@ -479,7 +497,7 @@ namespace videoGather
this.groupBox1.Margin = new System.Windows.Forms.Padding(2);
this.groupBox1.Name = "groupBox1";
this.groupBox1.Padding = new System.Windows.Forms.Padding(2);
- this.groupBox1.Size = new System.Drawing.Size(556, 586);
+ this.groupBox1.Size = new System.Drawing.Size(503, 586);
this.groupBox1.TabIndex = 19;
this.groupBox1.TabStop = false;
this.groupBox1.Text = "患者信息";
@@ -500,7 +518,7 @@ namespace videoGather
this.dGVPatient.ReadOnly = true;
this.dGVPatient.RowTemplate.Height = 23;
this.dGVPatient.SelectionMode = System.Windows.Forms.DataGridViewSelectionMode.FullRowSelect;
- this.dGVPatient.Size = new System.Drawing.Size(552, 563);
+ this.dGVPatient.Size = new System.Drawing.Size(499, 563);
this.dGVPatient.TabIndex = 0;
this.dGVPatient.CellDoubleClick += new System.Windows.Forms.DataGridViewCellEventHandler(this.dGVPatient_CellDoubleClick);
//
@@ -551,27 +569,28 @@ namespace videoGather
//
// gb_CameraPanel
//
- this.gb_CameraPanel.Controls.Add(this.vsp_Panel);
+ this.gb_CameraPanel.Controls.Add(this.pictureBox1);
this.gb_CameraPanel.Dock = System.Windows.Forms.DockStyle.Fill;
this.gb_CameraPanel.Font = new System.Drawing.Font("宋体", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
- this.gb_CameraPanel.Location = new System.Drawing.Point(562, 0);
+ this.gb_CameraPanel.Location = new System.Drawing.Point(509, 0);
this.gb_CameraPanel.Margin = new System.Windows.Forms.Padding(2);
this.gb_CameraPanel.Name = "gb_CameraPanel";
this.gb_CameraPanel.Padding = new System.Windows.Forms.Padding(2);
- this.gb_CameraPanel.Size = new System.Drawing.Size(1153, 994);
+ this.gb_CameraPanel.Size = new System.Drawing.Size(1206, 994);
this.gb_CameraPanel.TabIndex = 20;
this.gb_CameraPanel.TabStop = false;
this.gb_CameraPanel.Text = "拍摄";
//
- // vsp_Panel
+ // pictureBox1
//
- this.vsp_Panel.Dock = System.Windows.Forms.DockStyle.Fill;
- this.vsp_Panel.Location = new System.Drawing.Point(2, 21);
- this.vsp_Panel.Margin = new System.Windows.Forms.Padding(2);
- this.vsp_Panel.Name = "vsp_Panel";
- this.vsp_Panel.Size = new System.Drawing.Size(1149, 971);
- this.vsp_Panel.TabIndex = 1;
- this.vsp_Panel.VideoSource = null;
+ this.pictureBox1.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right)));
+ this.pictureBox1.BackColor = System.Drawing.SystemColors.ButtonShadow;
+ this.pictureBox1.Location = new System.Drawing.Point(15, 17);
+ this.pictureBox1.Name = "pictureBox1";
+ this.pictureBox1.Size = new System.Drawing.Size(1186, 720);
+ this.pictureBox1.TabIndex = 1;
+ this.pictureBox1.TabStop = false;
+ this.pictureBox1.Paint += new System.Windows.Forms.PaintEventHandler(this.pictureBox1_Paint);
//
// backgroundWorker1
//
@@ -592,7 +611,8 @@ namespace videoGather
this.Margin = new System.Windows.Forms.Padding(2);
this.Name = "video";
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
- this.Text = "视频采集";
+ this.Text = "视频采集V6";
+ this.WindowState = System.Windows.Forms.FormWindowState.Maximized;
this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.Form1_FormClosing);
this.Load += new System.EventHandler(this.Form1_Load);
this.gb_ButtonBox.ResumeLayout(false);
@@ -604,6 +624,7 @@ namespace videoGather
this.groupBox1.ResumeLayout(false);
((System.ComponentModel.ISupportInitialize)(this.dGVPatient)).EndInit();
this.gb_CameraPanel.ResumeLayout(false);
+ ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).EndInit();
this.ResumeLayout(false);
}
@@ -636,7 +657,6 @@ namespace videoGather
private System.Windows.Forms.GroupBox groupBox3;
private System.Windows.Forms.GroupBox groupBox1;
private System.Windows.Forms.GroupBox gb_CameraPanel;
- private AForge.Controls.VideoSourcePlayer vsp_Panel;
private System.Windows.Forms.DataGridView dGVPatient;
private System.Windows.Forms.DataGridViewTextBoxColumn Column1;
private System.Windows.Forms.DataGridViewTextBoxColumn name;
@@ -654,6 +674,8 @@ namespace videoGather
private System.Windows.Forms.Button button6;
private System.Windows.Forms.TextBox textBox1;
private System.Windows.Forms.Label label7;
+ private System.Windows.Forms.PictureBox pictureBox1;
+ private System.Windows.Forms.Button button7;
}
}
diff --git a/video.cs b/video.cs
index a13e589..74d292d 100644
--- a/video.cs
+++ b/video.cs
@@ -1,6 +1,9 @@
+using AForge.Controls;
using AForge.Imaging;
+using AForge.Video;
using AForge.Video.FFMPEG;
+using DirectShowLib;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
@@ -11,6 +14,7 @@ using System.Configuration;
using System.Data;
using System.Diagnostics;
using System.Drawing;
+using System.Drawing.Imaging;
using System.Globalization;
using System.IO;
using System.Linq;
@@ -19,6 +23,7 @@ using System.Net.Http;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.InteropServices;
+using System.Runtime.InteropServices.ComTypes;
using System.Security.Policy;
using System.Text;
using System.Threading;
@@ -33,11 +38,12 @@ using static System.Windows.Forms.VisualStyles.VisualStyleElement;
namespace videoGather
{
- public partial class video : Form
+ public partial class video : Form, ISampleGrabberCB
{
public video()
{
InitializeComponent();
+ InitializeOverlay(); // 初始化透明遮罩层
}
#region 属性
///
@@ -129,6 +135,11 @@ namespace videoGather
/// 是否开启体检编码扫码
///
private string _isInspect = string.Empty;
+ ///
+ /// 是否开启区域截图
+ ///
+ private string _isselectionXY = string.Empty;
+
//超声存放文件访问地址
ArrayList imagearray = new ArrayList();
///
@@ -139,6 +150,36 @@ namespace videoGather
/// 存放自己新增的数据源
///
List hisInfos = new List();
+
+ AForge.Controls.VideoSourcePlayer player;
+
+ #region 新的方式
+ DsDevice device1;
+ private int _pWidth = 1280;
+ private int _pHeight = 720;
+ private int _pStride = 0;
+ private int _pFPS = 30;
+ private volatile bool isGrab = false;
+
+ IVideoWindow videoWindow = null;
+ IMediaControl mediaControl = null;
+ IFilterGraph2 graphBuilder = null;
+ ICaptureGraphBuilder2 captureGraphBuilder = null;
+
+
+ DsROTEntry rot = null;
+
+ DsDevice[] devices;
+ #endregion
+
+ #region 选区
+ // 类成员变量声明
+ private System.Drawing.Rectangle selectionRect; // 存储当前选区矩形
+ private Point startPoint; // 选区起始坐标点
+ private bool isSelecting; // 是否处于选区状态标志
+ private DoubleBufferedPanel overlayPanel; // 透明遮罩层控件
+ #endregion
+
#endregion
#region 窗口加载与关闭
@@ -149,10 +190,11 @@ namespace videoGather
///
private void Form1_Load(object sender, EventArgs e)
{
-
+ // _pWidth = pictureBox1.Width;
+ // _pHeight = pictureBox1.Height;
dGVPatient.AutoGenerateColumns = false;
- InitCamera();
+ // InitCamera();
InitCameraSelect();
//读取配置信息
_isInspect = ConfigurationManager.AppSettings["isInspect"];
@@ -166,6 +208,7 @@ namespace videoGather
_xywh = ConfigurationManager.AppSettings["xywh"];
_model = ConfigurationManager.AppSettings["model"];
_ishisinfo = ConfigurationManager.AppSettings["ishisinfo"];
+ _isselectionXY = ConfigurationManager.AppSettings["isselectionXY"];
if (_type == "1")
{
@@ -198,6 +241,18 @@ namespace videoGather
label7.Visible = false;
textBox1.Visible = false;
}
+ if (_isselectionXY=="1")
+ {
+ button7.Visible = true;
+ }
+ else
+ {
+ button7.Visible = false;
+ }
+ // 启用双缓冲减少闪烁
+ typeof(System.Windows.Forms.PictureBox).InvokeMember("DoubleBuffered",
+ BindingFlags.SetProperty | BindingFlags.Instance | BindingFlags.NonPublic,
+ null, pictureBox1, new object[] { true });
//秒表
timer_count = new System.Timers.Timer(); //实例化Timer类,设置间隔时间为1000毫秒;
@@ -217,9 +272,43 @@ namespace videoGather
}
label4.Focus();
// 添加对窗口大小改变事件的订阅
- this.Resize += new EventHandler(Form1_Resize);
+ // this.Resize += new EventHandler(Form1_Resize);
}
+ #region 初始化透明遮罩层
+ ///
+ /// 初始化透明遮罩层
+ ///
+ private void InitializeOverlay()
+ {
+ // 创建透明遮罩层
+ overlayPanel = new DoubleBufferedPanel
+ {
+ // 设置与 PictureBox 相同的尺寸和位置
+ // Size = pictureBox1.Size,
+ Location = pictureBox1.Location,
+ // 设置透明背景
+ BackColor = Color.FromArgb(0, 0, 0, 0),
+ // 设置十字光标
+ Cursor = Cursors.Cross,
+ // 初始不可见
+ Visible = false,
+ Width= 1280,
+ Height=720
+ };
+
+ // 将遮罩层添加到PictureBox的父容器(确保层级正确)
+ pictureBox1.Parent.Controls.Add(overlayPanel);
+ // 置于顶层,保证在视频上方显示
+ overlayPanel.BringToFront();
+
+ // 绑定事件处理器
+ overlayPanel.MouseDown += Overlay_MouseDown;
+ overlayPanel.MouseMove += Overlay_MouseMove;
+ overlayPanel.MouseUp += Overlay_MouseUp;
+ overlayPanel.Paint += Overlay_Paint;
+ }
+ #endregion
private void Form1_Resize(object sender, EventArgs e)
{
//// 检查视频捕获是否已初始化
@@ -260,7 +349,8 @@ namespace videoGather
///
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
- EndCamera();
+ // EndCamera();
+ StopCamera();
}
#endregion
@@ -285,20 +375,31 @@ namespace videoGather
public void InitCameraSelect()
{
this.cb_CameraSelect.DropDownStyle = ComboBoxStyle.DropDownList;
- //根据读取到的摄像头加载选择项
- foreach (AForge.Video.DirectShow.FilterInfo item in infoCollection)
- {
- this.cb_CameraSelect.Items.Add(item.Name);
- }
- //for (int i = 1; i <= infoCollection.Count; i++)
+ ////根据读取到的摄像头加载选择项
+ //foreach (AForge.Video.DirectShow.FilterInfo item in infoCollection)
//{
- // this.cb_CameraSelect.Items.Add("摄像头" + i);
+ // this.cb_CameraSelect.Items.Add(item.Name);
//}
+ ////for (int i = 1; i <= infoCollection.Count; i++)
+ ////{
+ //// this.cb_CameraSelect.Items.Add("摄像头" + i);
+ ////}
+ //if (cb_CameraSelect.Items.Count > 0)
+ //{
+ // cb_CameraSelect.SelectedIndex = 0;
+ //}
+
+ devices = DsDevice.GetDevicesOfCat(FilterCategory.VideoInputDevice);
+ for (int i = 0; i < devices.Length; i++)
+ {
+ this.cb_CameraSelect.Items.Add(devices[i].Name);
+
+ }
if (cb_CameraSelect.Items.Count > 0)
{
- cb_CameraSelect.SelectedIndex = 0;
+ cb_CameraSelect.SelectedIndex = 1;
+ //}
}
-
}
#endregion
@@ -310,24 +411,89 @@ namespace videoGather
///
private void btn_Connect_Click(object sender, EventArgs e)
{
- var CameraSelect = this.cb_CameraSelect.Text;
- var selectIndex = this.cb_CameraSelect.SelectedIndex;
- if (string.IsNullOrEmpty(CameraSelect))
+ // var CameraSelect = this.cb_CameraSelect.Text;
+ // var selectIndex = this.cb_CameraSelect.SelectedIndex;
+ // if (string.IsNullOrEmpty(CameraSelect))
+ // {
+ // MessageBox.Show("请先选择视频源");
+ // return;
+ // }
+
+
+ // //已有连接的摄像头时先关闭
+ // if (videoCapture != null)
+ // {
+ // EndCamera();
+ // }
+
+ // player = new VideoSourcePlayer();
+ // player.Dock = DockStyle.Fill;
+ // gb_CameraPanel.Controls.Add(player);
+
+
+ // videoCapture = new AForge.Video.DirectShow.VideoCaptureDevice(infoCollection[selectIndex].MonikerString);
+ // videoCapture.VideoResolution = videoCapture.VideoCapabilities
+ //.OrderBy(x => x.MaximumFrameRate)
+ //.FirstOrDefault();
+
+ // //启动摄像头
+ // player.VideoSource = videoCapture;
+ // player.Start();
+ // // videoCapture.Start();
+ // //this.vsp_Panel.VideoSource.NewFrame += videoCapture_NewFrame;
+ // //this.vsp_Panel.VideoSource.
+
+ StopCamera();
+ // 调用前检查
+ if (!ValidateResolution(_pWidth, _pHeight))
{
- MessageBox.Show("请先选择视频源");
+ MessageBox.Show("不支持的视频分辨率");
return;
}
- //已有连接的摄像头时先关闭
- if (videoCapture != null)
+
+ if (devices.Length == 0)
{
- EndCamera();
+ MessageBox.Show("无视频源");
+ return;
+ }
+ else
+ {
+ DsDevice ds=null;
+ foreach (var item in devices)
+ {
+ if(item.Name== this.cb_CameraSelect.SelectedItem)
+ {
+ ds = item;
+ break;
+ }
+ }
+
+ CaptureVideo(ds);
}
- videoCapture = new AForge.Video.DirectShow.VideoCaptureDevice(infoCollection[selectIndex].MonikerString);
- //启动摄像头
- this.vsp_Panel.VideoSource = videoCapture;
- this.vsp_Panel.Start();
this.btn_Capture.Enabled = true;
+
+
}
+
+
+ ///
+ /// 检查是否支持分辨率
+ ///
+ ///
+ ///
+ ///
+ private bool ValidateResolution(int width, int height)
+ {
+ // 检查是否为设备支持的分辨率
+ var supportedResolutions = new[] {
+ new Size(640, 480),
+ new Size(1280, 720),
+ new Size(1920, 1080)
+ };
+ return supportedResolutions.Any(s => s.Width == width && s.Height == height);
+ }
+
+
///
/// 关闭按钮
///
@@ -336,23 +502,53 @@ namespace videoGather
private void btn_Close_Click(object sender, EventArgs e)
{
HookStop();
- EndCamera();
+ // EndCamera();
+ StopCamera();
}
///
/// 关闭摄像头
///
public void EndCamera()
{
- if (this.vsp_Panel.VideoSource != null)
+ if (videoCapture != null)
{
- //也可以用 Stop() 方法关闭
- //指示灯停止且等待
- this.vsp_Panel.SignalToStop();
- //停止且等待
- this.vsp_Panel.WaitForStop();
- this.vsp_Panel.VideoSource = null;
+ // 先移除事件处理器
+ // this.vsp_Panel.VideoSource.NewFrame -= videoCapture_NewFrame;
+ if (player!=null)
+ {
+
+ videoCapture.SignalToStop();
+ videoCapture.WaitForStop();
+ videoCapture.Stop();
+
+ // 停止视频源
+ player.SignalToStop();
+ player.WaitForStop();
+ player.Stop();
+ gb_CameraPanel.Controls.Clear();
+ videoCapture = null;
+ player = null;
+
+
+ }
+
}
+ //if (this.vsp_Panel.VideoSource != null)
+ //{
+ // //也可以用 Stop() 方法关闭
+ // //指示灯停止且等待
+ // //this.vsp_Panel.SignalToStop();
+ // ////停止且等待
+ // //this.vsp_Panel.WaitForStop();
+ // //this.vsp_Panel.VideoSource = null;
+ // // this.vsp_Panel.Stop();
+ // // this.vsp_Panel.Dispose();
+ // // this.vsp_Panel.VideoSource = null;
+
+
+
+ //}
}
#endregion
@@ -366,29 +562,34 @@ namespace videoGather
{
try
{
- if (videoCapture == null)
- {
- MessageBox.Show("设备未连接");
- return;
- }
- imgMap = this.vsp_Panel.GetCurrentVideoFrame();
- if (imgMap == null)
- {
- return;
- }
- var saveName = $"{filePath}{$"{DateTime.Now.ToString("yyyyMMddhhmmssffff")}"}.jpg";
- imgMap.Save(saveName);
- imagearray.Add(saveName);
- // 使用 Invoke 方法确保在UI线程上更新标签的文本
- if (label1.InvokeRequired)
- {
- label1.Invoke(new Action(() => label1.Text = imagearray.Count.ToString()));
- }
- else
- {
- label1.Text = imagearray.Count.ToString();
- }
- label1.Refresh();
+ #region 之前
+ //if (videoCapture == null)
+ //{
+ // MessageBox.Show("设备未连接");
+ // return;
+ //}
+ //imgMap = player.GetCurrentVideoFrame();
+ //if (imgMap == null)
+ //{
+ // return;
+ //}
+ //var saveName = $"{filePath}{$"{DateTime.Now.ToString("yyyyMMddhhmmssffff")}"}.jpg";
+ //imgMap.Save(saveName);
+ //imgMap = null;
+ //imagearray.Add(saveName);
+ //// 使用 Invoke 方法确保在UI线程上更新标签的文本
+ //if (label1.InvokeRequired)
+ //{
+ // label1.Invoke(new Action(() => label1.Text = imagearray.Count.ToString()));
+ //}
+ //else
+ //{
+ // label1.Text = imagearray.Count.ToString();
+ //}
+ //label1.Refresh();
+ #endregion
+
+ isGrab = true;
}
catch (Exception ex)
{
@@ -1108,7 +1309,7 @@ namespace videoGather
///
private void SaveImageDcm()
{
- Bitmap currentFrame = this.vsp_Panel.GetCurrentVideoFrame();
+ Bitmap currentFrame = player.GetCurrentVideoFrame();
if (currentFrame != null)
{
//开启区域截图
@@ -1900,6 +2101,634 @@ namespace videoGather
}
}
}
+
+ private void button7_Click(object sender, EventArgs e)
+ {
+
+ }
+
+
+ #region 新的方式内容
+ //private void StartCamera()
+ //{
+
+ // DsDevice[] devices = DsDevice.GetDevicesOfCat(FilterCategory.VideoInputDevice);
+
+ // if (devices.Length == 0)
+ // {
+ // MessageBox.Show("无相机连接!");
+ // return;
+ // }
+ // else
+ // {
+
+ // CaptureVideo((DsDevice)comboBox1.SelectedItem);
+ // }
+ //}
+
+
+ public void CaptureVideo(DsDevice device)
+ {
+ pictureBox1.Image = null;
+ int hr = 0;
+ IBaseFilter sourceFilter = null;
+ ISampleGrabber sampleGrabber = null;
+
+ try
+ {
+ GetInterfaces();
+ hr = this.captureGraphBuilder.SetFiltergraph(this.graphBuilder);
+ DsError.ThrowExceptionForHR(hr);
+ sourceFilter = SelectCaptureDevice(device);
+ hr = this.graphBuilder.AddFilter(sourceFilter, "Video Capture");
+ DsError.ThrowExceptionForHR(hr);
+ sampleGrabber = new SampleGrabber() as ISampleGrabber;
+ ConfigureSampleGrabber(sampleGrabber);
+ hr = this.graphBuilder.AddFilter(sampleGrabber as IBaseFilter, "Frame Callback");
+ DsError.ThrowExceptionForHR(hr);
+ SetConfigParams(this.captureGraphBuilder, sourceFilter, _pFPS, _pWidth, _pHeight);
+ hr = this.captureGraphBuilder.RenderStream(PinCategory.Preview, MediaType.Video, sourceFilter, (sampleGrabber as IBaseFilter), null);
+
+
+
+ DsError.ThrowExceptionForHR(hr);
+
+ SaveSizeInfo(sampleGrabber);
+ SetupVideoWindow();
+
+ rot = new DsROTEntry(this.graphBuilder);
+
+ hr = this.mediaControl.Run();
+ DsError.ThrowExceptionForHR(hr);
+ }
+ catch
+ {
+ MessageBox.Show("error!");
+ }
+ finally
+ {
+ if (sourceFilter != null)
+ {
+ Marshal.ReleaseComObject(sourceFilter);
+ sourceFilter = null;
+ }
+
+ if (sampleGrabber != null)
+ {
+ Marshal.ReleaseComObject(sampleGrabber);
+ sampleGrabber = null;
+ }
+ }
+ }
+
+ public void CaptureVideo()
+ {
+ pictureBox1.Image = null;
+ int hr = 0;
+ IBaseFilter sourceFilter = null;
+ ISampleGrabber sampleGrabber = null;
+
+ try
+ {
+ // Get DirectShow interfaces
+ GetInterfaces();
+
+ // Attach the filter graph to the capture graph
+ hr = this.captureGraphBuilder.SetFiltergraph(this.graphBuilder);
+ DsError.ThrowExceptionForHR(hr);
+
+ // Use the system device enumerator and class enumerator to find
+ // a video capture/preview device, such as a desktop USB video camera.
+ sourceFilter = FindCaptureDevice();
+ // Add Capture filter to graph.
+ hr = this.graphBuilder.AddFilter(sourceFilter, "Video Capture");
+ DsError.ThrowExceptionForHR(hr);
+
+ // Initialize SampleGrabber.
+ sampleGrabber = new SampleGrabber() as ISampleGrabber;
+ // Configure SampleGrabber. Add preview callback.
+ ConfigureSampleGrabber(sampleGrabber);
+
+ // Add SampleGrabber to graph.
+ hr = this.graphBuilder.AddFilter(sampleGrabber as IBaseFilter, "Frame Callback");
+ DsError.ThrowExceptionForHR(hr);
+
+ // Configure preview settings.
+ SetConfigParams(this.captureGraphBuilder, sourceFilter, _pFPS, _pWidth, _pHeight);
+
+ // Render the preview
+ hr = this.captureGraphBuilder.RenderStream(PinCategory.Preview, MediaType.Video, sourceFilter, (sampleGrabber as IBaseFilter), null);
+ DsError.ThrowExceptionForHR(hr);
+
+ SaveSizeInfo(sampleGrabber);
+
+ // Set video window style and position
+ SetupVideoWindow();
+
+ // Add our graph to the running object table, which will allow
+ // the GraphEdit application to "spy" on our graph
+ rot = new DsROTEntry(this.graphBuilder);
+
+ // Start previewing video data
+ hr = this.mediaControl.Run();
+ DsError.ThrowExceptionForHR(hr);
+ }
+ catch
+ {
+ MessageBox.Show("error!");
+ }
+ finally
+ {
+ if (sourceFilter != null)
+ {
+ Marshal.ReleaseComObject(sourceFilter);
+ sourceFilter = null;
+ }
+
+ if (sampleGrabber != null)
+ {
+ Marshal.ReleaseComObject(sampleGrabber);
+ sampleGrabber = null;
+ }
+ }
+ }
+
+ public IBaseFilter SelectCaptureDevice(DsDevice device)
+ {
+ object source = null;
+ Guid iid = typeof(IBaseFilter).GUID;
+ device.Mon.BindToObject(null, null, ref iid, out source);
+ return (IBaseFilter)source;
+ }
+
+ public IBaseFilter FindCaptureDevice()
+ {
+ int hr = 0;
+#if USING_NET11
+ UCOMIEnumMoniker classEnum = null;
+ UCOMIMoniker[] moniker = new UCOMIMoniker[1];
+#else
+ IEnumMoniker classEnum = null;
+ IMoniker[] moniker = new IMoniker[1];
+#endif
+ object source = null;
+
+ // Create the system device enumerator
+ ICreateDevEnum devEnum = (ICreateDevEnum)new CreateDevEnum();
+
+ // Create an enumerator for the video capture devices
+ hr = devEnum.CreateClassEnumerator(FilterCategory.VideoInputDevice, out classEnum, 0);
+ DsError.ThrowExceptionForHR(hr);
+
+ // The device enumerator is no more needed
+ Marshal.ReleaseComObject(devEnum);
+
+ // If there are no enumerators for the requested type, then
+ // CreateClassEnumerator will succeed, but classEnum will be NULL.
+ if (classEnum == null)
+ {
+ throw new ApplicationException("No video capture device was detected.\r\n\r\n" +
+ "This sample requires a video capture device, such as a USB WebCam,\r\n" +
+ "to be installed and working properly. The sample will now close.");
+ }
+
+ // Use the first video capture device on the device list.
+ // Note that if the Next() call succeeds but there are no monikers,
+ // it will return 1 (S_FALSE) (which is not a failure). Therefore, we
+ // check that the return code is 0 (S_OK).
+#if USING_NET11
+ int i;
+ if (classEnum.Next (moniker.Length, moniker, IntPtr.Zero) == 0)
+#else
+ if (classEnum.Next(moniker.Length, moniker, IntPtr.Zero) == 0)
+#endif
+ {
+ // Bind Moniker to a filter object
+ Guid iid = typeof(IBaseFilter).GUID;
+ moniker[0].BindToObject(null, null, ref iid, out source);
+ }
+ else
+ {
+ throw new ApplicationException("Unable to access video capture device!");
+ }
+
+ // Release COM objects
+ Marshal.ReleaseComObject(moniker[0]);
+ Marshal.ReleaseComObject(classEnum);
+
+ // An exception is thrown if cast fail
+ return (IBaseFilter)source;
+ }
+
+ public void GetInterfaces()
+ {
+ int hr = 0;
+
+ // An exception is thrown if cast fail
+ this.graphBuilder = (IFilterGraph2)new FilterGraph();
+ this.captureGraphBuilder = (ICaptureGraphBuilder2)new CaptureGraphBuilder2();
+ this.mediaControl = (IMediaControl)this.graphBuilder;
+ this.videoWindow = (IVideoWindow)this.graphBuilder;
+
+
+ DsError.ThrowExceptionForHR(hr);
+ }
+
+ public void StopCamera()
+ {
+ if (mediaControl != null)
+ {
+ int hr = mediaControl.StopWhenReady();
+ DsError.ThrowExceptionForHR(hr);
+ }
+
+ if (videoWindow != null)
+ {
+ videoWindow.put_Visible(OABool.False);
+ videoWindow.put_Owner(IntPtr.Zero);
+ }
+
+ // Remove filter graph from the running object table.
+ if (rot != null)
+ {
+ rot.Dispose();
+ rot = null;
+ }
+
+ if (this.mediaControl != null)
+ {
+ Marshal.ReleaseComObject(this.mediaControl); this.mediaControl = null;
+ Marshal.ReleaseComObject(this.videoWindow); this.videoWindow = null;
+ Marshal.ReleaseComObject(this.graphBuilder); this.graphBuilder = null;
+ Marshal.ReleaseComObject(this.captureGraphBuilder); this.captureGraphBuilder = null;
+ }
+ }
+
+ public void SetupVideoWindow()
+ {
+ int hr = 0;
+
+ // Set the video window to be a child of the PictureBox
+ hr = this.videoWindow.put_Owner(pictureBox1.Handle);
+ DsError.ThrowExceptionForHR(hr);
+
+ hr = this.videoWindow.put_WindowStyle(WindowStyle.Child);
+ DsError.ThrowExceptionForHR(hr);
+
+ // Make the video window visible, now that it is properly positioned
+ hr = this.videoWindow.put_Visible(OABool.True);
+ DsError.ThrowExceptionForHR(hr);
+
+ // Set the video position
+ System.Drawing.Rectangle rc = pictureBox1.ClientRectangle;
+ hr = videoWindow.SetWindowPosition(0, 0, _pWidth, _pHeight);
+ DsError.ThrowExceptionForHR(hr);
+ }
+
+
+
+ private void SetConfigParams(ICaptureGraphBuilder2 capGraph, IBaseFilter capFilter, int iFrameRate, int iWidth, int iHeight)
+ {
+ int hr;
+ object config;
+ AMMediaType mediaType;
+ // Find the stream config interface
+ hr = capGraph.FindInterface(
+ PinCategory.Capture, MediaType.Video, capFilter, typeof(IAMStreamConfig).GUID, out config);
+
+ IAMStreamConfig videoStreamConfig = config as IAMStreamConfig;
+ if (videoStreamConfig == null)
+ {
+ throw new Exception("Failed to get IAMStreamConfig");
+ }
+
+ // Get the existing format block
+ hr = videoStreamConfig.GetFormat(out mediaType);
+ DsError.ThrowExceptionForHR(hr);
+
+ // copy out the videoinfoheader
+ VideoInfoHeader videoInfoHeader = new VideoInfoHeader();
+ Marshal.PtrToStructure(mediaType.formatPtr, videoInfoHeader);
+
+ // if overriding the framerate, set the frame rate
+ if (iFrameRate > 0)
+ {
+ videoInfoHeader.AvgTimePerFrame = 10000000 / iFrameRate;
+ }
+
+ // if overriding the width, set the width
+ if (iWidth > 0)
+ {
+ videoInfoHeader.BmiHeader.Width = iWidth;
+ }
+
+ // if overriding the Height, set the Height
+ if (iHeight > 0)
+ {
+ videoInfoHeader.BmiHeader.Height = iHeight;
+ }
+
+ // Copy the media structure back
+ Marshal.StructureToPtr(videoInfoHeader, mediaType.formatPtr, false);
+
+ // Set the new format
+ hr = videoStreamConfig.SetFormat(mediaType);
+ DsError.ThrowExceptionForHR(hr);
+
+ DsUtils.FreeAMMediaType(mediaType);
+ mediaType = null;
+ }
+
+ private void SaveSizeInfo(ISampleGrabber sampleGrabber)
+ {
+ int hr;
+
+ // Get the media type from the SampleGrabber
+ AMMediaType media = new AMMediaType();
+ hr = sampleGrabber.GetConnectedMediaType(media);
+ DsError.ThrowExceptionForHR(hr);
+
+ if ((media.formatType != FormatType.VideoInfo) || (media.formatPtr == IntPtr.Zero))
+ {
+ throw new NotSupportedException("Unknown Grabber Media Format");
+ }
+
+ // Grab the size info
+ VideoInfoHeader videoInfoHeader = (VideoInfoHeader)Marshal.PtrToStructure(media.formatPtr, typeof(VideoInfoHeader));
+ _pStride = _pWidth * (videoInfoHeader.BmiHeader.BitCount / 8);
+
+ DsUtils.FreeAMMediaType(media);
+ media = null;
+ }
+
+ private void ConfigureSampleGrabber(ISampleGrabber sampleGrabber)
+ {
+ AMMediaType media;
+ int hr;
+
+ // Set the media type to Video/RBG24
+ media = new AMMediaType();
+ media.majorType = MediaType.Video;
+ media.subType = MediaSubType.RGB24;
+ media.formatType = FormatType.VideoInfo;
+
+ hr = sampleGrabber.SetMediaType(media);
+ DsError.ThrowExceptionForHR(hr);
+
+ DsUtils.FreeAMMediaType(media);
+ media = null;
+
+ hr = sampleGrabber.SetCallback(this, 1);
+ DsError.ThrowExceptionForHR(hr);
+ }
+
+ public int BufferCB(double SampleTime, IntPtr pBuffer, int BufferLen)
+ {
+
+ if (isGrab)
+ {
+ Bitmap bmp = new Bitmap(_pWidth, _pHeight, _pStride, PixelFormat.Format24bppRgb, pBuffer);
+ bmp.RotateFlip(RotateFlipType.Rotate180FlipX);
+ this.BeginInvoke((MethodInvoker)delegate
+ {
+ // pictureBox2.BackgroundImage = bmp;
+ var saveName = string.Empty;
+ if (rowhisinfo != null)
+ {
+ saveName = $"{filePath}{$"{rowhisinfo.jianchaid}"}{$"{DateTime.Now.ToString("yyyyMMddhhmmssffff")}"}.jpg";
+ }
+ else
+ {
+
+ saveName = $"{filePath}{$"{DateTime.Now.ToString("yyyyMMddhhmmssffff")}"}.jpg";
+ }
+ //表示开启了选中区域 截图一下 当背景
+ if (isSelecting && overlayPanel.Visible)
+ {
+ // 外部设置背景图
+ overlayPanel.BackImage = bmp;
+ }
+ else
+ {
+ #region 根据保存的配置进行裁剪
+ // 读取配置,不存在时返回null
+ var loadedConfig = ConfigHelper.Load("selectionXY");
+ // 当存在有效配置时执行裁剪
+ if (_isselectionXY=="1" &&loadedConfig != null && loadedConfig.Width > 0 && loadedConfig.Height > 0)
+ {
+ // 创建选区矩形
+ var cropRect = new System.Drawing.Rectangle(
+ loadedConfig.X,
+ loadedConfig.Y,
+ loadedConfig.Width,
+ loadedConfig.Height);
+
+ // 执行裁剪(使用Clone保证原图不被释放)
+ using (bmp) // 释放原始位图
+ {
+ // 创建新Bitmap对象保存裁剪结果
+ var croppedBmp = bmp.Clone(cropRect, bmp.PixelFormat);
+ croppedBmp.Save(saveName);
+ }
+ }
+ else // 无有效配置时保存完整图片
+ {
+ bmp.Save(saveName);
+ }
+ #endregion
+
+ // bmp.Save(saveName);
+ imagearray.Add(saveName);
+ // 使用 Invoke 方法确保在UI线程上更新标签的文本
+ if (label1.InvokeRequired)
+ {
+ label1.Invoke(new Action(() => label1.Text = imagearray.Count.ToString()));
+ }
+ else
+ {
+ label1.Text = imagearray.Count.ToString();
+ }
+ label1.Refresh();
+ }
+
+
+ });
+ isGrab = false;
+ }
+ return 0;
+ }
+
+ public int SampleCB(double SampleTime, IMediaSample pSample)
+ {
+ return 0;
+ }
+ #endregion
+
+ ///
+ /// 点击"选区域"按钮
+ ///
+ ///
+ ///
+ private void button7_Click_1(object sender, EventArgs e)
+ {
+ // 清空选区
+ selectionRect = System.Drawing.Rectangle.Empty;
+ //截图
+ btn_Capture_Click(null,null);
+ // 显示遮罩层
+ overlayPanel.Visible = true;
+
+ // 进入选区模式
+ isSelecting = true;
+ }
+
+
+
+ #region 鼠标事件处理
+ // 鼠标按下事件处理
+ private void Overlay_MouseDown(object sender, MouseEventArgs e)
+ {
+ // 当处于选区模式且按下左键时
+ if (isSelecting && e.Button == MouseButtons.Left)
+ {
+ // 记录起始坐标点
+ startPoint = e.Location;
+ // 初始化选区矩形
+ selectionRect = new System.Drawing.Rectangle(e.Location, Size.Empty);
+ }
+ }
+
+ // 鼠标移动事件处理
+ private void Overlay_MouseMove(object sender, MouseEventArgs e)
+ {
+
+ // 当处于选区模式且按住左键拖动时
+ if (isSelecting && e.Button == MouseButtons.Left)
+ {
+ // 计算选区矩形参数
+ int x = Math.Min(startPoint.X, e.X);
+ int y = Math.Min(startPoint.Y, e.Y);
+ int width = Math.Abs(e.X - startPoint.X);
+ int height = Math.Abs(e.Y - startPoint.Y);
+
+ // 更新选区矩形
+ selectionRect = new System.Drawing.Rectangle(x, y, width, height);
+
+ // 限制选区在控件范围内
+ selectionRect = System.Drawing.Rectangle.Intersect(selectionRect, overlayPanel.ClientRectangle);
+
+ // 触发重绘更新选区显示
+ overlayPanel.Invalidate();
+ }
+ }
+
+ // 鼠标释放事件处理
+ private void Overlay_MouseUp(object sender, MouseEventArgs e)
+ {
+ // 当结束选区操作时
+ if (isSelecting)
+ {
+ // 退出选区模式
+ isSelecting = false;
+ // 隐藏遮罩层
+ overlayPanel.Visible = false;
+ // 清除背景图
+ overlayPanel.BackImage = null;
+ // 转换到实际图像坐标系
+ System.Drawing.Rectangle imageCoords = GetImageCoordinates(selectionRect);
+ var config = new SelectionConfig
+ {
+ X = imageCoords.X,
+ Y = imageCoords.Y,
+ Width = imageCoords.Width,
+ Height = imageCoords.Height
+ };
+ //存储坐标
+ ConfigHelper.Save("selectionXY", config);
+ //// 显示坐标信息
+ //MessageBox.Show($"捕获的选区坐标:\n" +
+ // $"X={imageCoords.X}, Y={imageCoords.Y}\n" +
+ // $"宽={imageCoords.Width}, 高={imageCoords.Height}");
+ }
+ }
+ #endregion
+
+
+ #region 绘制逻辑
+ private void pictureBox1_Paint(object sender, PaintEventArgs e)
+ {
+ //if (!selectionRect.IsEmpty)
+ //{
+ // using (Pen pen = new Pen(Color.Blue, 2)) // 蓝色边框
+ // {
+ // e.Graphics.DrawRectangle(pen, selectionRect);
+ // }
+ //}
+ }
+
+ // 遮罩层绘制事件
+ private void Overlay_Paint(object sender, PaintEventArgs e)
+ {
+ // 当存在有效选区时进行绘制
+ if (!selectionRect.IsEmpty)
+ {
+ using (Pen pen = new Pen(Color.Red, 2)) // 2像素宽红色边框
+ using (Brush brush = new SolidBrush(Color.FromArgb(50, 255, 0, 0))) // 半透明红色填充
+ {
+ // 绘制半透明填充区域
+ e.Graphics.FillRectangle(brush, selectionRect);
+ // 绘制红色边框
+ e.Graphics.DrawRectangle(pen, selectionRect);
+ }
+ }
+ }
+ #endregion
+
+ #region 坐标转换方法
+ ///
+ /// 将控件坐标转换为实际图像坐标
+ ///
+ /// 控件坐标系中的矩形
+ /// 实际图像坐标系中的矩形
+ private System.Drawing.Rectangle GetImageCoordinates(System.Drawing.Rectangle controlRect)
+ {
+ if (pictureBox1.SizeMode == PictureBoxSizeMode.Zoom)
+ {
+ // 检查图像是否存在
+ if (pictureBox1.Image == null)
+ return System.Drawing.Rectangle.Empty;
+
+ // 计算Zoom模式的缩放比例
+ float zoomRatio = Math.Min(
+ (float)pictureBox1.Width / pictureBox1.Image.Width,
+ (float)pictureBox1.Height / pictureBox1.Image.Height);
+
+ // 计算实际显示区域参数
+ int displayWidth = (int)(pictureBox1.Image.Width * zoomRatio);
+ int displayHeight = (int)(pictureBox1.Image.Height * zoomRatio);
+ int offsetX = (pictureBox1.Width - displayWidth) / 2;
+ int offsetY = (pictureBox1.Height - displayHeight) / 2;
+
+ // 执行坐标转换(考虑居中显示偏移)
+ return new System.Drawing.Rectangle(
+ (int)((controlRect.X - offsetX) / zoomRatio),
+ (int)((controlRect.Y - offsetY) / zoomRatio),
+ (int)(controlRect.Width / zoomRatio),
+ (int)(controlRect.Height / zoomRatio));
+ }
+ else
+ {
+ // 如果SizeMode不是Zoom,直接返回
+ return controlRect;
+ }
+ }
+ #endregion
+
+ private void button8_Click(object sender, EventArgs e)
+ {
+ // 重新绘制选区
+ pictureBox1.Invalidate();
+ }
}
}
diff --git a/videoGather.csproj b/videoGather.csproj
index b0081ab..0806d7c 100644
--- a/videoGather.csproj
+++ b/videoGather.csproj
@@ -86,6 +86,10 @@
packages\fo-dicom.Desktop.4.0.0\lib\net45\Dicom.Core.dll
+
+ False
+ bin\x86\Debug\DirectShowLib.dll
+
packages\Newtonsoft.Json.13.0.3\lib\net45\Newtonsoft.Json.dll
@@ -104,6 +108,10 @@
+
+
+ Component
+
@@ -129,6 +137,7 @@
+