Class1.cs 13.2 KB
using System;
using System.Diagnostics;
using System.Drawing;
using System.Runtime.InteropServices;

namespace Asa
{
    /// <summary>
    /// Careray平板图像
    /// </summary>
    public class CarerayImage
    {
        private byte[] buffer;
        private API.CR_EventID eventID;
        private API.CallbackDelegate callback;

        private const int HEAD = 64;
        private const int DEV_INDEX = 1;
        private const int MODE_ID = 103;
        private readonly log4net.ILog LOG;


        /// <summary>
        /// Careray平板图像
        /// </summary>
        public CarerayImage(string logName = "CarerayImage")
        {
            callback = new API.CallbackDelegate(Process);
            LOG = log4net.LogManager.GetLogger(logName);
        }

        /// <summary>
        /// 窗宽
        /// </summary>
        public int WindowWidth { set; get; }

        /// <summary>
        /// 窗位
        /// </summary>
        public int WindowLevel { set; get; }

        /// <summary>
        /// 图像宽度
        /// </summary>
        public int ImageWidth { private set; get; }

        /// <summary>
        /// 图像高度
        /// </summary>
        public int ImageHeight { private set; get; }

        /// <summary>
        /// IP地址
        /// </summary>
        public string IP { private set; get; }

        /// <summary>
        /// 打开设备
        /// </summary>
        /// <returns></returns>
        public bool Open()
        {
            int rtn;

            //注册回调函数
            callback = new API.CallbackDelegate(Process);
            rtn = API.CR_RegisterEventCallbackFun(DEV_INDEX, callback);
            LOG.Info("CR_RegisterEventCallbackFun Return " + rtn);
            if (rtn != 0) return false;
            GC.KeepAlive(callback);

            //连接设备
            rtn = API.CR_Connect(DEV_INDEX);
            LOG.Info("CR_Connect Return " + rtn);
            if (rtn != 0) return false;

            //获取IP
            rtn = API.CR_GetDetectorIndexAndIPAddress(out API.CR_DetrIdxAndIPAddr pDetrIdxAndIPAddr, out int pDetrNum);
            LOG.Info("CR_GetDetectorIndexAndIPAddress Return " + rtn + " DetrNum=" + pDetrNum);
            if (rtn != 0) return false;
            int len = Array.FindIndex(pDetrIdxAndIPAddr.szIPAddr, b => b == 0);
            IP = System.Text.Encoding.ASCII.GetString(pDetrIdxAndIPAddr.szIPAddr, 0, len);

            //重置不重启
            rtn = API.CR_ResetDetector(DEV_INDEX, false);
            LOG.Info("CR_ResetDetector Return " + rtn);
            if (rtn != 0) return false;

            //获取应用模式
            API.CR_ModeInfo[] pModeInfo = new API.CR_ModeInfo[10];
            for (int i = 0; i < pModeInfo.Length; i++)
                pModeInfo[i] = new API.CR_ModeInfo();
            rtn = API.CR_GetApplicationMode(DEV_INDEX, pModeInfo, out int pModeNum);
            LOG.Info("CR_GetApplicationMode Return " + rtn + " ModeNum=" + pModeNum);
            if (rtn != 0) return false;

            //获取图像宽度高度
            for (int i = 0; i < pModeNum; i++)
            {
                if (pModeInfo[i].nModeID == MODE_ID)
                {
                    ImageWidth = pModeInfo[i].nImageWidth;
                    ImageHeight = pModeInfo[i].nImageHeight;
                    break;
                }
            }

            //设置参数
            float pFrameRate = 1.2f;  //帧率
            int pExposureTime = 0;    //积分时间
            int nTriggType = 9;       //触发类型,内触发
            int nGainIndex = 6;       //增益
            rtn = API.CR_SetApplicationModeWithParam(DEV_INDEX, MODE_ID, ref pFrameRate, ref pExposureTime, nTriggType, nGainIndex);
            LOG.Info(string.Format("CR_SetApplicationModeWithParam({0},{1},{2},{3},{4},{5}) Return {6}", DEV_INDEX, MODE_ID, pFrameRate, pExposureTime, nTriggType, nGainIndex, rtn));
            if (rtn != 0) return false;

            return true;
        }

        /// <summary>
        /// 关闭设备
        /// </summary>
        /// <returns></returns>
        public bool Close()
        {
            int rtn;

            //还在采集图像
            if (eventID == API.CR_EventID.CR_EVT_NEW_FRAME)
            {
                rtn = API.CR_StopAcquisition(DEV_INDEX);
                LOG.Info("CR_StopAcquisition Return " + rtn);
            }

            //关闭设备
            rtn = API.CR_Disconnect(DEV_INDEX);
            LOG.Info("CR_Disconnect Return " + rtn);
            if (rtn != 0) return false;

            return true;
        }

        /// <summary>
        /// 获取图像
        /// </summary>
        /// <returns></returns>
        public bool GetImage()
        {
            buffer = new byte[ImageWidth * ImageHeight * 2 + HEAD];
            for (int i = 0; i < buffer.Length; i++)
                buffer[i] = 255;

            int rtn;
            rtn = API.CR_StartAcquisition(DEV_INDEX, 1, buffer);
            LOG.Info("CR_StartAcquisition Return " + rtn);
            if (rtn != 0) return false;

            System.Threading.Thread.Sleep(5000);
            rtn = API.CR_StopAcquisition(DEV_INDEX);
            LOG.Info("CR_StopAcquisition Return " + rtn);
            if (rtn != 0) return false;

            return true;
        }

        /// <summary>
        /// 加载本地RAW图片,64字节头
        /// </summary>
        /// <param name="filePath"></param>
        public void LoadRAW(string filePath)
        {
            buffer = System.IO.File.ReadAllBytes(filePath);

        }

        /// <summary>
        /// 获取48位RGB图像
        /// </summary>
        /// <returns></returns>
        public Bitmap Get48bImage()
        {
            if (buffer == null) return null;
            int count = ImageWidth * ImageHeight;
            byte[] gray = new byte[count * 2];
            Array.Copy(buffer, HEAD, gray, 0, gray.Length);

            int idx1 = 0;
            int idx2 = 0;
            int half = WindowWidth / 2;
            byte[] buff = new byte[gray.Length * 3];
            for (int i = 0; i < count; i++)
            {
                short point = BitConverter.ToInt16(gray, idx1);
                point += 20000;

                if (point < WindowLevel - half)
                {
                    buff[idx2++] = 0;
                    buff[idx2++] = 0;
                    buff[idx2++] = 0;
                    buff[idx2++] = 0;
                    buff[idx2++] = 0;
                    buff[idx2++] = 0;
                }
                else if (point > WindowLevel + half)
                {
                    //buff[idx2++] = 255;
                    //buff[idx2++] = 127;
                    //buff[idx2++] = 255;
                    //buff[idx2++] = 127;
                    //buff[idx2++] = 255;
                    //buff[idx2++] = 127;
                    buff[idx2++] = 255;
                    buff[idx2++] = 255;
                    buff[idx2++] = 255;
                    buff[idx2++] = 255;
                    buff[idx2++] = 255;
                    buff[idx2++] = 255;
                }
                else
                {
                    byte[] bb = BitConverter.GetBytes(point);
                    buff[idx2++] = bb[0];
                    buff[idx2++] = bb[1];
                    buff[idx2++] = bb[0];
                    buff[idx2++] = bb[1];
                    buff[idx2++] = bb[0];
                    buff[idx2++] = bb[1];
                }
                idx1 += 2;
            }


            Bitmap bmp = new Bitmap(ImageWidth, ImageHeight, System.Drawing.Imaging.PixelFormat.Format48bppRgb);
            System.Drawing.Imaging.BitmapData bmpData = bmp.LockBits(new Rectangle(0, 0, ImageWidth, ImageHeight), System.Drawing.Imaging.ImageLockMode.ReadWrite, bmp.PixelFormat);
            Marshal.Copy(buff, 0, bmpData.Scan0, bmpData.Stride * ImageHeight);
            bmp.UnlockBits(bmpData);
            return bmp;

        }




        internal void Process(int nEventID, ref API.CR_Event pEvent)
        {
            eventID = (API.CR_EventID)nEventID;
            LOG.Debug(string.Format("nEventID={0} {1}", nEventID, eventID));
            Debug.Print("nEventID=" + nEventID);


        }


    }



    internal static class API
    {
        [DllImport("CRInterface.dll")]
        internal static extern int CR_Connect(int nDetrIndex);

        [DllImport("CRInterface.dll")]
        internal static extern int CR_Disconnect(int nDetrIndex);

        [DllImport("CRInterface.dll")]
        internal static extern int CR_GetSystemInformation(int nDetrIndex, out CR_SystemInfo pSystemInformation);

        [DllImport("CRInterface.dll")]
        internal static extern int CR_ResetDetector(int nDetrIndex, bool needReboot);

        [DllImport("CRInterface.dll")]
        internal static extern int CR_StartAcquisition(int nDetrIndex, int nFrameNum, [In, Out] byte[] pBuffer, int nNumFrmReqFromDetr = -1); // nNumFrmReqFromDetr == -1 means that detector sends out frames continuously until StopAcquisition() is received.

        [DllImport("CRInterface.dll")]
        internal static extern int CR_StopAcquisition(int nDetrIndex);

        [DllImport("CRCallback.dll")]
        internal static extern int CR_RegisterEventCallbackFun(int nDetrIndex, CallbackDelegate pCallback);

        [DllImport("CRInterface.dll")]
        internal static extern int CR_SetApplicationMode(int nDetrIndex, int nModeIndex);

        [DllImport("CRInterface.dll")]
        internal static extern int CR_GetApplicationMode(int nDetrIndex, [In, Out] CR_ModeInfo[] pModeInfo, out int pModeNum);

        [DllImport("CRInterface.dll")]
        internal static extern int CR_GetDetectorIndexAndIPAddress(out CR_DetrIdxAndIPAddr pDetrIdxAndIPAddr, out int pDetrNum);

        [DllImport("CRInterface.dll")]
        internal static extern int CR_SetApplicationModeWithParam(int nDetrIndex, int nModeIndex, ref float pFrameRate, ref int pExposureTime, int nTriggType, int nGainIndex);

        [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
        internal delegate void CallbackDelegate(int nEventID, ref CR_Event pEvent);




        [StructLayout(LayoutKind.Sequential)]
        internal struct CR_Event
        {
            internal int nDetrIndex;
            internal int nWidth;
            internal int nHeight;
            internal int nPixelDepth;
            internal int pData;
        }

        [StructLayout(LayoutKind.Sequential)]
        internal struct CR_SystemInfo
        {
            internal uint nRawImageWidth;
            internal uint nRawImageHeight;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 64)]
            internal byte[] szHardwareVersion;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 64)]
            internal byte[] szSerialNumber;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 64)]
            internal byte[] szSoftwareVersion;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 64)]
            internal byte[] szFirmwareVersion;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 64)]
            internal byte[] szDetrMachineID;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 128)]
            internal byte[] szDetrDesc;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 512)]
            internal byte[] szReserved;
        }

        [StructLayout(LayoutKind.Sequential)]
        internal struct CR_ModeInfo
        {
            internal int nModeID; // Application mode ID
            internal int nImageWidth;
            internal int nImageHeight;
            internal int nCutoffX;
            internal int nCutoffY;
            internal int nBinX; // Binning scheme along X direction
            internal int nBinY; // Binning scheme along Y direction
            internal float fMaxFrmRate; // Maximal frame rate in fps
            internal int nMaxExpTime; // Maximal exposure time in ms
            internal int nPixelDepth; // Pixel depth in bits
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
            internal int[] nTrigTypes;
            internal int nTrigTypeNum; // 0 - 15
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
            internal int[] nGainLevels;
            internal int nGainLevelNum; // 0 - 15
            internal int nDefaultTrigType; // Default trigger type
            internal int nDefaultGainLevel; // Default gain level
            internal int nRoiX;
            internal int nRoiY;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 256)]
            internal byte[] szDesc; // Additional description
        }

        [StructLayout(LayoutKind.Sequential)]
        internal struct CR_DetrIdxAndIPAddr
        {
            internal int nIdx;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 64)]
            internal byte[] szIPAddr;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 128)]
            internal byte[] szReserved;
        }

        internal enum CR_EventID
        {
            CR_EVT_SERVER_DISCONNECTED,
            CR_EVT_DETR_DISCONNECTED,
            CR_EVT_EXPOSURE_INFO,
            CR_EVT_TEMPERATURE_INFO,
            CR_EVT_BATTERY_INFO,
            CR_EVT_WIRELESS_INFO,
            CR_EVT_NEW_FRAME,
            CR_EVT_CALIBRATION_IN_PROGRESS,
            CR_EVT_CALIBRATION_FINISHED,
            CR_EVT_ACQ_STAT_INFO
        };




    }


}