using Cognex.VisionPro; using Microsoft.Win32; using NPOI.SS.Formula.Eval; using SciCamera.Net; using System; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; using System.Drawing; using System.IO; using System.Linq; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Text; using System.Threading; using System.Threading.Tasks; using TeamAAS_VP.Enums; using TeamAAS_VP.Interfaces; using TeamAAS_VP.Models; namespace TeamAAS_VP.Core.Cameras { public class OptCamera : ICamera, INotifyPropertyChanged { #region 字段 private Thread m_hReceiveThread; // 用于序列化对同一相机实例的操作,防止同一实例被并发操作 //private readonly SemaphoreSlim _operationSemaphore = new SemaphoreSlim(1, 1); // 用于保护状态变量(例如 IsGrabbing)的并发访问 private readonly object _stateLock = new object(); #endregion #region 属性 /// /// 是否是3D相机 /// public bool Is3D { get; } = false; public CameraBrand CameraBrand { get => CameraBrand.Opt; } public string Name { get; private set; } public Guid ID { get; private set; } public int Index { get; set; } public string ManufacturerName { get; private set; } public bool IsFindByIp { get; private set; } public string ModelName { get; private set; } public string SerialNumber { get; private set; } public string CameraIp { get; private set; } public CameraType CameraType { get; private set; } SciCam mvCameraAcq; public SciCam.SCI_DEVICE_INFO CameraInfo { get; private set; } public UInt32 ImageWidth { get; private set; } public UInt32 ImageHeight { get; private set; } public SciCam.SciCamPixelType PixelType { get; private set; } private bool _IsGrabbing; /// /// 正在采集 /// public bool IsGrabbing { get { return _IsGrabbing; } private set { SetProperty(ref _IsGrabbing, value); } } private ICogImage _Image; public ICogImage Image { get { return _Image; } private set { SetProperty(ref _Image, value); } } public bool IsConnected { get; private set; } private bool IsHaveCamera = false; /// /// 采集用时 /// public TimeSpan TotalTime { get; private set; } /// /// 错误信息 /// public string ErrorMessage { get; private set; } #endregion #region 事件 public event Action ImageCallbackEvent; public event Action CameraConnectChangedEvent; #endregion public OptCamera(Guid id, int index, string name, string serialNumber, string cameraip, bool isFindByIp) { ID = id; Name = serialNumber; Index = index; CameraIp = cameraip; SerialNumber = serialNumber; IsFindByIp = isFindByIp; mvCameraAcq = new SciCam(); SciCam.SCI_DEVICE_INFO_LIST stDeviceList = new SciCam.SCI_DEVICE_INFO_LIST(); //设备列表 uint nReVal = SciCam.DiscoveryDevices(ref stDeviceList, (uint)(SciCam.SciCamTLType.SciCam_TLType_Gige)); if (nReVal != SciCam.SCI_CAMERA_OK) { return; } for (int i = 0; i < stDeviceList.count; i++) { SciCam.SCI_DEVICE_INFO device = stDeviceList.pDevInfo[i]; SciCam.SciCamTLType devTlType = device.tlType; if (devTlType == SciCam.SciCamTLType.SciCam_TLType_Gige) { SciCam.SCI_DEVICE_GIGE_INFO gigeDevInfo = (SciCam.SCI_DEVICE_GIGE_INFO)SciCam.ByteToStruct(device.info.gigeInfo, typeof(SciCam.SCI_DEVICE_GIGE_INFO)); uint ip1 = gigeDevInfo.ip; int nIp1 = (int)(ip1 & 0x000000ff); int nIp2 = (int)((ip1 & 0x0000ff00) >> 8); int nIp3 = (int)((ip1 & 0x00ff0000) >> 16); int nIp4 = (int)((ip1 & 0xff000000) >> 24); string ip = string.Format("{0}.{1}.{2}.{3}", nIp1, nIp2, nIp3, nIp4); if (IsFindByIp) { if (CameraIp == ip) { ManufacturerName = gigeDevInfo.manufactureName; ModelName = gigeDevInfo.modelName; SerialNumber = gigeDevInfo.serialNumber; CameraType = CameraType.GIGE; CameraInfo = device; IsHaveCamera = true; break; } } else { if (string.Equals(gigeDevInfo.serialNumber, serialNumber)) { ManufacturerName = gigeDevInfo.manufactureName; ModelName = gigeDevInfo.modelName; SerialNumber = gigeDevInfo.serialNumber; CameraType = CameraType.GIGE; CameraInfo = device; IsHaveCamera = true; break; } } } } IsConnected = false; } #region 方法 /// /// 获取设备 /// /// public static CameraInfo[] GetDevices() { List cameras = new List(); try { if (!CheckSoftwareInstalled().isInstalled) { LogHelper.WriteLogInfo("未安装OPT"); return cameras.ToArray(); } SciCam.SCI_DEVICE_INFO_LIST stDeviceList = new SciCam.SCI_DEVICE_INFO_LIST(); //设备列表 uint nReVal = SciCam.DiscoveryDevices(ref stDeviceList, (uint)(SciCam.SciCamTLType.SciCam_TLType_Gige)); if (nReVal != SciCam.SCI_CAMERA_OK) { return cameras.ToArray(); } for (int i = 0; i < stDeviceList.count; i++) { SciCam.SCI_DEVICE_INFO device = stDeviceList.pDevInfo[i]; SciCam.SciCamTLType devTlType = device.tlType; if (devTlType == SciCam.SciCamTLType.SciCam_TLType_Gige) { SciCam.SCI_DEVICE_GIGE_INFO gigeDevInfo = (SciCam.SCI_DEVICE_GIGE_INFO)SciCam.ByteToStruct(device.info.gigeInfo, typeof(SciCam.SCI_DEVICE_GIGE_INFO)); uint ip1 = gigeDevInfo.ip; int nIp1 = (int)(ip1 & 0x000000ff); int nIp2 = (int)((ip1 & 0x0000ff00) >> 8); int nIp3 = (int)((ip1 & 0x00ff0000) >> 16); int nIp4 = (int)((ip1 & 0xff000000) >> 24); string ip = string.Format("{0}.{1}.{2}.{3}", nIp1, nIp2, nIp3, nIp4); cameras.Add(new CameraInfo() { CameraNo = i + 1, CameraName = gigeDevInfo.name, CameraBrand = CameraBrand.Opt, CameraType = CameraType.GIGE, ManufacturerName = gigeDevInfo.manufactureName, Model = gigeDevInfo.modelName, SerialNumber = gigeDevInfo.serialNumber, CameraIp = ip, IsFindByIp = true, }); } } } catch (Exception ex) { LogHelper.WriteLogError("搜索OPT相机列表时出错!", ex); } return cameras.ToArray(); } /// /// 检查相机软件是否安装 /// /// public static (bool isInstalled, string version) CheckSoftwareInstalled() { //string softwareName = "OPT Camera Viewer"; //string softwareVersion = "4.0.0.3"; //string[] registryPaths = new[] //{ // @"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall", // @"SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall" //}; //foreach (var path in registryPaths) //{ // using (RegistryKey key = Registry.LocalMachine.OpenSubKey(path)) // { // if (key == null) continue; // foreach (string subKeyName in key.GetSubKeyNames()) // { // using (RegistryKey subKey = key.OpenSubKey(subKeyName)) // { // string displayName = subKey.GetValue("DisplayName")?.ToString(); // if (displayName != null && displayName.ToUpper().Trim() == softwareName.ToUpper()) // { // string version = subKey.GetValue("DisplayVersion")?.ToString(); // Version v1 = new Version(version); // Version v2 = new Version(softwareVersion); // if (v1 >= v2) // { // return (true, version); // } // else // { // return (false, version); // } // } // } // } // } //} //return (false, ""); return (true, "4.0.0.3"); // TODO: Opt相机不检查软件安装 } /// /// 打开相机 /// /// /// public bool OpenDevice() { //_operationSemaphore.Wait(); uint nReVal = SciCam.SCI_CAMERA_OK; try { if (!IsHaveCamera) { mvCameraAcq = new SciCam(); SciCam.SCI_DEVICE_INFO_LIST stDeviceList = new SciCam.SCI_DEVICE_INFO_LIST(); //设备列表 nReVal = SciCam.DiscoveryDevices(ref stDeviceList, (uint)(SciCam.SciCamTLType.SciCam_TLType_Gige)); if (nReVal != SciCam.SCI_CAMERA_OK) { return false; } for (int i = 0; i < stDeviceList.count; i++) { SciCam.SCI_DEVICE_INFO device = stDeviceList.pDevInfo[i]; SciCam.SciCamTLType devTlType = device.tlType; if (devTlType == SciCam.SciCamTLType.SciCam_TLType_Gige) { SciCam.SCI_DEVICE_GIGE_INFO gigeDevInfo = (SciCam.SCI_DEVICE_GIGE_INFO)SciCam.ByteToStruct(device.info.gigeInfo, typeof(SciCam.SCI_DEVICE_GIGE_INFO)); uint ip1 = gigeDevInfo.ip; int nIp1 = (int)(ip1 & 0x000000ff); int nIp2 = (int)((ip1 & 0x0000ff00) >> 8); int nIp3 = (int)((ip1 & 0x00ff0000) >> 16); int nIp4 = (int)((ip1 & 0xff000000) >> 24); string ip = string.Format("{0}.{1}.{2}.{3}", nIp1, nIp2, nIp3, nIp4); if (IsFindByIp) { if (CameraIp == ip) { ManufacturerName = gigeDevInfo.manufactureName; ModelName = gigeDevInfo.modelName; SerialNumber = gigeDevInfo.serialNumber; CameraType = CameraType.GIGE; CameraInfo = device; IsHaveCamera = true; break; } } else { if (string.Equals(gigeDevInfo.serialNumber, SerialNumber)) { ManufacturerName = gigeDevInfo.manufactureName; ModelName = gigeDevInfo.modelName; SerialNumber = gigeDevInfo.serialNumber; CameraType = CameraType.GIGE; CameraInfo = device; IsHaveCamera = true; break; } } } } if (!IsHaveCamera) { throw new Exception("没有发现相机"); } } SciCam.SCI_DEVICE_INFO sCI_DEVICE_INFO= CameraInfo; nReVal = mvCameraAcq.CreateDevice(ref sCI_DEVICE_INFO); if (nReVal != SciCam.SCI_CAMERA_OK) { Console.WriteLine("Creat Device Fail! nRet:{0}", nReVal); throw new Exception("Creat Device Fail!"); } // ch:打开设备 | en:Open device nReVal = mvCameraAcq.OpenDevice(); // ch:设置触发模式为off | en:Set trigger mode as off nReVal = mvCameraAcq.SetEnumValueByStringEx(SciCam.SciCamDeviceXmlType.SciCam_DeviceXml_Camera, "TriggerMode", "On"); nReVal = mvCameraAcq.SetEnumValueByStringEx(SciCam.SciCamDeviceXmlType.SciCam_DeviceXml_Camera, "TriggerSource", "Software"); if (!IsConnected) { CameraConnectChangedEvent?.Invoke(ID, true); } IsConnected = mvCameraAcq.IsDeviceOpen(); if (IsConnected) { mvCameraAcq.StartGrabbing(); } return IsConnected; } finally { //_operationSemaphore.Release(); } } /// /// 打开相机异步 /// /// public Task OpenDeviceAsync() { return Task.Run(() => { return OpenDevice(); }); } /// /// 关闭相机 /// public void CloseDevice() { // ch:关闭设备 | en:Close Device //_operationSemaphore.Wait(); try { if (mvCameraAcq!=null) { mvCameraAcq.StopGrabbing(); mvCameraAcq.CloseDevice(); } } finally { //_operationSemaphore.Release(); } } /// /// 采集图像 /// /// public ICogImage Grab(bool isRealtime = true) { //_operationSemaphore.Wait(); uint nReVal = SciCam.SCI_CAMERA_OK; IntPtr payload = IntPtr.Zero; try { Stopwatch sw = Stopwatch.StartNew(); for (int i = 0; i < 5; i++) { try { //if (!mvCameraAcq.IsDeviceOpen()) //{ // OpenDevice(); //} //nReVal = mvCameraAcq.StartGrabbing(); mvCameraAcq.ClearPayloadBuffer(); nReVal = mvCameraAcq.SetCommandValueEx(SciCam.SciCamDeviceXmlType.SciCam_DeviceXml_Camera, "TriggerSoftware"); nReVal = mvCameraAcq.Grab(ref payload); if (nReVal == SciCam.SCI_CAMERA_OK) { Image = GetConvertedInfo(payload); mvCameraAcq.FreePayload(payload); //nReVal = mvCameraAcq.StopGrabbing(); TotalTime = sw.Elapsed; return Image; } //else //{ // nReVal = mvCameraAcq.FreePayload(payload); // //nReVal = mvCameraAcq.StopGrabbing(); // //_operationSemaphore.Release(); // CloseDevice(); // OpenDevice(); // ErrorMessage = "图像采集失败!"; //} } catch (Exception ex) { //_operationSemaphore.Release(); CloseDevice(); OpenDevice(); ErrorMessage = ex.Message; } } if (IsConnected) { IsConnected = false; CameraConnectChangedEvent?.Invoke(ID, false); } return null; } finally { //_operationSemaphore.Release(); } } /// /// 采集图像 /// /// public ICogImage Grab2(bool isRealtime = true) { //_operationSemaphore.Wait(); uint nReVal = SciCam.SCI_CAMERA_OK; IntPtr payload = IntPtr.Zero; try { Stopwatch sw = Stopwatch.StartNew(); for (int i = 0; i < 5; i++) { try { //if (!mvCameraAcq.IsDeviceOpen()) //{ // OpenDevice(); //} //nReVal = mvCameraAcq.StartGrabbing(); mvCameraAcq.ClearPayloadBuffer(); nReVal = mvCameraAcq.SetCommandValueEx(SciCam.SciCamDeviceXmlType.SciCam_DeviceXml_Camera, "TriggerSoftware"); nReVal = mvCameraAcq.Grab(ref payload); if (nReVal == SciCam.SCI_CAMERA_OK) { Image = GetConvertedInfo(payload); mvCameraAcq.FreePayload(payload); //nReVal = mvCameraAcq.StopGrabbing(); TotalTime = sw.Elapsed; return Image; } //else //{ // nReVal = mvCameraAcq.FreePayload(payload); // //nReVal = mvCameraAcq.StopGrabbing(); // //_operationSemaphore.Release(); // CloseDevice(); // OpenDevice(); // ErrorMessage = "图像采集失败!"; //} } catch (Exception ex) { //_operationSemaphore.Release(); CloseDevice(); OpenDevice(); ErrorMessage = ex.Message; } } if (IsConnected) { IsConnected = false; CameraConnectChangedEvent?.Invoke(ID, false); } return null; } finally { //_operationSemaphore.Release(); } } /// /// 开始采集图像 /// public void StartGrabbing() { lock (_stateLock) { if (IsGrabbing) return; IsGrabbing = true; } m_hReceiveThread = new Thread(GetStreamThreadProc) { IsBackground = true }; m_hReceiveThread.Start(); } /// /// 停止采集图像 /// public void StopGrabbing() { try { lock (_stateLock) { IsGrabbing = false; } if (m_hReceiveThread != null) { m_hReceiveThread.Abort(); m_hReceiveThread = null; } } catch (Exception) { } } /// /// 设置曝光时间 /// /// /// public bool SetExposureTime(float ExposureTime) { //_operationSemaphore.Wait(); try { if (!mvCameraAcq.IsDeviceOpen()) return false; uint nReVal = SciCam.SCI_CAMERA_OK; nReVal = mvCameraAcq.SetIntValue("ExposureTime", (int)ExposureTime); if (nReVal != SciCam.SCI_CAMERA_OK) { mvCameraAcq.SetFloatValue("ExposureTime", ExposureTime); } return true; } finally { //_operationSemaphore.Release(); } } /// /// 获取曝光时间 /// /// public float GetExposureTime() { //_operationSemaphore.Wait(); try { if (!mvCameraAcq.IsDeviceOpen()) return 0; uint nReVal = SciCam.SCI_CAMERA_OK; SciCam.SCI_NODE_VAL_INT iNodeVal = new SciCam.SCI_NODE_VAL_INT(); nReVal = mvCameraAcq.GetIntValue("ExposureTime", ref iNodeVal); if (nReVal != SciCam.SCI_CAMERA_OK) { SciCam.SCI_NODE_VAL_FLOAT fNodeVal = new SciCam.SCI_NODE_VAL_FLOAT(); nReVal = mvCameraAcq.GetFloatValue("ExposureTime", ref fNodeVal); if (nReVal == SciCam.SCI_CAMERA_OK) { return (float)fNodeVal.dVal; } else { return 0; } } else { return (float)iNodeVal.nVal; } } finally { //_operationSemaphore.Release(); } } /// /// 设置增益 /// /// /// public bool SetGain(float Gain) { //_operationSemaphore.Wait(); try { if (!mvCameraAcq.IsDeviceOpen()) return false; uint nReVal = SciCam.SCI_CAMERA_OK; nReVal = mvCameraAcq.SetIntValue("Gain", (int)Gain); if (nReVal != SciCam.SCI_CAMERA_OK) { mvCameraAcq.SetFloatValue("Gain", Gain); } return true; } finally { //_operationSemaphore.Release(); } } /// /// 获取增益 /// /// public float GetGain() { //_operationSemaphore.Wait(); try { if (!mvCameraAcq.IsDeviceOpen()) return 0; uint nReVal = SciCam.SCI_CAMERA_OK; SciCam.SCI_NODE_VAL_INT iNodeVal = new SciCam.SCI_NODE_VAL_INT(); nReVal = mvCameraAcq.GetIntValue("Gain", ref iNodeVal); if (nReVal != SciCam.SCI_CAMERA_OK) { SciCam.SCI_NODE_VAL_FLOAT fNodeVal = new SciCam.SCI_NODE_VAL_FLOAT(); nReVal = mvCameraAcq.GetFloatValue("Gain", ref fNodeVal); if (nReVal == SciCam.SCI_CAMERA_OK) { return (float)fNodeVal.dVal; } else { return 0; } } else { return (float)iNodeVal.nVal; } } finally { //_operationSemaphore.Release(); } } private void GetStreamThreadProc() { while (IsGrabbing) { try { Grab(); ImageCallbackEvent?.Invoke(Image, TotalTime, ErrorMessage,ID); } catch (Exception) { } Thread.Sleep(10); } IsGrabbing = false; } private ICogImage GetConvertedInfo(IntPtr payload) { if (payload == IntPtr.Zero) { return null; } SciCam.SCI_CAM_PAYLOAD_ATTRIBUTE payloadAttribute = new SciCam.SCI_CAM_PAYLOAD_ATTRIBUTE(); uint nReVal = SciCam.PayloadGetAttribute(payload, ref payloadAttribute); if (nReVal != SciCam.SCI_CAMERA_OK) { return null; } bool imgIsComplete = payloadAttribute.isComplete; SciCam.SciCamPayloadMode payloadMode = payloadAttribute.payloadMode; SciCam.SciCamPixelType imgPixelType = payloadAttribute.imgAttr.pixelType; ulong imgWidth = payloadAttribute.imgAttr.width; ulong imgHeight = payloadAttribute.imgAttr.height; ulong framID = payloadAttribute.frameID; if (!imgIsComplete || payloadMode != SciCam.SciCamPayloadMode.SciCam_PayloadMode_2D) { return null; } IntPtr imgData = IntPtr.Zero; nReVal = SciCam.PayloadGetImage(payload, ref imgData); if (nReVal != SciCam.SCI_CAMERA_OK) { return null; } long destImgSize = 0; if (imgPixelType == SciCam.SciCamPixelType.Mono1p || imgPixelType == SciCam.SciCamPixelType.Mono2p || imgPixelType == SciCam.SciCamPixelType.Mono4p || imgPixelType == SciCam.SciCamPixelType.Mono8s || imgPixelType == SciCam.SciCamPixelType.Mono8 || imgPixelType == SciCam.SciCamPixelType.Mono10 || imgPixelType == SciCam.SciCamPixelType.Mono10p || imgPixelType == SciCam.SciCamPixelType.Mono12 || imgPixelType == SciCam.SciCamPixelType.Mono12p || imgPixelType == SciCam.SciCamPixelType.Mono14 || imgPixelType == SciCam.SciCamPixelType.Mono16 || imgPixelType == SciCam.SciCamPixelType.Mono10Packed || imgPixelType == SciCam.SciCamPixelType.Mono12Packed || imgPixelType == SciCam.SciCamPixelType.Mono14p) { nReVal = SciCam.PayloadConvertImage(ref payloadAttribute.imgAttr, imgData, SciCam.SciCamPixelType.Mono8, IntPtr.Zero, ref destImgSize, true); if (nReVal == SciCam.SCI_CAMERA_OK) { IntPtr destImg = Marshal.AllocHGlobal((int)destImgSize); try { nReVal = SciCam.PayloadConvertImage(ref payloadAttribute.imgAttr, imgData, SciCam.SciCamPixelType.Mono8, destImg, ref destImgSize, true); if (nReVal == SciCam.SCI_CAMERA_OK) { byte[] bBitmap = new byte[destImgSize]; Marshal.Copy(destImg, bBitmap, 0, (int)destImgSize); Bitmap bitMap = new Bitmap((int)imgWidth, (int)imgHeight, System.Drawing.Imaging.PixelFormat.Format8bppIndexed); System.Drawing.Imaging.BitmapData bitmapData = bitMap.LockBits(new Rectangle(0, 0, (int)imgWidth, (int)imgHeight), System.Drawing.Imaging.ImageLockMode.WriteOnly, System.Drawing.Imaging.PixelFormat.Format8bppIndexed); Marshal.Copy(bBitmap, 0, bitmapData.Scan0, (int)destImgSize); bitMap.UnlockBits(bitmapData); //设置调色板 System.Drawing.Imaging.ColorPalette palette = bitMap.Palette; for (int i = 0; i < 256; i++) { palette.Entries[i] = Color.FromArgb(i, i, i); } bitMap.Palette = palette; //显示图片 return TransformICogImage((uint)imgHeight, (uint)imgWidth, destImg, SciCam.SciCamPixelType.Mono8); } } catch (Exception ex) { } finally { Marshal.FreeHGlobal(destImg); } } } else { nReVal = SciCam.PayloadConvertImage(ref payloadAttribute.imgAttr, imgData, SciCam.SciCamPixelType.RGB8, IntPtr.Zero, ref destImgSize, true); if (nReVal == SciCam.SCI_CAMERA_OK) { IntPtr destImg = Marshal.AllocHGlobal((int)destImgSize); try { nReVal = SciCam.PayloadConvertImage(ref payloadAttribute.imgAttr, imgData, SciCam.SciCamPixelType.RGB8, destImg, ref destImgSize, true); if (nReVal == SciCam.SCI_CAMERA_OK) { IntPtr pTemp = IntPtr.Zero; Byte[] byteArrImageData = new Byte[imgWidth * imgHeight * 3]; unsafe { byte* pBufForSaveImage = (byte*)destImg; UInt32 nSupWidth = ((UInt32)imgWidth + (UInt32)3) & 0xfffffffc; for (int nRow = 0; nRow < (int)imgHeight; nRow++) { for (int col = 0; col < (int)imgWidth; col++) { byteArrImageData[nRow * nSupWidth + col] = pBufForSaveImage[nRow * (int)imgWidth * 3 + (3 * col)]; byteArrImageData[(int)imgWidth * (int)imgHeight + nRow * nSupWidth + col] = pBufForSaveImage[nRow * (int)imgWidth * 3 + (3 * col + 1)]; byteArrImageData[(int)imgWidth * (int)imgHeight * 2 + nRow * nSupWidth + col] = pBufForSaveImage[nRow * (int)imgWidth * 3 + (3 * col + 2)]; } } pTemp = Marshal.UnsafeAddrOfPinnedArrayElement(byteArrImageData, 0); } //显示图片 return TransformICogImage((uint)imgHeight, (uint)imgWidth, pTemp, SciCam.SciCamPixelType.RGB8); } } catch (Exception ex) { } finally { Marshal.FreeHGlobal(destImg); } } } return null; } private ICogImage TransformICogImage(UInt32 nHeight, UInt32 nWidth, IntPtr pImageBuf, SciCam.SciCamPixelType enPixelType) { try { ICogImage image; if (enPixelType == SciCam.SciCamPixelType.Mono8) { CogImage8Root cogImage8Root = new CogImage8Root(); cogImage8Root.Initialize((Int32)nWidth, (Int32)nHeight, pImageBuf, (Int32)nWidth, null); CogImage8Grey cogImage8Grey = new CogImage8Grey(); cogImage8Grey.SetRoot(cogImage8Root); image = cogImage8Grey.ScaleImage((int)nWidth, (int)nHeight); System.GC.Collect(); return image; } else { CogImage8Root image0 = new CogImage8Root(); IntPtr ptr0 = new IntPtr(pImageBuf.ToInt64()); image0.Initialize((int)nWidth, (int)nHeight, ptr0, (int)nWidth, null); CogImage8Root image1 = new CogImage8Root(); IntPtr ptr1 = new IntPtr(pImageBuf.ToInt64() + nWidth * nHeight); image1.Initialize((int)nWidth, (int)nHeight, ptr1, (int)nWidth, null); CogImage8Root image2 = new CogImage8Root(); IntPtr ptr2 = new IntPtr(pImageBuf.ToInt64() + nWidth * nHeight * 2); image2.Initialize((int)nWidth, (int)nHeight, ptr2, (int)nWidth, null); CogImage24PlanarColor colorImage = new CogImage24PlanarColor(); //colorImage.SetRoots(image0, image1, image2); colorImage.SetRoots(image2, image1, image0); image = colorImage.ScaleImage((int)nWidth, (int)nHeight); System.GC.Collect(); return image; } } catch (System.Exception) { return null; } } #endregion #region 属性通知 /// /// Occurs when a property value changes. /// public event PropertyChangedEventHandler PropertyChanged; /// /// Checks if a property already matches a desired value. Sets the property and /// notifies listeners only when necessary. /// /// Type of the property. /// Reference to a property with both getter and setter. /// Desired value for the property. /// Name of the property used to notify listeners. This /// value is optional and can be provided automatically when invoked from compilers that /// support CallerMemberName. /// True if the value was changed, false if the existing value matched the /// desired value. protected virtual bool SetProperty(ref T storage, T value, [CallerMemberName] string propertyName = null) { if (EqualityComparer.Default.Equals(storage, value)) return false; storage = value; RaisePropertyChanged(propertyName); return true; } /// /// Checks if a property already matches a desired value. Sets the property and /// notifies listeners only when necessary. /// /// Type of the property. /// Reference to a property with both getter and setter. /// Desired value for the property. /// Name of the property used to notify listeners. This /// value is optional and can be provided automatically when invoked from compilers that /// support CallerMemberName. /// Action that is called after the property value has been changed. /// True if the value was changed, false if the existing value matched the /// desired value. protected virtual bool SetProperty(ref T storage, T value, Action onChanged, [CallerMemberName] string propertyName = null) { if (EqualityComparer.Default.Equals(storage, value)) return false; storage = value; onChanged?.Invoke(); RaisePropertyChanged(propertyName); return true; } /// /// Raises this object's PropertyChanged event. /// /// Name of the property used to notify listeners. This /// value is optional and can be provided automatically when invoked from compilers /// that support . protected void RaisePropertyChanged([CallerMemberName] string propertyName = null) { OnPropertyChanged(new PropertyChangedEventArgs(propertyName)); } /// /// Raises this object's PropertyChanged event. /// /// The PropertyChangedEventArgs protected virtual void OnPropertyChanged(PropertyChangedEventArgs args) { PropertyChanged?.Invoke(this, args); } #endregion } }