工具块与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,避免程序崩溃。
相关推荐
c#上位机2 小时前
wpf之行为
c#·wpf
星夜泊客2 小时前
C# 基础:为什么类可以在静态方法中创建自己的实例?
开发语言·经验分享·笔记·unity·c#·游戏引擎
kylezhao20194 小时前
深入浅出地理解 C# WPF 中的属性
hadoop·c#·wpf
多多*4 小时前
2月3日面试题整理 字节跳动后端开发相关
android·java·开发语言·网络·jvm·adb·c#
一念春风5 小时前
C# 通用工具类代码
c#
海盗12346 小时前
WPF上位机组件开发-设备状态运行图基础版
开发语言·c#·wpf
浮生如梦_7 小时前
C# 窗体工厂类 - 简单工厂模式演示案例
计算机视觉·c#·视觉检测·简单工厂模式
两千次7 小时前
web主从站
windows·c#
lihongli0007 小时前
四连杆机构驱动角与被驱动连杆角度关系
c#