c#程序源码,相机图片展示,工艺图片,打包压缩,全屏显示,缺陷图片,类别查询等
最近在搞工业检测系统,发现几个实用功能点特别有意思。就拿相机图片实时展示来说,用C#的PictureBox控件就能快速实现。不过这里有个坑要注意------直接操作Image对象可能会导致内存泄漏,得用双缓冲机制:
csharp
// 工业相机回调函数里这么处理
void OnFrameReceived(byte[] buffer)
{
using (var ms = new MemoryStream(buffer))
{
var newImage = Image.FromStream(ms);
if (pictureBox1.InvokeRequired)
{
pictureBox1.BeginInvoke((MethodInvoker)(() =>
{
var old = pictureBox1.Image;
pictureBox1.Image = (Image)newImage.Clone();
old?.Dispose();
}));
}
}
}
实测发现用BeginInvoke代替Invoke能减少界面卡顿,特别是当帧率超过30fps的时候。记得要克隆新图像再赋值,否则可能遇到跨线程资源访问问题。

搞定了全屏显示才发现WPF才是真香,WinForm的全屏方案得自己处理任务栏遮挡。这段代码实测有效:
csharp
this.FormBorderStyle = FormBorderStyle.None;
this.WindowState = FormWindowState.Maximized;
// 隐藏鼠标光标
Cursor.Hide();
不过要注意多显示器环境,得用Screen.AllScreens遍历显示器信息。有次现场调试就因为没处理这个,全屏显示跑到工程师的笔记本主屏去了,产线显示器反而黑着...
工艺图纸的打包压缩用System.IO.Compression挺省事,但要注意文件锁定问题。见过有人直接用File.Copy导致产线图片被占用的情况:
csharp
using (var archive = ZipFile.Open(zipPath, ZipArchiveMode.Create))
{
foreach (var tifFile in Directory.GetFiles(scanPath,"*.tif"))
{
// 用FileStream明确控制文件访问方式
using (var fs = new FileStream(tifFile, FileMode.Open, FileAccess.Read))
{
var entry = archive.CreateEntry(Path.GetFileName(tifFile));
using (var entryStream = entry.Open())
{
fs.CopyTo(entryStream);
}
}
}
}
缺陷分类查询这块,EF Core的延迟加载在产线环境容易翻车。后来改用原生SQL查询,速度直接起飞:
csharp
var defectList = new List<DefectItem>();
using (var conn = new SqlConnection(_config.GetConnectionString("AOI")))
{
var sql = @"SELECT TOP 20 defect_code, defect_name
FROM t_defect_lib
WHERE category = @cat
ORDER BY occur_count DESC";
defectList = conn.Query<DefectItem>(sql, new { cat = currentCategory }).ToList();
}
// Dapper的Query方法比EF快3倍左右
最后说说图片比对,用OpenCVSharp的模板匹配不如直接上EmguCV。有个取巧的办法------把标准图和检测图都转成灰度图再比对,内存占用能少三分之一:
csharp
using (var template = new Image<Gray, byte>(standardPath))
using (var source = new Image<Gray, byte>(testPath))
{
using (var result = source.MatchTemplate(template, TemplateMatchingType.CcoeffNormed))
{
result.MinMax(out _, out double[] maxValues, out _, out _);
return maxValues[0] > 0.95 ? "OK" : "NG";
}
}
这些模块组合起来,再配上RabbitMQ做消息队列,一个基础版的工业检测系统就搭起来了。实测在i5-8500的工控机上跑,处理500ms的超时控制完全没问题。不过千万记得要把所有图像处理放在单独的工作线程,不然界面分分钟卡成PPT------别问我怎么知道的。
