不推荐在新项目中使用AForge.NET,因其自2019年停止维护、不支持.NET Core/5+及跨平台(Linux/macOS),且存在兼容性与稳定性问题;应优先选用ImageSharp或OpenCvSharp。
AForge.NET 已于 2019 年正式停止维护,AForge.Imaging 模块缺乏 .NET Core / .NET 5+ 兼容性,且多数类型(如 Bitmap 依赖 GDI+)在 Linux/macOS 上无法运行。NuGet 包 AForge 最后更新是 2018 年,引用 System.Drawing.Common 时容易触发 PlatformNotSupportedException。如果你正在开发跨平台应用或需要长期维护,应直接转向 ImageSharp 或 OpenCvSharp。
它不支持直接读取 PNG 透明通道或 WebP,只认 BMP/JPG/GIF(靠 System.Drawing.Bitmap 底层)。常见错误是传入路径含中文或空格,导致 NullReferenceException —— 实际是 Bitmap 构造失败后返回 null,而 AForge 未做校验。
new Bitmap(@"C:\img.jpg")
加载,再转成 AForge.Imaging.UnmanagedImage
PictureBox.Image = bitmap,要先调用 bitmap.Clone() 防止资源被 AForge 锁住Bitmap.ToManagedImage(),会抛 InvalidOperationException
var bmp = new Bitmap(@"C:\test.jpg"); var unmanaged = UnmanagedImage.FromManagedImage(bmp); // 处理完记得释放 unmanaged.Dispose(); bmp.Dispose();
AForge 的滤镜链(FiltersSequence)默认复用输入内存,若多次调用同一实例,可能因前一步释放了像素内存而导致后续步骤崩溃。最稳妥方式是每次新建滤镜对象。
Grayscale.CommonAlgorithms.BT709 是推荐的灰度算法,比 BT601 更符合人眼感知OtsuThreshold 比固定阈值更鲁棒,但要求输入已是灰度图(否则结果不可控)Apply() 方法返回新图像,原图不变;若想原地修改,得用 ApplyInPlace(),但仅部分滤镜支持var grayFilter = new Grayscale(CommonAlgorithms.BT709); var grayImage = grayFilter.Apply(unmanaged); var otsu = new OtsuThreshold(); var binaryImage = otsu.Apply(grayImage); // 注意:这里必须是灰度图
把 AForge.Imaging.Filters 对应功能映射到 ImageSharp 时,注意坐标系差异:AForge 的 Rectangle 参数是 (x, y, width, height),而 ImageSharp 的 Crop() 是 (x, y, width, height) —— 表面一样,但 AForge 的 y 在某些滤镜里会被反向解释(尤其旋转后),实际行为需实测。
image.Mutate(x => x.Grayscale())
image.Mutate(x => x.Threshold(128)),或自定义 ThresholdProcessor
GaussianBlur 默认 kernel=3,ImageSharp 要显式设 new GaussianBlurProcessor(3f)
真正难迁的是运动检测(MotionDetector)和霍夫变换(HoughLineTransformation)—— 这些在 ImageSharp 中没有等价实现,得换用 OpenCvSharp,且 API 完全不同。