using Autofac;
|
using Bro.Common.Helper;
|
using Bro.Common.Interface;
|
using Bro.Common.Model;
|
using HalconDotNet;
|
using System;
|
using System.Collections;
|
using System.Collections.Concurrent;
|
using System.Collections.Generic;
|
using System.ComponentModel;
|
using System.Drawing;
|
using System.Drawing.Design;
|
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;
|
|
namespace Bro.Common.Base
|
{
|
public abstract class CameraBase : DeviceBase
|
{
|
private const int IMAGESETLIFETIME = 10;
|
|
#region DeviceBase
|
protected override void Start()
|
{
|
if (clearImageTimer == null)
|
{
|
clearImageTimer = new System.Threading.Timer((o) => { ClearImage(); }, null, 0, 1000 * 60 * 120);
|
}
|
|
//if (clearImageSetTimer == null)
|
//{
|
// clearImageSetTimer = new System.Threading.Timer((o) => { ClearImageSetPeriodically(); }, null, 0, 1000 * IMAGESETLIFETIME);
|
//}
|
}
|
|
protected override void Stop()
|
{
|
if (clearImageTimer != null)
|
{
|
clearImageTimer.Change(-1, -1);
|
clearImageTimer.Dispose();
|
clearImageTimer = null;
|
}
|
|
//if (clearImageSetTimer != null)
|
//{
|
// clearImageSetTimer.Change(-1, -1);
|
// clearImageSetTimer.Dispose();
|
// clearImageSetTimer = null;
|
//}
|
}
|
#endregion
|
|
#region 配置相关
|
public virtual CameraInitialConfigBase IConfig
|
{
|
get
|
{
|
return InitialConfig as CameraInitialConfigBase;
|
}
|
}
|
|
public abstract IOperationConfig GetOperationConfigFromDevice();
|
|
public abstract void UploadOperationConfig(IOperationConfig config);
|
#endregion
|
|
#region 图片相关
|
public Action<CameraBase, Bitmap, string> OnImageUpdated;
|
|
public Action<CameraBase, HObject, string> OnHImageOutput { get; set; }
|
public event Action OnCameraOpModeChanged;
|
|
private EnumHelper.CameraOpMode opMode = CameraOpMode.SingleSnapShot;
|
/// <summary>
|
/// 运行模式 扫描or拍照
|
/// </summary>
|
public EnumHelper.CameraOpMode OpMode
|
{
|
get => opMode;
|
set
|
{
|
if (opMode != value)
|
{
|
opMode = value;
|
OnCameraOpModeChanged?.BeginInvoke(null, null);
|
}
|
|
if (opMode == CameraOpMode.ContinuousMode)
|
{
|
Task.Run(() =>
|
{
|
while (CurrentState == DeviceState.DSOpen && opMode == CameraOpMode.ContinuousMode)
|
{
|
Snapshot();
|
ImageShowedHandle.WaitOne();
|
}
|
});
|
}
|
}
|
}
|
|
public AutoResetEvent ImageShowedHandle = new AutoResetEvent(false);
|
|
//private Bitmap showImage;
|
/// <summary>
|
/// 输出显示的图片
|
/// </summary>
|
//public virtual Bitmap ShowImage
|
//{
|
// get
|
// {
|
// return showImage;
|
// }
|
// set
|
// {
|
// try
|
// {
|
// showImage = value;
|
|
// if (showImage != null)
|
// {
|
// OnImageUpdated?.Invoke(this, new Bitmap(showImage));
|
// }
|
// }
|
// catch (Exception ex)
|
// {
|
// LogAsync(DateTime.Now, $"图片显示异常信息", ex.GetExceptionMessage());
|
// }
|
// }
|
//}
|
|
|
/// <summary>
|
/// 一次性抓拍
|
/// </summary>
|
/// <returns></returns>
|
public abstract void Snapshot();
|
public abstract IImageSet Snapshot(IOperationConfig config);
|
|
public virtual void InitialImageSet(IImageSet set, ImageSaveOption saveOption)
|
{
|
OpMode = CameraOpMode.SingleSnapShot;
|
|
//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[set.Id] = set;
|
}
|
|
/// <summary>
|
/// 释放图片数据
|
/// </summary>
|
protected virtual void FreeImage()
|
{
|
//if (ShowImage != null)
|
//{
|
// ShowImage.Dispose();
|
//}
|
}
|
#endregion
|
|
#region 基元处理
|
public Action<CameraBase, List<IShapeElement>, string> OnElementsUpdated;
|
#endregion
|
|
#region 图片缓存/保存
|
//public readonly ConcurrentBag<IImageSet> _imageSetList = new ConcurrentBag<IImageSet>();
|
protected Dictionary<string, IImageSet> _imageSetList = new Dictionary<string, IImageSet>();
|
|
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[set.Id] = set;
|
}
|
|
//public virtual async void UpdateFitElements(List<IShapeElement> eleList, string imgSetId)
|
//{
|
// await Task.Run(() =>
|
// {
|
// OnElementsUpdated?.BeginInvoke(this, eleList, imgSetId, null, null);
|
// });
|
//}
|
|
public virtual async void SaveOriginImage(Bitmap map, Bitmap showImage, string imgSetId)
|
{
|
await Task.Run(() =>
|
{
|
OnImageUpdated?.Invoke(this, showImage, imgSetId);
|
});
|
|
IImageSet set = _imageSetList[imgSetId];
|
|
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);
|
}
|
catch (Exception ex)
|
{
|
LogAsync(DateTime.Now, $"{set.Id}原图保存失败", ex.GetExceptionMessage());
|
}
|
}
|
set.IsOriginSaved = true;
|
ClearImageSet(set);
|
}
|
});
|
}
|
|
public virtual async void SaveFitImage(List<IShapeElement> eleList, string imgSetId)
|
{
|
if (eleList.Count > 0)
|
OnElementsUpdated?.BeginInvoke(this, eleList, imgSetId, null, null);
|
|
IImageSet set = _imageSetList[imgSetId];
|
if (set == null)
|
return;
|
|
if (eleList.Count <= 0)
|
{
|
set.IsFitSaved = true;
|
return;
|
}
|
|
//set.IsInvokeSaveFit = true;
|
await Task.Run(() =>
|
{
|
lock (set.SaveLock)
|
{
|
if (set.ImageSaveOption.IsSaveFitImage && !set.IsFitSaved)
|
{
|
string imgDir = CheckImageDirectory(set.ImageSaveOption.ImageSaveSubDirectory, "FitResult");
|
|
while (set.Image == null)
|
{
|
Thread.Sleep(50);
|
}
|
|
try
|
{
|
Bitmap map = new Bitmap(set.Image.Width, set.Image.Height);
|
using (Graphics g = Graphics.FromImage(map))
|
{
|
g.DrawImage(set.Image, 0, 0);
|
|
eleList.ForEach(e =>
|
{
|
e.State = ElementState.Normal;
|
e.Draw(g);
|
});
|
}
|
|
SaveImageByNameAndType(map, set.Id, set.ImageSaveOption.ImageFormat, imgDir);
|
}
|
catch (Exception ex)
|
{
|
LogAsync(DateTime.Now, $"{set.Id}拟合图片保存失败", ex.GetExceptionMessage());
|
}
|
//finally
|
//{
|
// set.IsFitSaved = true;
|
//}
|
}
|
set.IsFitSaved = true;
|
ClearImageSet(set);
|
}
|
});
|
}
|
|
/// <summary>
|
/// 保存特定类型图片,例如NG图片
|
/// </summary>
|
/// <param name="prefix">图片类型说明 例如“NG”</param>
|
/// <param name="imgSetId">图片ID</param>
|
public virtual async void SaveSelectedImage(string prefix, string imgSetId)
|
{
|
await Task.Run(() =>
|
{
|
IImageSet set = _imageSetList[imgSetId];
|
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
|
{
|
SaveImageByNameAndType(set.Image, set.Id, set.ImageSaveOption.ImageFormat, imgDir);
|
|
//set.IsNGSaved = true;
|
}
|
catch (Exception ex)
|
{
|
LogAsync(DateTime.Now, $"{set.Id}{prefix}图片保存失败", ex.GetExceptionMessage());
|
}
|
//finally
|
//{
|
// set.IsAddtionalSaved = true;
|
//}
|
}
|
set.IsAddtionalSaved = true;
|
ClearImageSet(set);
|
}
|
});
|
}
|
|
protected string CheckImageDirectory(string subDir, string prefix)
|
{
|
if (string.IsNullOrWhiteSpace(subDir))
|
{
|
subDir = DateTime.Now.ToString("yyyyMMdd");
|
}
|
else
|
{
|
subDir = Path.Combine(DateTime.Now.ToString("yyyyMMdd"), subDir);
|
}
|
|
string imgDir = Path.Combine(IConfig.ImgDirectory, subDir, prefix);
|
|
DirectoryInfo dir = new DirectoryInfo(imgDir);
|
if (!dir.Exists)
|
{
|
dir.Create();
|
}
|
|
return imgDir;
|
}
|
|
protected void SaveImageByNameAndType(Bitmap map, string imageName, ImageFormat imgFormat, string imageDir)
|
{
|
string filePath = Path.Combine(imageDir, $"{imageName}.{imgFormat.ToString().ToLower()}");
|
map.Save(filePath, imgFormat);
|
}
|
|
//private Timer clearImageSetTimer = null;
|
|
public virtual void ClearImageSet(IImageSet set)
|
{
|
try
|
{
|
//if ((!set.ImageSaveOption.IsSaveOriginImage || set.IsOriginSaved)
|
// && (!set.ImageSaveOption.IsSaveFitImage || set.IsFitSaved)
|
// && (!set.ImageSaveOption.IsSaveNGImage || set.IsNGSaved))
|
if (set.IsOriginSaved && set.IsFitSaved && set.IsAddtionalSaved)
|
{
|
set.Dispose();
|
|
_imageSetList.Remove(set.Id);
|
LogAsync(DateTime.Now, $"移除图片信息,当前缓存数量:{_imageSetList.Count}", "");
|
}
|
//bool flag = false;
|
|
//do
|
//{
|
// flag = _imageSetList.TryTake(out set);
|
//} while (!flag);
|
//set.Dispose();
|
|
//LogAsync(DateTime.Now, $"移除图片信息,当前缓存数量:{_imageSetList.Count}", "");
|
}
|
catch (Exception ex)
|
{
|
LogAsync(DateTime.Now, $"清理图片缓存异常,当前缓存数量{_imageSetList.Count}", ex.GetExceptionMessage());
|
}
|
}
|
|
//public void ClearImageSet(string imgSetId)
|
//{
|
// IImageSet set = _imageSetList[imgSetId];
|
// if (set != null)
|
// ClearImageSet(set);
|
//}
|
|
//private void ImageSet_OnImageSetTimeout(ImageSet set)
|
//{
|
// ClearImageSet(set);
|
//}
|
|
//private void ClearImageSetPeriodically()
|
//{
|
// try
|
// {
|
// DateTime dt = DateTime.Now;
|
// foreach (ImageSet set in _imageSetList)
|
// {
|
// if ((dt - set.InitialTime).TotalSeconds > IMAGESETLIFETIME)
|
// {
|
// ImageSet temp = set;
|
// _imageSetList.TryTake(out temp);
|
// temp.Dispose();
|
// }
|
// }
|
// }
|
// catch (Exception ex)
|
// {
|
// LogAsync(DateTime.Now, $"定时清理图片缓存异常,当前缓存数量{_imageSetList.Count}", ex.GetExceptionMessage());
|
// }
|
//}
|
#endregion
|
|
#region 定时清理图片
|
static readonly object _clearImageLock = new object();
|
protected void ClearImage()
|
{
|
if (IConfig.SaveImageDayLimit > 0)
|
{
|
lock (_clearImageLock)
|
{
|
LogAsync(DateTime.Now, $"ClearImage Start", "");
|
|
try
|
{
|
DirectoryInfo dirImage = new DirectoryInfo(IConfig.ImgDirectory);
|
if (dirImage.Exists)
|
{
|
DateTime dtNow = DateTime.Now;
|
|
var folderList = dirImage.GetDirectories().ToList();
|
|
folderList = folderList.Where(f =>
|
{
|
if (f.Name.Length < 8)
|
return false;
|
|
DateTime dt = DateTime.Now;
|
string name = f.Name.Substring(0, 4) + "/" + f.Name.Substring(4, 2) + "/" + f.Name.Substring(6);
|
return DateTime.TryParse(name, out dt);
|
}).OrderBy(u => u.Name).ToList();
|
|
if (folderList.Count > IConfig.SaveImageDayLimit)
|
{
|
folderList.Take(folderList.Count - IConfig.SaveImageDayLimit).ToList().ForEach(f =>
|
{
|
f.Delete(true);
|
});
|
}
|
}
|
}
|
catch (Exception ex)
|
{
|
LogAsync(DateTime.Now, $"ClearImage异常", ex.GetExceptionMessage());
|
}
|
|
LogAsync(DateTime.Now, $"ClearImage Done", "");
|
}
|
}
|
}
|
|
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
|
[Device("Camera", "相机取像配置", EnumHelper.DeviceAttributeType.OperationConfig)]
|
public class CameraOprerationConfigBase : OperationConfigBase, INotifyPropertyChanged, IComplexDisplay, IHalconToolPath
|
{
|
private float exposure = 0;
|
/// <summary>
|
/// 曝光
|
/// </summary>
|
[Category("取像配置")]
|
[Description("曝光")]
|
[DisplayName("曝光")]
|
public virtual float Exposure
|
{
|
get => exposure;
|
set
|
{
|
if (exposure != value)
|
{
|
exposure = value;
|
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Exposure"));
|
}
|
}
|
}
|
|
/// <summary>
|
/// 增益
|
/// </summary>
|
[Category("取像配置")]
|
[Description("增益")]
|
[DisplayName("增益")]
|
public virtual float Gain { get; set; }
|
|
[Category("取像配置")]
|
[Description("曝光修改后等待时间,单位ms。针对部分场景确保曝光修改及时生效。")]
|
[DisplayName("曝光等待")]
|
public virtual int ExposureWaitTime { get; set; }
|
|
[Category("取像配置")]
|
[Description("拍摄后曝光值。可在一次拍摄后将曝光修改为下次拍摄的曝光值,节约曝光生效时间。")]
|
[DisplayName("拍摄后曝光")]
|
public virtual float ExposureAfterSnap { get; set; }
|
|
[Category("算法配置")]
|
[Description("算法路径")]
|
[DisplayName("算法路径")]
|
[Editor(typeof(FileDialogEditor), typeof(UITypeEditor))]
|
public string AlgorithemPath { get; set; } = "";
|
|
[Category("保存设置")]
|
[Description("图片保存配置")]
|
[DisplayName("图片保存配置")]
|
[TypeConverter(typeof(ComplexObjectConvert))]
|
[Editor(typeof(PropertyObjectEditor), typeof(UITypeEditor))]
|
public ImageSaveOption ImageSaveOption { get; set; } = new ImageSaveOption();
|
|
[Category("延时配置")]
|
[Description("拍照前延时")]
|
[DisplayName("前延时")]
|
public int DelayBefore { get; set; } = 0;
|
|
[Category("延时配置")]
|
[Description("拍照后延时")]
|
[DisplayName("后延时")]
|
public int DelayAfter { get; set; } = 0;
|
|
public event PropertyChangedEventHandler PropertyChanged;
|
|
public string GetDisplayText()
|
{
|
return $"曝光:{Exposure.ToString("f2")} 算法:{AlgorithemPath}";
|
}
|
|
public List<string> GetHalconToolPathList()
|
{
|
return new List<string>() { AlgorithemPath };
|
}
|
}
|
|
public class CameraInitialConfigBase : InitialConfigBase
|
{
|
[Category("驱动类型")]
|
[Description("驱动类型")]
|
[DisplayName("驱动类型")]
|
[Browsable(true)]
|
[TypeConverter(typeof(CameraTypeConverter))]
|
public override string DriverType { get; set; }
|
|
[Category("相机设置")]
|
[Description("相机序列号")]
|
[DisplayName("序列号")]
|
[TypeConverter(typeof(HalconSerialNumConverter))]
|
public virtual string SerialNum { get; set; }
|
|
[Category("相机设置")]
|
[Description("相机IP地址")]
|
[DisplayName("相机IP地址")]
|
public virtual string CameraIP { get; set; }
|
|
[Category("相机设置")]
|
[Description("上位机IP地址")]
|
[DisplayName("上位机IP地址")]
|
public virtual string ComputerIP { get; set; }
|
|
[Category("保存设置")]
|
[Description("图片保存目录")]
|
[DisplayName("图片保存目录")]
|
[Editor(typeof(FoldDialogEditor), typeof(UITypeEditor))]
|
public virtual string ImgDirectory { get; set; } = @"../Images";
|
|
[Category("保存设置")]
|
[Description("图片保存天数")]
|
[DisplayName("图片保存天数")]
|
public virtual int SaveImageDayLimit { get; set; } = 0;
|
|
[Category("保存设置")]
|
[Description("图片保存默认配置,主要用于硬触发等没有明确操作配置说明的图片保存")]
|
[DisplayName("图片保存默认配置")]
|
[TypeConverter(typeof(ComplexObjectConvert))]
|
[Editor(typeof(PropertyObjectEditor), typeof(UITypeEditor))]
|
public virtual ImageSaveOption ImageSaveOption { get; set; } = new ImageSaveOption();
|
|
[Category("拍摄设置")]
|
[Description("默认曝光值,相机开启后就设置该曝光值")]
|
[DisplayName("默认曝光值")]
|
public virtual float DefaultExposure { get; set; }
|
}
|
#endregion
|
|
#region Converter & Editor
|
public class HalconSerialNumConverter : ComboBoxItemTypeConvert
|
{
|
public override Hashtable GetConvertHash(ITypeDescriptorContext context)
|
{
|
Hashtable table = new Hashtable();
|
HTuple deviceList = null;
|
|
AutoResetEvent handle = new AutoResetEvent(false);
|
|
Task.Run(() =>
|
{
|
HOperatorSet.InfoFramegrabber("GigEVision", "info_boards", out HTuple deviceInfo, out deviceList);
|
handle.Set();
|
});
|
|
handle.WaitOne(5000);
|
if (deviceList != null)
|
{
|
for (int i = 0; i < deviceList.Length; i++)
|
{
|
var list = deviceList[i].S.Split(new char[] { ':', '|' }, StringSplitOptions.RemoveEmptyEntries);
|
|
table[list[1].Trim()] = list[3].Trim() + "--" + list[1].Trim();
|
}
|
}
|
|
return table;
|
}
|
}
|
|
public class CameraTypeConverter : DeviceTypeConverter<CameraBase>
|
{
|
}
|
|
public class CameraInitialConfigEditor : DeviceInitialConfigEditor<CameraInitialConfigBase>
|
{
|
}
|
|
public class CameraDeviceConverter : ComboBoxItemTypeConvert
|
{
|
public override Hashtable GetConvertHash(ITypeDescriptorContext context)
|
{
|
Hashtable table = new Hashtable();
|
using (var scope = GlobalVar.Container.BeginLifetimeScope())
|
{
|
var config = scope.Resolve<IProcessConfig>();
|
|
config.CameraConfigCollection.ForEach(camera =>
|
{
|
table[camera.Id] = camera.Name;
|
});
|
}
|
|
return table;
|
}
|
}
|
#endregion
|
|
#region 辅助类
|
public class ImageSaveOption : IComplexDisplay
|
{
|
[Category("图片保存")]
|
[Description("图片保存文件夹子文件夹名称")]
|
[DisplayName("子目录")]
|
public string ImageSaveSubDirectory { get; set; }
|
|
[Category("图片保存")]
|
[Description("是否保存原始图片")]
|
[DisplayName("保存原始图片")]
|
public bool IsSaveOriginImage { get; set; } = true;
|
|
[Category("图片保存")]
|
[Description("图片保存格式")]
|
[DisplayName("图片保存格式")]
|
public ImageFormat ImageFormat { get; set; } = ImageFormat.Jpeg;
|
|
[Category("图片保存")]
|
[Description("是否保存拟合/结果图片")]
|
[DisplayName("保存拟合图片")]
|
public bool IsSaveFitImage { get; set; } = false;
|
|
//[Category("图片保存")]
|
//[Description("是否保存NG图片")]
|
//[DisplayName("保存NG图片")]
|
//public bool IsSaveNGImage { get; set; } = false;
|
[Category("图片保存")]
|
[Description("附加保存图片类型,多类型使用\",\"间隔。如要保存OK和NG图片,填写\"OK,NG\"")]
|
[DisplayName("附加保存图片类型")]
|
public string AddtionalSaveType { get; set; } = "";
|
|
public string GetDisplayText()
|
{
|
//return $"子目录:{ImageSaveSubDirectory}{(IsSaveOriginImage ? " 保存原图" : "")}{(string.IsNullOrWhiteSpace(AddtionalSaveType) ? "" : ("保存"{AddtionalSaveType}"图片"))} {(IsSaveFitImage ? " 保存拟合图片" : "")}";
|
|
string txt = "";
|
if (!string.IsNullOrWhiteSpace(ImageSaveSubDirectory))
|
{
|
txt += $"子目录:{ImageSaveSubDirectory}";
|
}
|
|
if (IsSaveOriginImage)
|
{
|
txt += " 保存原图";
|
}
|
|
if (!string.IsNullOrWhiteSpace(AddtionalSaveType))
|
{
|
txt += $" 保存{AddtionalSaveType}图片";
|
}
|
|
if (IsSaveFitImage)
|
{
|
txt += " 保存拟合图片";
|
}
|
|
return txt;
|
}
|
}
|
|
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;
|
|
private string id = "";
|
public string Id
|
{
|
get
|
{
|
if (string.IsNullOrWhiteSpace(id))
|
{
|
id = InitialTime.ToString("HHmmssfff");
|
}
|
return id;
|
}
|
}
|
|
public HImage HImage { get; set; } = null;
|
|
public Bitmap Image { get; set; } = null;
|
|
//public List<ElementBase> EleList { get; set; } = new List<ElementBase>();
|
|
//public OutputResult Result { get; set; } = OutputResult.OK;
|
|
#region Save Option & Result
|
public ImageSaveOption ImageSaveOption { get; set; } = new ImageSaveOption();
|
|
public bool IsOriginSaved { get; set; } = false;
|
|
//public bool IsInvokeSaveFit { get; set; } = false;
|
public bool IsFitSaved { get; set; } = false;
|
//public bool IsInvokeSaveNG { get; set; } = false;
|
public bool IsAddtionalSaved { get; set; } = false;
|
|
public object SaveLock { get; set; } = new object();
|
|
public virtual string ImageData { get; set; }
|
|
//public event Action<ImageSet> OnImageSetTimeout;
|
//private Timer autoDisposeTimer = null;
|
|
public void Dispose(object state)
|
{
|
//OnImageSetTimeout?.Invoke(this);
|
|
//autoDisposeTimer.Change(-1, -1);
|
//autoDisposeTimer.Dispose();
|
|
Image?.Dispose();
|
Image = null;
|
}
|
|
public virtual void Dispose()
|
{
|
Dispose(null);
|
}
|
|
public ImageSet()
|
{
|
//autoDisposeTimer = new Timer(Dispose, null, 10 * 1000, -1);
|
}
|
#endregion
|
}
|
#endregion
|
}
|