工具块与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,避免程序崩溃。
相关推荐
游乐码10 小时前
c#万物之父装箱拆箱
开发语言·c#
GIS程序猿10 小时前
批量出图工具,如何使用C#实现动态文本
开发语言·arcgis·c#·arcgis插件·gis二次开发
量子物理学10 小时前
三、C#高级进阶语法——特性(Attribute)
java·算法·c#
量子物理学10 小时前
四、C#高级进阶语法——委托(Delegate)
开发语言·c#
bepeater123412 小时前
Laravel9.X核心特性全面解析
c语言·c++·c#·php
lpfasd12313 小时前
Markdown 导出 Word 文档技术方案
开发语言·c#·word
m5655bj14 小时前
通过 C# 将 PPT 文档转换为 HTML 格式
c#·html·powerpoint
未来之窗软件服务14 小时前
AI人工智能(十五)C# AI的智障行为http服务—东方仙盟练气期
开发语言·http·c#
缺点内向14 小时前
C#中如何创建目录(TOC):使用Spire.Doc for .NET实现Word TOC自动化
c#·自动化·word·.net
2301_8169978814 小时前
Word 创建打开与保存文档
c#·word·xhtml