From 1f2fa3f54d4a7b5a2f601c4c947a06476342e3bd Mon Sep 17 00:00:00 2001
From: patrick.xu <patrick.xu@broconcentric.com>
Date: 星期五, 22 一月 2021 09:23:06 +0800
Subject: [PATCH] 1. gocator驱动将system.stop移到system.ReceiveData之后 2. 修改测量完成后状态切换逻辑,避免安全光线等干扰 3. 添加设备异常输出日志记录 4. 产品结果输出时做硬盘文件记录

---
 src/Bro.Common.Device/DeviceBase/CameraBase.cs |  245 +++++++++++++++++++++++++++++++++++++------------
 1 files changed, 185 insertions(+), 60 deletions(-)

diff --git a/src/Bro.Common.Device/DeviceBase/CameraBase.cs b/src/Bro.Common.Device/DeviceBase/CameraBase.cs
index c8a80ba..ca7afb3 100644
--- a/src/Bro.Common.Device/DeviceBase/CameraBase.cs
+++ b/src/Bro.Common.Device/DeviceBase/CameraBase.cs
@@ -13,6 +13,7 @@
 using System.Drawing.Imaging;
 using System.IO;
 using System.Linq;
+using System.Runtime.InteropServices;
 using System.Threading;
 using System.Threading.Tasks;
 using static Bro.Common.Helper.EnumHelper;
@@ -70,7 +71,7 @@
         #endregion
 
         #region 鍥剧墖鐩稿叧
-        public event Action<CameraBase, Bitmap, string> OnImageUpdated;
+        public Action<CameraBase, Bitmap, string> OnImageUpdated;
 
         public Action<CameraBase, HObject, string> OnHImageOutput { get; set; }
         public event Action OnCameraOpModeChanged;
@@ -140,22 +141,21 @@
         /// </summary>
         /// <returns></returns>
         public abstract void Snapshot();
+        public abstract IImageSet Snapshot(IOperationConfig config);
 
-        public virtual ImageSet Snapshot(IOperationConfig config)
+        public virtual void InitialImageSet(IImageSet set, ImageSaveOption saveOption)
         {
             OpMode = CameraOpMode.SingleSnapShot;
 
-            ImageSet set = new ImageSet();
-            CameraOprerationConfigBase opConfig = config as CameraOprerationConfigBase;
-            set.ImageSaveOption.DataFrom(opConfig.ImageSaveOption);
+            //CameraOprerationConfigBase opConfig = config as CameraOprerationConfigBase;
+            set.ImageSaveOption.DataFrom(saveOption);
 
             set.IsOriginSaved = !set.ImageSaveOption.IsSaveOriginImage;
             set.IsFitSaved = !set.ImageSaveOption.IsSaveFitImage;
-            set.IsAddtionalSaved = !string.IsNullOrWhiteSpace(set.ImageSaveOption.AddtionalSaveType);
-            set.OnImageSetTimeout += ImageSet_OnImageSetTimeout;
-            _imageSetList.Add(set);
+            set.IsAddtionalSaved = string.IsNullOrWhiteSpace(set.ImageSaveOption.AddtionalSaveType);
+            //set.OnImageSetTimeout += ImageSet_OnImageSetTimeout;
 
-            return set;
+            _imageSetList[set.Id] = set;
         }
 
         /// <summary>
@@ -171,19 +171,20 @@
         #endregion
 
         #region 鍩哄厓澶勭悊
-        public event Action<CameraBase, List<IShapeElement>, string> OnElementsUpdated;
+        public Action<CameraBase, List<IShapeElement>, string> OnElementsUpdated;
         #endregion
 
         #region 鍥剧墖缂撳瓨/淇濆瓨
-        readonly ConcurrentBag<ImageSet> _imageSetList = new ConcurrentBag<ImageSet>();
+        //public readonly ConcurrentBag<IImageSet> _imageSetList = new ConcurrentBag<IImageSet>();
+        protected Dictionary<string, IImageSet> _imageSetList = new Dictionary<string, IImageSet>();
 
-        public void NewImageSet(ImageSet set)
+        public void NewImageSet(IImageSet set)
         {
             set.IsOriginSaved = !set.ImageSaveOption.IsSaveOriginImage;
             set.IsFitSaved = !set.ImageSaveOption.IsSaveFitImage;
-            set.IsAddtionalSaved = !string.IsNullOrWhiteSpace(set.ImageSaveOption.AddtionalSaveType);
-            set.OnImageSetTimeout += ImageSet_OnImageSetTimeout;
-            _imageSetList.Add(set);
+            set.IsAddtionalSaved = string.IsNullOrWhiteSpace(set.ImageSaveOption.AddtionalSaveType);
+            //set.OnImageSetTimeout += ImageSet_OnImageSetTimeout;
+            _imageSetList[set.Id] = set;
         }
 
         //public virtual async void UpdateFitElements(List<IShapeElement> eleList, string imgSetId)
@@ -196,12 +197,12 @@
 
         public virtual async void SaveOriginImage(Bitmap map, Bitmap showImage, string imgSetId)
         {
-            Task.Run(() =>
+            await Task.Run(() =>
             {
                 OnImageUpdated?.Invoke(this, showImage, imgSetId);
             });
 
-            ImageSet set = _imageSetList.FirstOrDefault(u => u.Id == imgSetId);
+            IImageSet set = _imageSetList[imgSetId];
 
             if (set == null)
                 return;
@@ -224,10 +225,6 @@
                         {
                             LogAsync(DateTime.Now, $"{set.Id}鍘熷浘淇濆瓨澶辫触", ex.GetExceptionMessage());
                         }
-                        //finally
-                        //{
-                        //    set.IsOriginSaved = true;
-                        //}
                     }
                     set.IsOriginSaved = true;
                     ClearImageSet(set);
@@ -240,7 +237,7 @@
             if (eleList.Count > 0)
                 OnElementsUpdated?.BeginInvoke(this, eleList, imgSetId, null, null);
 
-            ImageSet set = _imageSetList.FirstOrDefault(u => u.Id == imgSetId);
+            IImageSet set = _imageSetList[imgSetId];
             if (set == null)
                 return;
 
@@ -304,7 +301,7 @@
         {
             await Task.Run(() =>
             {
-                ImageSet set = _imageSetList.FirstOrDefault(u => u.Id == imgSetId);
+                IImageSet set = _imageSetList[imgSetId];
                 if (set == null)
                     return;
 
@@ -340,7 +337,7 @@
             });
         }
 
-        private string CheckImageDirectory(string subDir, string prefix)
+        protected string CheckImageDirectory(string subDir, string prefix)
         {
             if (string.IsNullOrWhiteSpace(subDir))
             {
@@ -362,7 +359,7 @@
             return imgDir;
         }
 
-        private void SaveImageByNameAndType(Bitmap map, string imageName, ImageFormat imgFormat, string imageDir)
+        protected void SaveImageByNameAndType(Bitmap map, string imageName, ImageFormat imgFormat, string imageDir)
         {
             string filePath = Path.Combine(imageDir, $"{imageName}.{imgFormat.ToString().ToLower()}");
             map.Save(filePath, imgFormat);
@@ -370,7 +367,7 @@
 
         //private Timer clearImageSetTimer = null;
 
-        public void ClearImageSet(ImageSet set)
+        public virtual void ClearImageSet(IImageSet set)
         {
             try
             {
@@ -379,9 +376,10 @@
                 //    && (!set.ImageSaveOption.IsSaveNGImage || set.IsNGSaved))
                 if (set.IsOriginSaved && set.IsFitSaved && set.IsAddtionalSaved)
                 {
-                    _imageSetList.TryTake(out set);
                     set.Dispose();
-                    //LogAsync(DateTime.Now, $"绉婚櫎鍥剧墖淇℃伅锛屽綋鍓嶇紦瀛樻暟閲忥細{_imageSetList.Count}", "");
+
+                    _imageSetList.Remove(set.Id);
+                    LogAsync(DateTime.Now, $"绉婚櫎鍥剧墖淇℃伅锛屽綋鍓嶇紦瀛樻暟閲忥細{_imageSetList.Count}", "");
                 }
                 //bool flag = false;
 
@@ -401,7 +399,7 @@
 
         public void ClearImageSet(string imgSetId)
         {
-            ImageSet set = _imageSetList.First(u => u.Id == imgSetId);
+            IImageSet set = _imageSetList[imgSetId];
             if (set != null)
                 ClearImageSet(set);
         }
@@ -483,6 +481,110 @@
 
         private System.Threading.Timer clearImageTimer = null;
         #endregion
+
+        #region 鍥剧墖杞崲
+        [DllImport("kernel32.dll", EntryPoint = "CopyMemory", SetLastError = false)]
+        public static extern void CopyMemory(IntPtr dest, IntPtr src, long count);
+
+        protected async void Generate8GrayImageByPointer(int width, int height, IntPtr dataPtr, string imgSetId)
+        {
+            await Task.Run(() =>
+            {
+                //************************Mono8 杞� Bitmap*******************************
+                Bitmap bmp = new Bitmap(width, height, PixelFormat.Format8bppIndexed);
+                Bitmap showImage = new Bitmap(width, height, PixelFormat.Format8bppIndexed);
+
+                ColorPalette cp = bmp.Palette;
+                for (int i = 0; i < 256; i++)
+                {
+                    cp.Entries[i] = Color.FromArgb(i, i, i);
+                }
+                bmp.Palette = cp;
+
+                ColorPalette cp1 = showImage.Palette;
+                for (int i = 0; i < 256; i++)
+                {
+                    cp1.Entries[i] = Color.FromArgb(i, i, i);
+                }
+                showImage.Palette = cp1;
+
+                long[] ptr = new long[3];
+                Rectangle rect = new Rectangle(0, 0, width, height);
+                BitmapData bitmapData = bmp.LockBits(rect, ImageLockMode.WriteOnly, PixelFormat.Format8bppIndexed);
+                BitmapData showImageData = showImage.LockBits(rect, ImageLockMode.WriteOnly, PixelFormat.Format8bppIndexed);
+                int PixelSize = Bitmap.GetPixelFormatSize(bitmapData.PixelFormat) / 8;
+
+                if (width % 4 == 0)
+                {
+                    CopyMemory(bitmapData.Scan0, dataPtr, width * height * PixelSize);
+                    CopyMemory(showImageData.Scan0, dataPtr, width * height * PixelSize);
+                }
+                else
+                {
+                    ptr[0] = bitmapData.Scan0.ToInt64();
+                    ptr[1] = showImageData.Scan0.ToInt64();
+                    ptr[2] = (long)dataPtr;
+                    for (int i = 0; i < height - 1; i++)
+                    {
+                        ptr[2] += width;
+
+                        CopyMemory((IntPtr)ptr[0], (IntPtr)ptr[2], width * PixelSize);
+                        CopyMemory((IntPtr)ptr[1], (IntPtr)ptr[2], width * PixelSize);
+                        ptr[0] += bitmapData.Stride;
+                        ptr[1] += showImageData.Stride;
+                    }
+                }
+                bmp.UnlockBits(bitmapData);
+                showImage.UnlockBits(showImageData);
+
+                SaveOriginImage(bmp, showImage, imgSetId);
+            });
+        }
+
+        protected async Task Generate16GrayImageByPointer(int width, int height, IntPtr dataPtr, string imgSetId)
+        {
+            await Task.Run(() =>
+            {
+                //Thread.Sleep(1000);
+                int widthIn4 = (int)Math.Ceiling(width / 4.0) * 4;
+
+                Bitmap bmp = new Bitmap(widthIn4, height, PixelFormat.Format48bppRgb);
+                Bitmap showImage = new Bitmap(widthIn4, height, PixelFormat.Format48bppRgb);
+
+                Rectangle rect = new Rectangle(0, 0, widthIn4, height);
+                BitmapData bitmapData = bmp.LockBits(rect, ImageLockMode.WriteOnly, PixelFormat.Format48bppRgb);
+                BitmapData showImageData = showImage.LockBits(rect, ImageLockMode.WriteOnly, PixelFormat.Format48bppRgb);
+                unsafe
+                {
+                    byte* data = (byte*)dataPtr;
+                    byte* bitmapBuffer = (byte*)bitmapData.Scan0;
+                    byte* showBitmapBuffer = (byte*)showImageData.Scan0;
+
+                    //Parallel.For(0, height, i =>
+                    //      {
+                    //          Parallel.For(0, width, j =>
+                    //            {
+                    //                showBitmapBuffer[(i * widthIn4 + j) * 6] = bitmapBuffer[(i * widthIn4 + j) * 6] = data[(i * width + j) * 2];
+                    //                showBitmapBuffer[(i * widthIn4 + j) * 6 + 1] = bitmapBuffer[(i * widthIn4 + j) * 6 + 1] = data[(i * width + j) * 2 + 1];
+                    //            });
+                    //      });
+
+                    Parallel.For(0, width * height, i =>
+                      {
+                          int index = (i + 1) % width + widthIn4 * ((i + 1) / width) - 1;
+
+                          showBitmapBuffer[index * 6] = bitmapBuffer[index * 6] = data[i * 2];
+                          showBitmapBuffer[index * 6 + 1] = bitmapBuffer[index * 6 + 1] = data[i * 2 + 1];
+                      });
+                }
+
+                bmp.UnlockBits(bitmapData);
+                showImage.UnlockBits(showImageData);
+
+                SaveOriginImage(bmp, showImage, imgSetId);
+            });
+        }
+        #endregion
     }
 
     #region Config
@@ -496,7 +598,7 @@
         [Category("鍙栧儚閰嶇疆")]
         [Description("鏇濆厜")]
         [DisplayName("鏇濆厜")]
-        public float Exposure
+        public virtual float Exposure
         {
             get => exposure;
             set
@@ -515,17 +617,17 @@
         [Category("鍙栧儚閰嶇疆")]
         [Description("澧炵泭")]
         [DisplayName("澧炵泭")]
-        public float Gain { get; set; }
+        public virtual float Gain { get; set; }
 
         [Category("鍙栧儚閰嶇疆")]
         [Description("鏇濆厜淇敼鍚庣瓑寰呮椂闂达紝鍗曚綅ms銆傞拡瀵归儴鍒嗗満鏅‘淇濇洕鍏変慨鏀瑰強鏃剁敓鏁堛��")]
         [DisplayName("鏇濆厜绛夊緟")]
-        public int ExposureWaitTime { get; set; }
+        public virtual int ExposureWaitTime { get; set; }
 
         [Category("鍙栧儚閰嶇疆")]
         [Description("鎷嶆憚鍚庢洕鍏夊�笺�傚彲鍦ㄤ竴娆℃媿鎽勫悗灏嗘洕鍏変慨鏀逛负涓嬫鎷嶆憚鐨勬洕鍏夊�硷紝鑺傜害鏇濆厜鐢熸晥鏃堕棿銆�")]
         [DisplayName("鎷嶆憚鍚庢洕鍏�")]
-        public float ExposureAfterSnap { get; set; }
+        public virtual float ExposureAfterSnap { get; set; }
 
         [Category("绠楁硶閰嶇疆")]
         [Description("绠楁硶璺緞")]
@@ -581,42 +683,42 @@
         [Category("鐩告満璁剧疆")]
         [Description("鐩告満IP鍦板潃")]
         [DisplayName("鐩告満IP鍦板潃")]
-        public string CameraIP { get; set; }
+        public virtual string CameraIP { get; set; }
 
         [Category("鐩告満璁剧疆")]
         [Description("涓婁綅鏈篒P鍦板潃")]
         [DisplayName("涓婁綅鏈篒P鍦板潃")]
-        public string ComputerIP { get; set; }
+        public virtual string ComputerIP { get; set; }
 
         [Category("淇濆瓨璁剧疆")]
         [Description("鍥剧墖淇濆瓨鐩綍")]
         [DisplayName("鍥剧墖淇濆瓨鐩綍")]
         [Editor(typeof(FoldDialogEditor), typeof(UITypeEditor))]
-        public string ImgDirectory { get; set; } = @"../Images";
+        public virtual string ImgDirectory { get; set; } = @"../Images";
 
         [Category("淇濆瓨璁剧疆")]
         [Description("鍥剧墖淇濆瓨澶╂暟")]
         [DisplayName("鍥剧墖淇濆瓨澶╂暟")]
-        public int SaveImageDayLimit { get; set; } = 0;
+        public virtual int SaveImageDayLimit { get; set; } = 0;
 
         [Category("淇濆瓨璁剧疆")]
         [Description("鍥剧墖淇濆瓨榛樿閰嶇疆锛屼富瑕佺敤浜庣‖瑙﹀彂绛夋病鏈夋槑纭搷浣滈厤缃鏄庣殑鍥剧墖淇濆瓨")]
         [DisplayName("鍥剧墖淇濆瓨榛樿閰嶇疆")]
         [TypeConverter(typeof(ComplexObjectConvert))]
         [Editor(typeof(PropertyObjectEditor), typeof(UITypeEditor))]
-        public ImageSaveOption ImageSaveOption { get; set; } = new ImageSaveOption();
+        public virtual ImageSaveOption ImageSaveOption { get; set; } = new ImageSaveOption();
 
         [Category("鎷嶆憚璁剧疆")]
         [Description("榛樿鏇濆厜鍊硷紝鐩告満寮�鍚悗灏辫缃鏇濆厜鍊�")]
         [DisplayName("榛樿鏇濆厜鍊�")]
-        public float DefaultExposure { get; set; }
+        public virtual float DefaultExposure { get; set; }
     }
     #endregion
 
     #region Converter & Editor
     public class HalconSerialNumConverter : ComboBoxItemTypeConvert
     {
-        public override Hashtable GetConvertHash()
+        public override Hashtable GetConvertHash(ITypeDescriptorContext context)
         {
             Hashtable table = new Hashtable();
             HTuple deviceList = null;
@@ -654,7 +756,7 @@
 
     public class CameraDeviceConverter : ComboBoxItemTypeConvert
     {
-        public override Hashtable GetConvertHash()
+        public override Hashtable GetConvertHash(ITypeDescriptorContext context)
         {
             Hashtable table = new Hashtable();
             using (var scope = GlobalVar.Container.BeginLifetimeScope())
@@ -733,7 +835,29 @@
         }
     }
 
-    public class ImageSet : IDisposable
+    public interface IImageSet:IDisposable
+    {
+        DateTime InitialTime { get; set; }
+        string Id { get; }
+        HImage HImage { get; set; }
+        Bitmap Image { get; set; }
+
+        object SaveLock { get; set; }
+
+        ImageSaveOption ImageSaveOption { get; set; }
+        bool IsOriginSaved { get; set; }
+        bool IsFitSaved { get; set; }
+        bool IsAddtionalSaved { get; set; }
+
+        //event Action<ImageSet> OnImageSetTimeout;
+
+        /// <summary>
+        /// 搴忓垪鍖栨搷浣滅殑鍥惧儚淇℃伅
+        /// </summary>
+        string ImageData { get; set; }
+    }
+
+    public class ImageSet : IImageSet
     {
         public DateTime InitialTime { get; set; } = DateTime.Now;
 
@@ -768,31 +892,32 @@
         //public bool IsInvokeSaveNG { get; set; } = false;
         public bool IsAddtionalSaved { get; set; } = false;
 
-        public object SaveLock = new object();
+        public object SaveLock { get; set; } = new object();
 
-        public event Action<ImageSet> OnImageSetTimeout;
-        private Timer autoDisposeTimer = null;
+        public virtual string ImageData { get; set; }
 
-        private void OnAutoDispose(object state)
+        //public event Action<ImageSet> OnImageSetTimeout;
+        //private Timer autoDisposeTimer = null;
+
+        public void Dispose(object state)
         {
-            OnImageSetTimeout?.Invoke(this);
+            //OnImageSetTimeout?.Invoke(this);
+
+            //autoDisposeTimer.Change(-1, -1);
+            //autoDisposeTimer.Dispose();
+
+            Image?.Dispose();
+            Image = null;
+        }
+
+        public virtual void Dispose()
+        {
+            Dispose(null);
         }
 
         public ImageSet()
         {
-            autoDisposeTimer = new Timer(OnAutoDispose, null, -1, 10 * 1000);
-        }
-
-        public void Dispose()
-        {
-            autoDisposeTimer.Change(-1, -1);
-            autoDisposeTimer.Dispose();
-
-            Image?.Dispose();
-            Image = null;
-
-            HImage?.Dispose();
-            HImage = null;
+            //autoDisposeTimer = new Timer(Dispose, null, 10 * 1000, -1);
         }
         #endregion
     }

--
Gitblit v1.8.0