using System; using System.Drawing; using System.Runtime.InteropServices; using Cognex.VisionPro; using TeamAAS.Camera.Images; namespace Plugins.Vpp.Converters { /// /// GenImage ↔ VisionPro ICogImage 双向转换器。 /// 用于 Plugins.Vpp 中把通用图像类转换为 VisionPro 图像类型供 ToolBlock/AcqFifo 使用。 /// public static class GenImageConverter { /// /// GenImage → ICogImage(供 VisionPro 工具使用)。 /// Grey8 → CogImage8Grey,彩色 → CogImage24PlanarColor。 /// public static ICogImage ToCogImage(GenImage img) { if (img == null) return null; try { if (img.Format == PixelType.Grey8) { return Grey8ToCogImage(img); } // 彩色或 Grey16 → 通过 Bitmap 中转 using (var bmp = img.ToBitmap()) { if (img.Format == PixelType.Grey8 || img.Format == PixelType.Grey16) { var grey = new CogImage8Grey(bmp); return grey; } var color = new CogImage24PlanarColor(bmp); return color; } } catch { return null; } } /// /// ICogImage → GenImage(从 VisionPro 采集结果转换为通用图像)。 /// public static GenImage FromCogImage(ICogImage cogImage) { if (cogImage == null) return null; try { using (var bmp = cogImage.ToBitmap()) { return GenImage.FromBitmap(bmp); } } catch { return null; } } private static ICogImage Grey8ToCogImage(GenImage img) { // 通过 Bitmap 中转:CogImage8Grey(Bitmap) 会把像素【拷贝】进 VisionPro 自有内存。 // 历史教训:直接 CogImage8Root.Initialize 包裹 GenImage.Data 的托管数组 + 立即解除固定, // GC 挪动/回收数组后 CogImage 读到悬空指针 → 显示全黑、工具结果恒为 0(本机实测复现)。 // (CogImage8Grey 没有 SetRootCopier/Freeze 可用,Bitmap 路径是确定正确的拷贝方式。) using (var bmp = img.ToBitmap()) { return new CogImage8Grey(bmp); } } } }