src/Bro.Common.Device/DeviceBase/CameraBase.cs | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/Bro.Device.Gocator/Bro.Device.Gocator.csproj | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/Bro.Device.Gocator/GocatorConfig.cs | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/Bro.Device.Gocator/GocatorDriver.cs | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/Bro.Device.HikCamera/HikCameraDriver.cs | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/Bro.UI.Model.Winform/UI/Canvas.cs | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/Bro.UI.Model.Winform/UI/CanvasImage.cs | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 |
src/Bro.Common.Device/DeviceBase/CameraBase.cs
@@ -71,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; @@ -141,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); return set; _imageSetList.Add(set); } /// <summary> @@ -172,13 +171,13 @@ #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>(); public void NewImageSet(ImageSet set) public void NewImageSet(IImageSet set) { set.IsOriginSaved = !set.ImageSaveOption.IsSaveOriginImage; set.IsFitSaved = !set.ImageSaveOption.IsSaveFitImage; @@ -202,7 +201,7 @@ OnImageUpdated?.Invoke(this, showImage, imgSetId); }); ImageSet set = _imageSetList.FirstOrDefault(u => u.Id == imgSetId); IImageSet set = _imageSetList.FirstOrDefault(u => u.Id == imgSetId); if (set == null) return; @@ -225,10 +224,6 @@ { LogAsync(DateTime.Now, $"{set.Id}原图保存失败", ex.GetExceptionMessage()); } //finally //{ // set.IsOriginSaved = true; //} } set.IsOriginSaved = true; ClearImageSet(set); @@ -241,7 +236,7 @@ if (eleList.Count > 0) OnElementsUpdated?.BeginInvoke(this, eleList, imgSetId, null, null); ImageSet set = _imageSetList.FirstOrDefault(u => u.Id == imgSetId); IImageSet set = _imageSetList.FirstOrDefault(u => u.Id == imgSetId); if (set == null) return; @@ -305,7 +300,7 @@ { await Task.Run(() => { ImageSet set = _imageSetList.FirstOrDefault(u => u.Id == imgSetId); IImageSet set = _imageSetList.FirstOrDefault(u => u.Id == imgSetId); if (set == null) return; @@ -341,7 +336,7 @@ }); } private string CheckImageDirectory(string subDir, string prefix) protected string CheckImageDirectory(string subDir, string prefix) { if (string.IsNullOrWhiteSpace(subDir)) { @@ -363,7 +358,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); @@ -371,7 +366,7 @@ //private Timer clearImageSetTimer = null; public void ClearImageSet(ImageSet set) public void ClearImageSet(IImageSet set) { try { @@ -402,7 +397,7 @@ public void ClearImageSet(string imgSetId) { ImageSet set = _imageSetList.First(u => u.Id == imgSetId); IImageSet set = _imageSetList.First(u => u.Id == imgSetId); if (set != null) ClearImageSet(set); } @@ -548,6 +543,7 @@ { await Task.Run(() => { Thread.Sleep(1000); int widthIn4 = (int)Math.Ceiling(width / 4.0) * 4; Bitmap bmp = new Bitmap(widthIn4, height, PixelFormat.Format48bppRgb); @@ -575,15 +571,14 @@ { int index = (i + 1) % width + widthIn4 * ((i + 1) / width) - 1; showBitmapBuffer[index * 6] = data[i * 2]; showBitmapBuffer[index * 6 + 1] = data[i * 2 + 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); //showImage.Save(@"D:\1.bmp", ImageFormat.Bmp); SaveOriginImage(bmp, showImage, imgSetId); }); } @@ -838,7 +833,24 @@ } } 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; } public class ImageSet : IImageSet { public DateTime InitialTime { get; set; } = DateTime.Now; @@ -873,7 +885,7 @@ //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; @@ -888,7 +900,7 @@ autoDisposeTimer = new Timer(OnAutoDispose, null, -1, 10 * 1000); } public void Dispose() public virtual void Dispose() { autoDisposeTimer.Change(-1, -1); autoDisposeTimer.Dispose(); src/Bro.Device.Gocator/Bro.Device.Gocator.csproj
@@ -57,11 +57,16 @@ <Reference Include="GoSdkNet"> <HintPath>..\..\libs\gocator\GoSdkNet.dll</HintPath> </Reference> <Reference Include="halcondotnet, Version=12.0.0.0, Culture=neutral, PublicKeyToken=4973bed59ddbf2b8, processorArchitecture=MSIL"> <SpecificVersion>False</SpecificVersion> <HintPath>..\..\libs\halcon12\halcondotnet.dll</HintPath> </Reference> <Reference Include="kApiNet"> <HintPath>..\..\libs\gocator\kApiNet.dll</HintPath> </Reference> <Reference Include="System" /> <Reference Include="System.Core" /> <Reference Include="System.Drawing" /> <Reference Include="System.Windows.Forms" /> <Reference Include="System.Xml.Linq" /> <Reference Include="System.Data.DataSetExtensions" /> src/Bro.Device.Gocator/GocatorConfig.cs
@@ -24,6 +24,7 @@ [Category("计算设置")] [Description("true:计算时使用加速器,false:不使用加速器")] [DefaultValue(false)] [Browsable(false)] public bool IsUseAccelerator { get; set; } = false; [Category("拍摄设置")] @@ -37,10 +38,10 @@ [DefaultValue(1000)] public int SnapshotTimeout { get; set; } = 1000; //[Category("采图模式")] //[Description("是否硬触发模式。true:硬触发;false:软触发")] //[DisplayName("硬触发")] //public bool IsHardwareTrigger { get; set; } = false; [Category("采图模式")] [Description("异步采图时,是否硬触发模式。true:硬触发;false:软触发")] [DisplayName("硬触发")] public bool IsHardwareTrigger { get; set; } = false; [Category("采图模式")] [Description("true:异步/被动采图模式 false:同步/主动采图模式")] src/Bro.Device.Gocator/GocatorDriver.cs
@@ -1,16 +1,21 @@ using Bro.Common.Base; using Bro.Common.Helper; using Bro.Common.Interface; using HalconDotNet; using Lmi3d.GoSdk; using Lmi3d.GoSdk.Messages; using Lmi3d.Zen; using Lmi3d.Zen.Io; using System; using System.Collections.Generic; using System.Drawing; using System.IO; using System.Linq; using System.Runtime.InteropServices; using System.Text; using System.Threading; using System.Threading.Tasks; using static Bro.Common.Helper.EnumHelper; namespace Bro.Device.Gocator { @@ -30,14 +35,23 @@ public override void Snapshot() { GoDataSet dataSet = null; if (IIConfig.IsAsyncMode) { if (!IIConfig.IsHardwareTrigger) { _snapFlag = true; if (!_snapHandle.WaitOne(IIConfig.SnapshotTimeout)) { LogAsync(DateTime.Now, $"{Name}获取图像超时", ""); return; } dataSet = _currentData; } } else { GoDataSet dataSet = null; try { dataSet = system.ReceiveData(IIConfig.SnapshotTimeout); @@ -47,33 +61,23 @@ LogAsync(DateTime.Now, $"{Name}获取图像异常", ex.GetExceptionMessage()); return; } HandleGoData(dataSet); } HandleGoData(dataSet); } private void HandleGoData(GoDataSet dataSet) private void HandleGoData(GoDataSet dataSet, GoImageSet imgSet = null) { if (dataSet == null) { return; } for (UInt32 i = 0; i < dataSet.Count; i++) { GoDataMsg dataObj = (GoDataMsg)dataSet.Get(i); switch (dataObj.MessageType) { //case GoDataMessageType.Stamp: // { // GoStampMsg stampMsg = (GoStampMsg)dataObj; // for (UInt32 j = 0; j < stampMsg.Count; j++) // { // GoStamp stamp = stampMsg.Get(j); // Console.WriteLine("Frame Index = {0}", stamp.FrameIndex); // Console.WriteLine("Time Stamp = {0}", stamp.Timestamp); // Console.WriteLine("Encoder Value = {0}", stamp.Encoder); // } // } // break; case GoDataMessageType.Surface: { GoSurfaceMsg surfaceMsg = (GoSurfaceMsg)dataObj; @@ -82,43 +86,83 @@ long bufferSize = width * height; IntPtr bufferPointer = surfaceMsg.Data; //Console.WriteLine("Whole Part Height Map received:"); //Console.WriteLine(" Buffer width: {0}", width); //Console.WriteLine(" Buffer height: {0}", height); if (imgSet != null) { imgSet.HImage = new HImage(); imgSet.HImage.GenImage1("uint2", (int)width, (int)height, bufferPointer); //short[] ranges = new short[bufferSize]; //Marshal.Copy(bufferPointer, ranges, 0, ranges.Length); imgSet.HImage_2 = new HImage(); imgSet.HImage_2.GenImage1("uint2", (int)width, (int)height, bufferPointer); } Generate16GrayImageByPointer((int)(width / 1), (int)(height / 1), bufferPointer, ""); Generate16GrayImageByPointer((int)width, (int)height, bufferPointer, imgSet?.Id); } break; //case GoDataMessageType.SurfaceIntensity: // { // GoSurfaceIntensityMsg surfaceMsg = (GoSurfaceIntensityMsg)dataObj; // long width = surfaceMsg.Width; // long height = surfaceMsg.Length; // long bufferSize = width * height; // IntPtr bufferPointeri = surfaceMsg.Data; // //Console.WriteLine("Whole Part Intensity Image received:"); // //Console.WriteLine(" Buffer width: {0}", width); // //Console.WriteLine(" Buffer height: {0}", height); // //byte[] ranges = new byte[bufferSize]; // //Marshal.Copy(bufferPointeri, ranges, 0, ranges.Length); // //GenerateGrayImageByPointer((int)width, (int)height, bufferPointeri, ""); // } // break; } } } public override ImageSet Snapshot(IOperationConfig config) public override IImageSet Snapshot(IOperationConfig config) { ImageSet imgSet = base.Snapshot(config); if (!IIConfig.IsAsyncMode) { if (config is GocatorOperationConfig opConfig) { if (opConfig.IsOpenConnection) { system.Start(); } else { system.Stop(); } if (!opConfig.IsSnapshotAction) { return null; } } } GoImageSet imgSet = new GoImageSet(); InitialImageSet(imgSet, (config as CameraOprerationConfigBase).ImageSaveOption); GoDataSet dataSet = null; if (IIConfig.IsAsyncMode) { if (!IIConfig.IsHardwareTrigger) { _snapFlag = true; if (!_snapHandle.WaitOne(IIConfig.SnapshotTimeout)) { LogAsync(DateTime.Now, $"{Name}获取图像超时", ""); return null; } dataSet = _currentData; } } else { try { dataSet = system.ReceiveData(IIConfig.SnapshotTimeout); } catch (Exception ex) { LogAsync(DateTime.Now, $"{Name}获取图像异常", ex.GetExceptionMessage()); return null; } } HandleGoData(dataSet, imgSet); if (imgSet.HImage == null) { LogAsync(DateTime.Now, $"{Name}未能获取HImage图像", ""); } return imgSet; } float _currentExposure = 0; string _currentJob = ""; @@ -193,7 +237,15 @@ _currentJob = sensor.DefaultJob; if (!string.IsNullOrWhiteSpace(IIConfig.DefaultJob) && _currentJob != IIConfig.DefaultJob) { _currentJob = sensor.DefaultJob = IIConfig.DefaultJob; //_currentJob = sensor.DefaultJob = IIConfig.DefaultJob; string currentJob = IIConfig.DefaultJob; bool isChanged = false; sensor.LoadedJob(ref currentJob, ref isChanged); if (!isChanged) { throw new ProcessException($"{Name}未成功切换至任务{IIConfig.DefaultJob}"); } } sensor.Flush(); @@ -240,6 +292,10 @@ get => InitialConfig as GocatorInitialConfig; } volatile bool _snapFlag = false; readonly ManualResetEvent _snapHandle = new ManualResetEvent(false); GoDataSet _currentData = null; /// <summary> /// 异步模式获取数据 /// </summary> @@ -247,6 +303,127 @@ private void onData(KObject data) { GoDataSet dataSet = (GoDataSet)data; if (IIConfig.IsHardwareTrigger) { GoImageSet imgSet = new GoImageSet(); InitialImageSet(imgSet, IConfig.ImageSaveOption); HandleGoData(dataSet, imgSet); if (imgSet.HImage != null) { OnHImageOutput?.BeginInvoke(this, imgSet.HImage, imgSet.Id, null, null); } else { LogAsync(DateTime.Now, $"{Name}获取HImage失败", ""); } } else { if (_snapFlag) { _snapFlag = false; _currentData = dataSet.Clone<GoDataSet>(); _snapHandle.Set(); } } } #region 重写图片保存操作 public override async void SaveOriginImage(Bitmap map, Bitmap showImage, string imgSetId) { Task.Run(() => { OnImageUpdated?.Invoke(this, showImage, imgSetId); }); GoImageSet set = _imageSetList.FirstOrDefault(u => u.Id == imgSetId) as GoImageSet; if (set == null) return; set.Image = map; await Task.Run(() => { lock (set.SaveLock) { if (set.ImageSaveOption.IsSaveOriginImage && !set.IsOriginSaved) { string imgDir = CheckImageDirectory(set.ImageSaveOption.ImageSaveSubDirectory, "Origin"); try { //SaveImageByNameAndType(map, set.Id, set.ImageSaveOption.ImageFormat, imgDir); string filePath = Path.Combine(imgDir, $"{set.Id}.tif"); set.HImage_2.WriteImage("tiff", 0, filePath); } catch (Exception ex) { LogAsync(DateTime.Now, $"{set.Id}原图保存失败", ex.GetExceptionMessage()); } } set.IsOriginSaved = true; ClearImageSet(set); } }); } /// <summary> /// 保存特定类型图片,例如NG图片 /// </summary> /// <param name="prefix">图片类型说明 例如“NG”</param> /// <param name="imgSetId">图片ID</param> public override async void SaveSelectedImage(string prefix, string imgSetId) { await Task.Run(() => { GoImageSet set = _imageSetList.FirstOrDefault(u => u.Id == imgSetId) as GoImageSet; if (set == null) return; lock (set.SaveLock) { if (set.ImageSaveOption.AddtionalSaveType.Contains(prefix) && !set.IsAddtionalSaved) { string imgDir = CheckImageDirectory(set.ImageSaveOption.ImageSaveSubDirectory, prefix); while (set.Image == null) { Thread.Sleep(50); } try { string filePath = Path.Combine(imgDir, $"{set.Id}.tif"); set.HImage_2.WriteImage("tiff", 0, filePath); } catch (Exception ex) { LogAsync(DateTime.Now, $"{set.Id}{prefix}图片保存失败", ex.GetExceptionMessage()); } } set.IsAddtionalSaved = true; ClearImageSet(set); } }); } #endregion } public class GoImageSet : ImageSet { public HImage HImage_2 { get; set; } public override void Dispose() { base.Dispose(); HImage_2?.Dispose(); HImage_2 = null; } } } src/Bro.Device.HikCamera/HikCameraDriver.cs
@@ -392,9 +392,11 @@ } } public override ImageSet Snapshot(IOperationConfig config) public override IImageSet Snapshot(IOperationConfig config) { ImageSet set = base.Snapshot(config); ImageSet set = new ImageSet(); InitialImageSet(set, (config as CameraOprerationConfigBase).ImageSaveOption); MyCamera.MV_FRAME_OUT frameInfo = new MyCamera.MV_FRAME_OUT(); nRet = MyCamera.MV_OK; src/Bro.UI.Model.Winform/UI/Canvas.cs
@@ -77,22 +77,26 @@ set => stsStatus.Visible = value; } private void OnMouseLocationUpdated(Point screenPoint, Point imagePoint) private async void OnMouseLocationUpdated(Point screenPoint, Point imagePoint, string colorDesc) { MouseLocationUpdated(screenPoint, imagePoint); //await Task.Run(() => tsslLocation.Text = $"屏幕坐标X:{screenPoint.X},Y:{screenPoint.Y} 图片坐标X:{imagePoint.X},Y:{imagePoint.Y} 颜色:{colorDesc}"); this.Invoke(new Action(() => { tsslLocation.Text = $"屏幕坐标X:{screenPoint.X},Y:{screenPoint.Y} 图片坐标X:{imagePoint.X},Y:{imagePoint.Y} 颜色:{colorDesc}"; })); } private void MouseLocationUpdated(Point screenPoint, Point imagePoint) { if (InvokeRequired) { Invoke(new Action<Point, Point>(MouseLocationUpdated), screenPoint, imagePoint); } else { tsslLocation.Text = $"屏幕坐标X:{screenPoint.X},Y:{screenPoint.Y} 图片坐标X:{imagePoint.X},Y:{imagePoint.Y}"; } } //private void MouseLocationUpdated(Point screenPoint, Point imagePoint, string colorDesc) //{ // if (InvokeRequired) // { // Invoke(new Action<Point, Point, string>(MouseLocationUpdated), screenPoint, imagePoint); // } // else // { // tsslLocation.Text = $"屏幕坐标X:{screenPoint.X},Y:{screenPoint.Y} 图片坐标X:{imagePoint.X},Y:{imagePoint.Y} 颜色:{colorDesc}"; // } //} #endregion #region 属性 src/Bro.UI.Model.Winform/UI/CanvasImage.cs
@@ -35,7 +35,7 @@ #region Event public Action<MouseState> OnMouseStateChanged; public Action<IShapeElement> DrawTemplateChanged = null; public Action<Point, Point> OnMouseLocationUpdated; public Action<Point, Point, string> OnMouseLocationUpdated; #endregion private MouseState mouseState = MouseState.Normal; @@ -540,7 +540,13 @@ //} //DisplayMouseLocation(e.Location); OnMouseLocationUpdated?.BeginInvoke(e.Location, ToMapPoint(e.Location), null, null); Point mapPoint = ToMapPoint(e.Location); Color color = Color.Transparent; if (MAP != null && mapPoint.X > 0 && mapPoint.X < MAP.Width && mapPoint.Y > 0 && mapPoint.Y < MAP.Height) { color = MAP.GetPixel(mapPoint.X, mapPoint.Y); } OnMouseLocationUpdated?.BeginInvoke(e.Location, mapPoint, color.Name, null, null); if (MouseState != MouseState.SelectionZoneDoing) {