工具块与vs的联合编程(豆包总结生成)

一、核心知识点梳理(按功能模块)

模块 核心知识点 关键注意事项
ToolBlock 基础操作 1. CogToolBlock 是 VisionPro 工具块容器,封装多个视觉工具2. 序列化:CogSerializer.Load/SaveObjectFromFile 读写 vpp 文件3. 跨线程操作 UI 必须用Invoke 1. vpp 文件路径必须正确,否则加载失败2. 跨线程直接操作 UI 控件会抛异常
图片与 ToolBlock 交互 1. 本地 Bitmap 转 VisionPro 图像对象 CogImage24PlanarColor2. tb.Inputs["参数名"].Value给工具块输入赋值 仅支持 24 位彩色图,灰度图需用 CogImage8Grey
ToolBlock 运行 1. tb.Run()执行工具块所有工具2. CreateLastRunRecord()获取运行记录绑定到 CogRecordDisplay Run () 前必须确保输入参数已赋值,否则工具执行失败
结果处理 1. tb.Outputs["参数名"].Value获取工具块输出结果2. 数值转换(Convert.ToDouble)判断 OK/NG 输出参数名必须和 ToolBlock 内定义的一致(大小写敏感)
图片保存 1. CogRecordDisplay 转 Bitmap:CreateContentBitmap2. 动态创建 OK/NG 目录3. DateTime 生成唯一文件名 1. 文件名不能包含:、--等非法字符2. Bitmap 使用后需 Dispose 释放内存

二、可复用关键代码片段(标注用途,直接复制用)

1. 异步加载 ToolBlock(窗体加载,避免 UI 阻塞)

csharp

运行

复制代码
// 全局变量(窗体类内)
private CogToolBlock _toolBlock; // 工具块核心对象
private List<string> _imagePaths = new List<string>(); // 图片路径列表
private int _currentImgIndex = 0; // 当前图片索引

// 窗体加载事件:跨线程加载ToolBlock(核心)
private void Form1_Load(object sender, EventArgs e)
{
    // 异步线程加载,避免UI卡死
    Thread loadThread = new Thread(LoadToolBlock);
    loadThread.IsBackground = true; // 设为后台线程,窗口关闭自动退出
    loadThread.Start();
}

// 加载ToolBlock的核心方法
private void LoadToolBlock()
{
    try
    {
        // 跨线程操作UI控件必须用Invoke
        this.Invoke(new Action(() =>
        {
            // 加载vpp工具块文件(替换为你的路径)
            string tbPath = @"D:\C#\绘制与保存\加载工具块\bin\Debug\tb.vpp";
            _toolBlock = CogSerializer.LoadObjectFromFile(tbPath) as CogToolBlock;
            cogToolBlockEditV21.Subject = _toolBlock; // 绑定到编辑控件
        }));
    }
    catch (Exception ex)
    {
        this.Invoke(new Action(() => MessageBox.Show($"加载ToolBlock失败:{ex.Message}")));
    }
}
2. 选择图片文件夹(按钮点击)

csharp

运行

复制代码
private void btnSelectImages_Click(object sender, EventArgs e)
{
    _imagePaths.Clear();
    using (FolderBrowserDialog fbd = new FolderBrowserDialog())
    {
        if (fbd.ShowDialog() != DialogResult.OK) return;

        // 获取文件夹内所有图片(可过滤格式:*.png|*.jpg|*.bmp)
        _imagePaths.AddRange(Directory.GetFiles(fbd.SelectedPath, "*.*", SearchOption.TopDirectoryOnly)
                             .Where(path => path.EndsWith(".png") || path.EndsWith(".jpg") || path.EndsWith(".bmp")));

        if (_imagePaths.Count == 0)
        {
            MessageBox.Show("文件夹内无图片!");
            return;
        }

        // 加载首张图片并执行ToolBlock
        RunToolBlockWithImage(_imagePaths[0]);
    }
}
3. 执行 ToolBlock 并显示结果(通用方法,可复用)

csharp

运行

复制代码
/// <summary>
/// 通用方法:传入图片路径,执行ToolBlock并显示结果
/// </summary>
/// <param name="imgPath">图片路径</param>
private void RunToolBlockWithImage(string imgPath)
{
    if (_toolBlock == null)
    {
        MessageBox.Show("ToolBlock未加载!");
        return;
    }

    // 1. 本地图片转VisionPro图像对象
    using (Bitmap bmp = new Bitmap(imgPath))
    {
        CogImage24PlanarColor cogImg = new CogImage24PlanarColor(bmp);
        
        // 2. 给ToolBlock输入参数赋值(OutputImage为工具块内定义的输入名)
        _toolBlock.Inputs["OutputImage"].Value = cogImg;
        
        // 3. 执行ToolBlock
        _toolBlock.Run();
        
        // 4. 绑定运行记录到显示控件
        cogRecordDisplay1.Record = _toolBlock.CreateLastRunRecord().SubRecords[0];
        cogRecordDisplay1.Fit(); // 适配显示区域
    }
}
4. 切换图片 + OK/NG 分类保存(运行按钮)

csharp

运行

复制代码
private void btnRunNext_Click(object sender, EventArgs e)
{
    if (_imagePaths.Count == 0)
    {
        MessageBox.Show("无图片,请先选择图片文件夹!");
        return;
    }

    // 切换图片索引(循环)
    _currentImgIndex++;
    if (_currentImgIndex >= _imagePaths.Count) _currentImgIndex = 0;

    // 执行ToolBlock并显示
    string currentImgPath = _imagePaths[_currentImgIndex];
    RunToolBlockWithImage(currentImgPath);

    // 5. 获取ToolBlock输出参数(Result_Mean为工具块内定义的输出名)
    double resultValue = Convert.ToDouble(_toolBlock.Outputs["Result_Mean"].Value);
    this.Text = $"当前结果:{resultValue}";

    // 6. OK/NG分类保存图片(避坑:文件名去掉非法字符)
    string okDir = Path.Combine(Directory.GetCurrentDirectory(), "OK");
    string ngDir = Path.Combine(Directory.GetCurrentDirectory(), "NG");
    CreateDirectoryIfNotExists(okDir);
    CreateDirectoryIfNotExists(ngDir);

    // 生成唯一文件名(避免--等非法字符)
    string fileName = DateTime.Now.ToString("yyyy-MM-dd-HH-mm-ss") + ".png";
    string savePath = resultValue > 100 ? Path.Combine(okDir, fileName) : Path.Combine(ngDir, fileName);

    // 从显示控件导出图片并保存
    using (Bitmap saveBmp = (Bitmap)cogRecordDisplay1.CreateContentBitmap(CogDisplayContentBitmapConstants.Image))
    {
        saveBmp.Save(savePath);
    }
}

// 通用方法:创建目录(不存在则创建)
private void CreateDirectoryIfNotExists(string dirPath)
{
    if (!Directory.Exists(dirPath))
    {
        Directory.CreateDirectory(dirPath);
    }
}
5. 保存 ToolBlock 到 vpp 文件(保存按钮)

csharp

运行

复制代码
private void btnSaveToolBlock_Click(object sender, EventArgs e)
{
    if (_toolBlock == null)
    {
        MessageBox.Show("ToolBlock未加载,无法保存!");
        return;
    }

    string savePath = @"D:\C#\绘制与保存\加载工具块\bin\Debug\tb.vpp";
    CogSerializer.SaveObjectToFile(_toolBlock, savePath);
    MessageBox.Show("ToolBlock保存成功!");
}

三、核心注意事项(避坑清单)

  1. 跨线程操作 :加载 ToolBlock 必须用this.Invoke,否则会触发 WinForms 跨线程访问控件异常;
  2. 路径与命名 :文件名不能包含:、--、/等非法字符,推荐用Path.Combine拼接路径;
  3. 资源释放 :Bitmap 对象必须用using包裹或手动Dispose,避免内存泄漏;
  4. 参数名匹配:Inputs/Outputs 的参数名必须和 ToolBlock 内定义的完全一致(大小写敏感);
  5. 异常处理:加载 vpp、读取图片时建议加 try-catch,避免程序崩溃。
相关推荐
samble10 小时前
从零搭建灌装监控系统(十七):LiveCharts 实时温度曲线
c#·wpf·mvvm·modbus·工业控制
淡海水18 小时前
02-07-原理篇-GC暂停时间的本质
开发语言·unity·c#·gc·暂停时间
小羊没烦恼!20 小时前
OS X 上使用.NET开发应用程序
开发语言·前端·数据库·人工智能·c#·策略模式
Behavior21 小时前
Unity 7.0 Alpha 拆解:编辑器干掉 Mono 换 CoreCLR
c#·unity3d·游戏开发
淡海水1 天前
02-06-原理篇-增量式GC与并发GC
算法·unity·c#·并发·gc·增量
Vertira1 天前
C# 函数封装成 DLL,
开发语言·c#
浅尝辄止;1 天前
设计模式在HIS/LIS医疗系统中的完整实践指南(C#版)
开发语言·设计模式·c#
kimloner1 天前
开源一个 376KB 的 Windows 桌面小工具:便签 + 截图标注 + OCR + 待办提醒(C# / WinForms)
windows·开源·c#·ocr·winforms
阿松爱学习1 天前
【Unity开发】Aspose.PDF的使用
unity·pdf·c#
半亩码田1 天前
C#转Python第4.8篇:正则表达式:Python re 模块 vs C# System.Text.RegularExpressions
python·正则表达式·c#