海康工业相机 SDK对接 Hikvision

news2025/1/31 3:09:46

有C#基础的,可以参考下,直接上代码

BaseResult 来自于Nuget包,搜Rotion可以搜出来 LS.Standard.Data

海康的接口操作,要先引用相应的dll

using MvCamCtrl.NET;
using PCZD.Commons.Data.CameraModel;
using PCZD.Data;
using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.Net;
using System.Runtime.InteropServices;
using System.Threading;





    public class Hikvision
    {
        //调用示例
        //Hikvision camera = new Hikvision();//创建相机对象并实例化
        //camera.connectCamera("123456");//连接相机,传入相机序列号123456
        //camera.startCamera();//开启相机采集
        //camera.setExposureTime(10000);//设置曝光时间为10ms
        //camera.softTrigger();//发送软触发采集图像
        //Himage image=camera.readImage();//获取采集到且转换后的图像
        //camera.stopCamera();//停止相机采集
        //camera.closeCamera();//关闭相机


        public Hikvision()
        {
            InitCamera();
        }

        #region 属性

        public MyCamera myCamera;//相机对象
        public MyCamera.MV_CC_DEVICE_INFO_LIST deviceList;//设备列表
        public MyCamera.MV_CC_DEVICE_INFO deviceInfo;//设备对象
        public string seriesStr;//接收相机序列号
        public MyCamera.MVCC_INTVALUE stParam;//用于接收特定的参数

        //为读取、保存图像创建的数组
        bool m_bGrabbing = false;
        Thread m_hReceiveThread;
        MyCamera.MV_FRAME_OUT_INFO_EX m_stFrameInfo = new MyCamera.MV_FRAME_OUT_INFO_EX();
        UInt32 m_nBufSizeForDriver = 0;
        IntPtr m_BufForDriver;
        private static Object BufForDriverLock = new Object();
        //保存图像使用的参数
        UInt32 m_nBufSizeForSaveImage = 0;
        IntPtr m_BufForSaveImage;

        //图像显示控件
        IntPtr image_handle;

        /// <summary>
        /// 获取实时的图像数据 委托
        /// </summary>
        public delegate void DelegateReceiveImage(Bitmap bmp);

        /// <summary>
        /// 获取实时的图像数据 委托方法
        /// </summary>
        public event DelegateReceiveImage OnReceiveImage;

        #endregion

        #region 相机参数

        //相机参数
        private float _ExposureTime;
        /// <summary>
        /// 曝光时间
        /// </summary>
        public float ExposureTime
        {
            get => _ExposureTime;
        }

        private float _Gain;
        /// <summary>
        /// 增益
        /// </summary>
        public float Gain
        {
            get => _Gain;
        }

        private float _ResultingFrameRate;
        /// <summary>
        /// 频率
        /// </summary>
        public float ResultingFrameRate
        {
            get => _ResultingFrameRate;
        }

        #endregion

        #region 公共操作方法

        /// <summary>
        /// 初始化相机数据
        /// </summary>
        public void InitCamera()
        {
            deviceList = new MyCamera.MV_CC_DEVICE_INFO_LIST();
        }

        /// <summary>
        /// 相机是否连接
        /// </summary>
        /// <returns></returns>
        public bool IsConnect()
        {
           return myCamera.MV_CC_IsDeviceConnected_NET();
        }

        /// <summary>
        /// 设置相机配置
        /// </summary>
        /// <param name="config">配置</param>
        public BaseResult SetCameraConfig(CameraConfig config)
        {
            try
            {
                if (config == null)
                {
                    return new BaseResult(false, "相机参数不能为空");
                }
                if (myCamera == null)
                {
                    return new BaseResult(false, "相机未连接");
                }
                int Res = 0;
                if (config.ImageWidth > 0)
                {
                    Res = myCamera.MV_CC_SetIntValue_NET("Width", (uint)config.ImageWidth);
                    if (MyCamera.MV_OK != Res)
                    {
                        return new BaseResult(false, $"相机参数-设置相机宽度出错【{config.ImageWidth}】");
                    }
                }

                if (config.ImageHeight > 0)
                {
                    Res = myCamera.MV_CC_SetIntValue_NET("Height", (uint)config.ImageHeight);
                    if (MyCamera.MV_OK != Res)
                    {
                        return new BaseResult(false, $"相机参数-设置相机高度出错【{config.ImageHeight}】");
                    }
                }

                //设置连续自动曝光模式
                //ExposureAutoMode值为0,表示自动曝光模式关闭;
                //ExposureAutoMode值为1,表示单次自动曝光模式开启;
                //ExposureAutoMode值为2,表示连续自动曝光模式开启。
                uint ExposureAutoMode = config.AutoExposure ? (uint)2 : 0;
                Res = myCamera.MV_CC_SetExposureAutoMode_NET(ExposureAutoMode);
                if (MyCamera.MV_OK != Res)
                {
                    return new BaseResult(false, $"相机参数-设置自动 曝光,参数【{ExposureAutoMode}】");
                }

                uint GainAutoMode = config.AutoGain ? (uint)2 : (uint)0;
                Res = myCamera.MV_CC_SetGainMode_NET(GainAutoMode);
                if (MyCamera.MV_OK != Res)
                {
                    return new BaseResult(false, $"相机参数-设置自动 增益,参数【{GainAutoMode}】");
                }


                if (!config.AutoExposure)
                {
                    Res = myCamera.MV_CC_SetFloatValue_NET("ExposureTime", config.ExposureTime);
                    if (MyCamera.MV_OK != Res)
                    {
                        return new BaseResult(false, $"相机参数-设置曝光时间出错【{config.ExposureTime}】");
                    }
                }

                if (!config.AutoGain)
                {
                    Res = myCamera.MV_CC_SetFloatValue_NET("Gain", config.Gain);
                    if (MyCamera.MV_OK != Res)
                    {
                        return new BaseResult(false, $"相机参数-设置增益出错【{config.Gain}】");
                    }
                }

                Res = myCamera.MV_CC_SetFloatValue_NET("AcquisitionFrameRate", config.FrameRate);
                if (MyCamera.MV_OK != Res)
                {
                    return new BaseResult(false, $"相机参数-设置频率错误,参数【{config.FrameRate}】");
                }

                //1:触发模式  0:非触发模式
                Res = myCamera.MV_CC_SetEnumValue_NET("TriggerMode", 1);
                if (MyCamera.MV_OK != Res)
                {
                    return new BaseResult(false, $"相机参数-设置触发模式失败,参数【{1}】");
                }

                //触发源 7:软触发
                Res = myCamera.MV_CC_SetEnumValue_NET("TriggerSource", 7);
                if (MyCamera.MV_OK != Res)
                {
                    return new BaseResult(false, $"相机参数-设置触发源失败,参数【{7}】");
                }

                myCamera.MV_CC_SetIntValue_NET("GevHeartbeatTimeout", 30 * 1000);

                return BaseResult.Successed;
            }
            catch (Exception ex)
            {
                return new BaseResult(false, ex.Message);
            }
        }

        /// <summary>
        /// 绑定显示图象控件
        /// </summary>
        /// <param name="handle"></param>
        public void BindDisplayControl(IntPtr handle)
        {
            image_handle = handle;
        }

        /// <summary>
        /// 寻找设备
        /// </summary>
        public void DeviceListAcq()
        {
            deviceList.nDeviceNum = 0;
            int nRet = MyCamera.MV_CC_EnumDevices_NET(MyCamera.MV_GIGE_DEVICE | MyCamera.MV_USB_DEVICE, ref deviceList);
            if (0 != nRet)
            {
                return;
            }
        }

        /// <summary>
        /// 相机修改IP
        /// 调用函数时可以传入需要改变的目标IP,如过没有传入则将相机IP设置为其所连接的网卡地址+1或-1
        /// </summary>
        /// <param name="IP"></param>
        /// <returns></returns>
        public BaseResult ChangeIP(string IP = "")
        {
            try
            {
                //获取相机相关信息,例如相机所连接网卡的网址
                IntPtr buffer = Marshal.UnsafeAddrOfPinnedArrayElement(deviceInfo.SpecialInfo.stGigEInfo, 0);
                MyCamera.MV_GIGE_DEVICE_INFO gigeInfo = (MyCamera.MV_GIGE_DEVICE_INFO)Marshal.PtrToStructure(buffer, typeof(MyCamera.MV_GIGE_DEVICE_INFO));
                IPAddress cameraIPAddress;
                string tempStr = "";
                if (IP.Trim().Equals("") || !(IPAddress.TryParse(IP, out cameraIPAddress)))
                {
                    //当前网卡的IP地址
                    UInt32 nNetIp1 = (gigeInfo.nNetExport & 0xFF000000) >> 24;
                    UInt32 nNetIp2 = (gigeInfo.nNetExport & 0x00FF0000) >> 16;
                    UInt32 nNetIp3 = (gigeInfo.nNetExport & 0x0000FF00) >> 8;
                    UInt32 nNetIp4 = (gigeInfo.nNetExport & 0x000000FF);
                    //根据网卡IP设定相机IP,如果网卡ip第四位小于252,则相机ip第四位+1,否则相机IP第四位-1
                    UInt32 cameraIp1 = nNetIp1;
                    UInt32 cameraIp2 = nNetIp2;
                    UInt32 cameraIp3 = nNetIp3;
                    UInt32 cameraIp4 = nNetIp4;
                    if (nNetIp4 < 252)
                    {
                        cameraIp4++;
                    }
                    else
                    {
                        cameraIp4--;
                    }
                    tempStr = cameraIp1 + "." + cameraIp2 + "." + cameraIp3 + "." + cameraIp4;
                }
                else
                {
                    tempStr = IP;
                }
                IPAddress.TryParse(tempStr, out cameraIPAddress);
                long cameraIP = IPAddress.NetworkToHostOrder(cameraIPAddress.Address);
                //设置相机掩码
                uint maskIp1 = (gigeInfo.nCurrentSubNetMask & 0xFF000000) >> 24;
                uint maskIp2 = (gigeInfo.nCurrentSubNetMask & 0x00FF0000) >> 16;
                uint maskIp3 = (gigeInfo.nCurrentSubNetMask & 0x0000FF00) >> 8;
                uint maskIp4 = (gigeInfo.nCurrentSubNetMask & 0x000000FF);
                IPAddress subMaskAddress;
                tempStr = maskIp1 + "." + maskIp2 + "." + maskIp3 + "." + maskIp4;
                IPAddress.TryParse(tempStr, out subMaskAddress);
                long maskIP = IPAddress.NetworkToHostOrder(subMaskAddress.Address);
                //设置网关
                uint gateIp1 = (gigeInfo.nDefultGateWay & 0xFF000000) >> 24;
                uint gateIp2 = (gigeInfo.nDefultGateWay & 0x00FF0000) >> 16;
                uint gateIp3 = (gigeInfo.nDefultGateWay & 0x0000FF00) >> 8;
                uint gateIp4 = (gigeInfo.nDefultGateWay & 0x000000FF);
                IPAddress gateAddress;
                tempStr = gateIp1 + "." + gateIp2 + "." + gateIp3 + "." + gateIp4;
                IPAddress.TryParse(tempStr, out gateAddress);
                long gateIP = IPAddress.NetworkToHostOrder(gateAddress.Address);

                int temp = myCamera.MV_GIGE_ForceIpEx_NET((UInt32)(cameraIP >> 32), (UInt32)(maskIP >> 32), (UInt32)(gateIP >> 32));//执行更改相机IP的命令
                if (temp == 0)
                    //强制IP成功
                    return BaseResult.Successed;
                //强制IP失败
                return BaseResult.Failed;
            }
            catch (Exception ex)
            {
                //PCZDLogHelper.Error("相机修改IP异常", ex);
                return BaseResult.Failed;
            }
        }

        /// <summary>
        /// 连接相机
        /// </summary>
        /// <param name="id">列表设备索引 0开始</param>
        /// <returns></returns>
        public BaseResult ConnectCamera(int id)
        {
            string m_SerialNumber = "";//接收设备返回的序列号
            int temp;//接收命令执行结果
            myCamera = new MyCamera();
            try
            {
                if (deviceList.nDeviceNum <= 0)
                {
                    temp = MyCamera.MV_CC_EnumDevices_NET(MyCamera.MV_GIGE_DEVICE | MyCamera.MV_USB_DEVICE, ref deviceList);//更新设备列表
                    if (temp != 0)
                    {
                        //设备更新成功接收命令的返回值为0,返回值不为0则为异常
                        return new BaseResult(false, "刷新设备列表错误");
                    }
                }

                if (id >= deviceList.nDeviceNum)
                {
                    return new BaseResult(false, "索引超出设备数量");
                }

                int index = id;

                deviceInfo = (MyCamera.MV_CC_DEVICE_INFO)Marshal.PtrToStructure(deviceList.pDeviceInfo[index], typeof(MyCamera.MV_CC_DEVICE_INFO));//获取设备
                if (deviceInfo.nTLayerType == MyCamera.MV_GIGE_DEVICE)
                {
                    IntPtr buffer = Marshal.UnsafeAddrOfPinnedArrayElement(deviceInfo.SpecialInfo.stGigEInfo, 0);
                    MyCamera.MV_GIGE_DEVICE_INFO gigeInfo = (MyCamera.MV_GIGE_DEVICE_INFO)Marshal.PtrToStructure(buffer, typeof(MyCamera.MV_GIGE_DEVICE_INFO));
                    //m_SerialNumber = gigeInfo.chSerialNumber;//获取序列号

                    m_SerialNumber = gigeInfo.chUserDefinedName;//获取用户名
                }
                else if (deviceInfo.nTLayerType == MyCamera.MV_USB_DEVICE)
                {
                    IntPtr buffer = Marshal.UnsafeAddrOfPinnedArrayElement(deviceInfo.SpecialInfo.stUsb3VInfo, 0);
                    MyCamera.MV_USB3_DEVICE_INFO usbInfo = (MyCamera.MV_USB3_DEVICE_INFO)Marshal.PtrToStructure(buffer, typeof(MyCamera.MV_USB3_DEVICE_INFO));
                    m_SerialNumber = usbInfo.chUserDefinedName;
                }
                this.seriesStr = m_SerialNumber;
                temp = myCamera.MV_CC_CreateDevice_NET(ref deviceInfo);
                if (MyCamera.MV_OK != temp)
                {
                    //创建相机失败
                    return new BaseResult(false, "相机创建失败");
                }
                temp = myCamera.MV_CC_OpenDevice_NET();//
                if (MyCamera.MV_OK != temp)
                {
                    //打开相机失败
                    return new BaseResult(false, "打开相机失败");
                }
                return BaseResult.Successed;
            }
            catch (Exception ex)
            {
                //PCZDLogHelper.Error("打开相机设备异常", ex);
                return new BaseResult(false, "打开相机设备发生异常,操作失败");
            }
        }

        /// <summary>
        /// 连接相机
        /// </summary>
        /// <param name="ip">相机IP地址 需要IP转long</param>
        /// <returns></returns>
        public BaseResult ConnectCamera(long ip)
        {
            string m_SerialNumber = "";//接收设备返回的序列号
            int temp;//接收命令执行结果
            myCamera = new MyCamera();
            try
            {
                if (deviceList.nDeviceNum <= 0)
                {
                    temp = MyCamera.MV_CC_EnumDevices_NET(MyCamera.MV_GIGE_DEVICE | MyCamera.MV_USB_DEVICE, ref deviceList);//更新设备列表
                    if (temp != 0)
                    {
                        //设备更新成功接收命令的返回值为0,返回值不为0则为异常
                        return new BaseResult(false, "刷新设备列表错误");
                    }
                }

                bool isFind = false;
                for (int index = 0; index < deviceList.nDeviceNum; index++)
                {
                    deviceInfo = (MyCamera.MV_CC_DEVICE_INFO)Marshal.PtrToStructure(deviceList.pDeviceInfo[index], typeof(MyCamera.MV_CC_DEVICE_INFO));//获取设备
                    if (deviceInfo.nTLayerType == MyCamera.MV_GIGE_DEVICE)
                    {
                        //使用IP就只有网口通讯类型了
                        IntPtr buffer = Marshal.UnsafeAddrOfPinnedArrayElement(deviceInfo.SpecialInfo.stGigEInfo, 0);
                        MyCamera.MV_GIGE_DEVICE_INFO gigeInfo = (MyCamera.MV_GIGE_DEVICE_INFO)Marshal.PtrToStructure(buffer, typeof(MyCamera.MV_GIGE_DEVICE_INFO));
                        if (gigeInfo.nCurrentIp == ip)
                        {
                            m_SerialNumber = gigeInfo.chUserDefinedName;//获取用户名
                            isFind = true;
                            break;
                        }
                    }
                }
                if (!isFind)
                {
                    return new BaseResult(false, $"未找到相应IP的相机设备,IP:[{IPHelper.LongToIp(ip)}]");
                }
                this.seriesStr = m_SerialNumber;
                temp = myCamera.MV_CC_CreateDevice_NET(ref deviceInfo);
                if (MyCamera.MV_OK != temp)
                {
                    //创建相机失败
                    return new BaseResult(false, "相机创建失败");
                }
                temp = myCamera.MV_CC_OpenDevice_NET();//
                if (MyCamera.MV_OK != temp)
                {
                    //打开相机失败
                    return new BaseResult(false, "打开相机失败");
                }
                return BaseResult.Successed;
            }
            catch (Exception ex)
            {
                //PCZDLogHelper.Error("打开相机设备异常", ex);
                return new BaseResult(false, "打开相机设备发生异常,操作失败");
            }
        }

        /// <summary>
        /// 相机开始采集
        /// </summary>
        /// <returns></returns>
        public BaseResult StartCamera()
        {
            //采集标识
            m_bGrabbing = true;

            //收集回调数据的处理线程
            m_hReceiveThread = new Thread(ReceiveThreadProcess);
            m_hReceiveThread.Start();

            m_stFrameInfo.nFrameLen = 0;//取流之前先清除帧长度
            m_stFrameInfo.enPixelType = MyCamera.MvGvspPixelType.PixelType_Gvsp_Undefined;
            // ch:开始采集 | en:Start Grabbing
            int nRet = myCamera.MV_CC_StartGrabbing_NET();
            if (MyCamera.MV_OK != nRet)
            {
                m_bGrabbing = false;
                m_hReceiveThread.Join();
                return BaseResult.Failed;
            }

            return BaseResult.Successed;
        }

        /// <summary>
        /// 停止相机采集
        /// </summary>
        /// <returns></returns>
        public BaseResult StopCamera()
        {
            m_bGrabbing = false;
            m_hReceiveThread?.Join();

            if (myCamera == null)
                return BaseResult.Successed;
            int temp = myCamera.MV_CC_StopGrabbing_NET();
            if (MyCamera.MV_OK != temp)
                return BaseResult.Failed;
            return BaseResult.Successed;
        }

        /// <summary>
        /// 关闭相机
        /// </summary>
        /// <returns></returns>
        public BaseResult CloseCamera()
        {
            if (myCamera == null)
                return BaseResult.Successed;
            if (m_bGrabbing)
            {
                var res = StopCamera();//停止相机采集
                if (!res)
                    return res;
            }
            int temp = myCamera.MV_CC_CloseDevice_NET();
            if (MyCamera.MV_OK != temp)
                return BaseResult.Failed;
            temp = myCamera.MV_CC_DestroyDevice_NET();
            if (MyCamera.MV_OK != temp)
                return BaseResult.Failed;
            return BaseResult.Successed;
        }

        /// <summary>
        /// 获取相机参数
        /// 如:曝光时间 、增益、频率等
        /// </summary>
        public void GetCameraParam()
        {
            try
            {
                if (myCamera == null)
                    return;
                MyCamera.MVCC_FLOATVALUE stParam = new MyCamera.MVCC_FLOATVALUE();
                int nRet = myCamera.MV_CC_GetFloatValue_NET("ExposureTime", ref stParam);
                if (MyCamera.MV_OK == nRet)
                {
                    _ExposureTime = stParam.fCurValue;
                }

                nRet = myCamera.MV_CC_GetFloatValue_NET("Gain", ref stParam);
                if (MyCamera.MV_OK == nRet)
                {
                    _Gain = stParam.fCurValue;
                }

                nRet = myCamera.MV_CC_GetFloatValue_NET("ResultingFrameRate", ref stParam);
                if (MyCamera.MV_OK == nRet)
                {
                    _ResultingFrameRate = stParam.fCurValue;
                }
            }
            catch (Exception ex)
            {
                //PCZDLogHelper.Error("获取相机参数发生异常", ex);
            }
        }

        /// <summary>
        /// 保存参数
        /// 0-- 成功  1--失败
        /// </summary>
        /// <param name="exTime">曝光时间</param>
        /// <param name="gain">增益</param>
        /// <param name="fRate">频率</param>
        /// <returns></returns>
        public BaseResult SetCameraParam(float exTime, float gain, float fRate)
        {
            try
            {
                myCamera.MV_CC_SetEnumValue_NET("ExposureAuto", 0);
                int nRet = myCamera.MV_CC_SetFloatValue_NET("ExposureTime", exTime);
                if (nRet != MyCamera.MV_OK)
                {
                    return new BaseResult(false, $"设置曝光时间错误,参数【{exTime}】");
                }

                myCamera.MV_CC_SetEnumValue_NET("GainAuto", 0);
                nRet = myCamera.MV_CC_SetFloatValue_NET("Gain", gain);
                if (nRet != MyCamera.MV_OK)
                {
                    return new BaseResult(false, $"设置增益错误,参数【{gain}】");
                }

                nRet = myCamera.MV_CC_SetFloatValue_NET("AcquisitionFrameRate", fRate);
                if (nRet != MyCamera.MV_OK)
                {
                    return new BaseResult(false, $"设置频率错误,参数【{fRate}】");
                }
                return BaseResult.Successed;
            }
            catch (Exception ex)
            {
                //PCZDLogHelper.Error("设置相机参数发生异常", ex);
                return BaseResult.Failed;
            }
        }

        /// <summary>
        /// 软触发一次
        /// 注意:软触发采集图像需要将相机设置为触发模式,并设置触发源为soft。
        /// </summary>
        /// <param name="triggerString">TriggerSoftware</param>
        /// <returns></returns>
        public BaseResult SoftTrigger(string triggerString = "TriggerSoftware")
        {
            int temp = myCamera.MV_CC_SetCommandValue_NET(triggerString);
            if (MyCamera.MV_OK != temp)
                return BaseResult.Failed;
            return BaseResult.Successed;
        }

        /// <summary>
        /// 设置图像宽度
        /// </summary>
        /// <param name="width">设置Int型参数</param>
        /// <returns></returns>
        public BaseResult SetWidth(uint width)
        {
            int temp = myCamera.MV_CC_SetIntValue_NET("Width", width);
            if (MyCamera.MV_OK != temp)
                return BaseResult.Failed;
            return BaseResult.Successed;
        }


        /// <summary>
        /// 获取图像宽度
        /// </summary>
        /// <returns></returns>
        public uint GetWidth()
        {
            if (myCamera == null)
                return 0;
            MyCamera.MVCC_INTVALUE stParam = new MyCamera.MVCC_INTVALUE();
            int temp = myCamera.MV_CC_GetIntValue_NET("Width", ref stParam);
            if (MyCamera.MV_OK == temp)
                return stParam.nCurValue;
            return 0;
        }

        /// <summary>
        /// 设置触发事件
        /// </summary>
        /// <param name="TriggerMode"> 1:On 触发模式 0:Off 非触发模式</param>
        /// <returns></returns>
        public BaseResult SetTriggerMode(uint TriggerMode)
        {
            int temp = myCamera.MV_CC_SetEnumValue_NET("TriggerMode", TriggerMode);
            if (MyCamera.MV_OK != temp)
                return BaseResult.Failed;
            return BaseResult.Successed;
        }

        /// <summary>
        /// 设置触发源(方式)
        /// 0 - Line0;
        /// 1 - Line1;
        /// 2 - Line2;
        /// 3 - Line3;
        /// 4 - Counter;
        /// 7 - Software;
        /// </summary>
        /// <param name="way">  0 - Line0; 1 - Line1;2 - Line2; 3 - Line3; 4 - Counter;7 - Software;</param>
        /// <returns></returns>
        public BaseResult SetTriggerWay(uint way)
        {
            int temp = myCamera.MV_CC_SetEnumValue_NET("TriggerSource", way);
            if (MyCamera.MV_OK != temp)
                return BaseResult.Failed;
            return BaseResult.Successed;
        }

        /// <summary>
        /// 设置曝光时间(us),成功返回0失败返回-1
        /// </summary>
        /// <param name="ExposureTime">曝光时间(us)</param>
        /// <returns></returns>
        public BaseResult SetExposureTime(uint ExposureTime)
        {
            int temp = myCamera.MV_CC_SetFloatValue_NET("ExposureTime", ExposureTime);
            if (MyCamera.MV_OK != temp)
                return BaseResult.Failed;
            return BaseResult.Successed;
        }



        /// <summary>
        /// 设置心跳时间,成功返回0失败返回-1
        /// </summary>
        /// <param name="heartBeatTime"></param>
        /// <returns></returns>
        public BaseResult SetHeartBeatTime(uint heartBeatTime)
        {
            //心跳时间最小为500
            uint tempTime = heartBeatTime > 500 ? heartBeatTime : 500;
            int temp = myCamera.MV_CC_SetIntValue_NET("GevHeartbeatTimeout", tempTime);
            if (MyCamera.MV_OK != temp)
                return BaseResult.Failed;
            return BaseResult.Successed;
        }

        /// <summary>
        /// 输出一张Bitmap图片
        /// </summary>
        /// <param name="bmp"></param>
        /// <returns></returns>
        public BaseResult SaveBmp(out Bitmap bmp)
        {
            bmp = new Bitmap(1, 1);
            try
            {
                if (!m_bGrabbing)
                {
                    return new BaseResult(false, "未开启采集");
                }

                if (RemoveCustomPixelFormats(m_stFrameInfo.enPixelType))
                {
                    return new BaseResult(false, "自定义像素格式");
                }

                IntPtr pTemp = IntPtr.Zero;
                MyCamera.MvGvspPixelType enDstPixelType = MyCamera.MvGvspPixelType.PixelType_Gvsp_Undefined;
                if (m_stFrameInfo.enPixelType == MyCamera.MvGvspPixelType.PixelType_Gvsp_Mono8 || m_stFrameInfo.enPixelType == MyCamera.MvGvspPixelType.PixelType_Gvsp_BGR8_Packed)
                {
                    pTemp = m_BufForDriver;
                    enDstPixelType = m_stFrameInfo.enPixelType;
                }
                else
                {
                    UInt32 nSaveImageNeedSize = 0;
                    MyCamera.MV_PIXEL_CONVERT_PARAM stConverPixelParam = new MyCamera.MV_PIXEL_CONVERT_PARAM();

                    lock (BufForDriverLock)
                    {
                        if (m_stFrameInfo.nFrameLen == 0)
                        {
                            return new BaseResult(false, "获取bitmap图像失败");
                        }

                        if (IsMonoData(m_stFrameInfo.enPixelType))
                        {
                            enDstPixelType = MyCamera.MvGvspPixelType.PixelType_Gvsp_Mono8;
                            nSaveImageNeedSize = (uint)m_stFrameInfo.nWidth * m_stFrameInfo.nHeight;
                        }
                        else if (IsColorData(m_stFrameInfo.enPixelType))
                        {
                            enDstPixelType = MyCamera.MvGvspPixelType.PixelType_Gvsp_BGR8_Packed;
                            nSaveImageNeedSize = (uint)m_stFrameInfo.nWidth * m_stFrameInfo.nHeight * 3;
                        }
                        else
                        {
                            return new BaseResult(false, "无效的像素类型");
                        }

                        if (m_nBufSizeForSaveImage < nSaveImageNeedSize)
                        {
                            if (m_BufForSaveImage != IntPtr.Zero)
                            {
                                Marshal.Release(m_BufForSaveImage);
                            }
                            m_nBufSizeForSaveImage = nSaveImageNeedSize;
                            m_BufForSaveImage = Marshal.AllocHGlobal((Int32)m_nBufSizeForSaveImage);
                        }

                        stConverPixelParam.nWidth = m_stFrameInfo.nWidth;
                        stConverPixelParam.nHeight = m_stFrameInfo.nHeight;
                        stConverPixelParam.pSrcData = m_BufForDriver;
                        stConverPixelParam.nSrcDataLen = m_stFrameInfo.nFrameLen;
                        stConverPixelParam.enSrcPixelType = m_stFrameInfo.enPixelType;
                        stConverPixelParam.enDstPixelType = enDstPixelType;
                        stConverPixelParam.pDstBuffer = m_BufForSaveImage;
                        stConverPixelParam.nDstBufferSize = m_nBufSizeForSaveImage;
                        int nRet = myCamera.MV_CC_ConvertPixelType_NET(ref stConverPixelParam);
                        if (MyCamera.MV_OK != nRet)
                        {
                            return new BaseResult(false, "像素类型转换失败");
                        }
                        pTemp = m_BufForSaveImage;
                    }
                }

                lock (BufForDriverLock)
                {
                    if (enDstPixelType == MyCamera.MvGvspPixelType.PixelType_Gvsp_Mono8)
                    {
                        //Mono8 转 Bitmap
                        bmp = new Bitmap(m_stFrameInfo.nWidth, m_stFrameInfo.nHeight, m_stFrameInfo.nWidth * 1, PixelFormat.Format8bppIndexed, pTemp);

                        ColorPalette cp = bmp.Palette;
                        for (int i = 0; i < 256; i++)
                        {
                            cp.Entries[i] = Color.FromArgb(i, i, i);
                        }
                        bmp.Palette = cp;
                        bmp.Save(OpenCV.bmpFile, ImageFormat.Bmp);
                    }
                    else
                    {
                        //BGR8 转 Bitmap
                        try
                        {
                            bmp = new Bitmap(m_stFrameInfo.nWidth, m_stFrameInfo.nHeight, m_stFrameInfo.nWidth * 3, PixelFormat.Format24bppRgb, pTemp);
                            bmp.Save(OpenCV.bmpFile, ImageFormat.Bmp);
                        }
                        catch
                        {
                            return new BaseResult(false, "生成图像失败");
                        }
                    }
                }
                return BaseResult.Successed;
            }
            catch (Exception ex)
            {
                //PCZDLogHelper.Error("保存图像发生异常", ex);
                return new BaseResult(false, "保存图像异常");
            }
        }


        #endregion


        #region 私有方法

        /// <summary>
        /// 获取图像的回调线程
        /// </summary>
        private void ReceiveThreadProcess()
        {
            MyCamera.MVCC_INTVALUE stParam = new MyCamera.MVCC_INTVALUE();
            int nRet = myCamera.MV_CC_GetIntValue_NET("PayloadSize", ref stParam);
            if (MyCamera.MV_OK != nRet)
            {
                return;
            }

            UInt32 nPayloadSize = stParam.nCurValue;
            if (nPayloadSize > m_nBufSizeForDriver)
            {
                if (m_BufForDriver != IntPtr.Zero)
                {
                    Marshal.Release(m_BufForDriver);
                }
                m_nBufSizeForDriver = nPayloadSize;
                m_BufForDriver = Marshal.AllocHGlobal((Int32)m_nBufSizeForDriver);
            }

            if (m_BufForDriver == IntPtr.Zero)
            {
                return;
            }

            MyCamera.MV_FRAME_OUT_INFO_EX stFrameInfo = new MyCamera.MV_FRAME_OUT_INFO_EX();
            MyCamera.MV_DISPLAY_FRAME_INFO stDisplayInfo = new MyCamera.MV_DISPLAY_FRAME_INFO();

            while (m_bGrabbing)
            {
                try
                {
                    lock (BufForDriverLock)
                    {
                        nRet = myCamera.MV_CC_GetOneFrameTimeout_NET(m_BufForDriver, nPayloadSize, ref stFrameInfo, 1000);
                        if (nRet == MyCamera.MV_OK)
                        {
                            m_stFrameInfo = stFrameInfo;
                        }
                    }

                    if (nRet == MyCamera.MV_OK)
                    {
                        if (RemoveCustomPixelFormats(stFrameInfo.enPixelType))
                        {
                            continue;
                        }
                        if (image_handle != IntPtr.Zero)
                        {
                            stDisplayInfo.hWnd = image_handle;
                        }
                        stDisplayInfo.pData = m_BufForDriver;
                        stDisplayInfo.nDataLen = stFrameInfo.nFrameLen;
                        stDisplayInfo.nWidth = stFrameInfo.nWidth;
                        stDisplayInfo.nHeight = stFrameInfo.nHeight;
                        stDisplayInfo.enPixelType = stFrameInfo.enPixelType;
                        myCamera.MV_CC_DisplayOneFrame_NET(ref stDisplayInfo);

                        Bitmap bmp = null;
                        if (stDisplayInfo.enPixelType == MyCamera.MvGvspPixelType.PixelType_Gvsp_Mono8)
                        {
                            //Mono8 转 Bitmap
                            bmp = new Bitmap(m_stFrameInfo.nWidth, m_stFrameInfo.nHeight, m_stFrameInfo.nWidth * 1, PixelFormat.Format8bppIndexed, stDisplayInfo.pData);

                            ColorPalette cp = bmp.Palette;
                            for (int i = 0; i < 256; i++)
                            {
                                cp.Entries[i] = Color.FromArgb(i, i, i);
                            }
                            bmp.Palette = cp;
                            //bmp.Save("image.bmp", ImageFormat.Bmp);
                        }
                        else
                        {
                            //BGR8 转 Bitmap
                            try
                            {
                                bmp = new Bitmap(m_stFrameInfo.nWidth, m_stFrameInfo.nHeight, m_stFrameInfo.nWidth * 3, PixelFormat.Format24bppRgb, stDisplayInfo.pData);
                                //bmp.Save("image.bmp", ImageFormat.Bmp);
                            }
                            catch
                            {
                                bmp = null;
                            }
                        }
                        if (bmp != null)
                            OnReceiveImage?.Invoke(bmp);
                    }
                    else
                    {
                        Thread.Sleep(5);
                    }
                }
                catch (Exception ex)
                {

                }
                finally
                {
                    Thread.Sleep(0);
                }
            }
        }


        /// <summary>
        /// 去除自定义的像素格式 
        /// </summary>
        /// <param name="enPixelFormat"></param>
        /// <returns></returns>
        private bool RemoveCustomPixelFormats(MyCamera.MvGvspPixelType enPixelFormat)
        {
            Int32 nResult = ((int)enPixelFormat) & (unchecked((Int32)0x80000000));
            if (0x80000000 == nResult)
            {
                return true;
            }
            else
            {
                return false;
            }
        }

        /// <summary>
        /// 判断是否为黑白图像
        /// </summary>
        /// <param name="enGvspPixelType"></param>
        /// <returns></returns>
        private Boolean IsMonoData(MyCamera.MvGvspPixelType enGvspPixelType)
        {
            switch (enGvspPixelType)
            {
                case MyCamera.MvGvspPixelType.PixelType_Gvsp_Mono8:
                case MyCamera.MvGvspPixelType.PixelType_Gvsp_Mono10:
                case MyCamera.MvGvspPixelType.PixelType_Gvsp_Mono10_Packed:
                case MyCamera.MvGvspPixelType.PixelType_Gvsp_Mono12:
                case MyCamera.MvGvspPixelType.PixelType_Gvsp_Mono12_Packed:
                    return true;
                default:
                    return false;
            }
        }

        /// <summary>
        /// 判断是否彩色照片
        /// </summary>
        /// <param name="enGvspPixelType"></param>
        /// <returns></returns>
        private Boolean IsColorData(MyCamera.MvGvspPixelType enGvspPixelType)
        {
            switch (enGvspPixelType)
            {
                case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerGR8:
                case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerRG8:
                case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerGB8:
                case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerBG8:
                case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerGR10:
                case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerRG10:
                case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerGB10:
                case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerBG10:
                case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerGR12:
                case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerRG12:
                case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerGB12:
                case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerBG12:
                case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerGR10_Packed:
                case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerRG10_Packed:
                case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerGB10_Packed:
                case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerBG10_Packed:
                case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerGR12_Packed:
                case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerRG12_Packed:
                case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerGB12_Packed:
                case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerBG12_Packed:
                case MyCamera.MvGvspPixelType.PixelType_Gvsp_RGB8_Packed:
                case MyCamera.MvGvspPixelType.PixelType_Gvsp_YUV422_Packed:
                case MyCamera.MvGvspPixelType.PixelType_Gvsp_YUV422_YUYV_Packed:
                case MyCamera.MvGvspPixelType.PixelType_Gvsp_YCBCR411_8_CBYYCRYY:
                    return true;

                default:
                    return false;
            }
        }

        #endregion

    }

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2284260.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

MySQL 二进制安装(正式篇)

Author&#xff1a;Arsen Date&#xff1a;2025/01/24 官方参考文档&#xff1a;点击链接跳转 目录 规划下载安装管理FAQ 规划 OSMySQL Server Version备注CentOS 7.9 or Linux - Generic8.0.33(GNU libc) 2.17 下载 二进制包下载地址&#xff1a;https://downloads.mysql.…

K8S部署DevOps自动化运维平台

持续集成&#xff08;CI&#xff09; 持续集成强调开发人员提交了新代码之后&#xff0c;立刻自动的进行构建、&#xff08;单元&#xff09;测试。根据测试结果&#xff0c;我 们可以确定新代码和原有代码能否正确地集成在一起。持续集成过程中很重视自动化测试验证结果&#…

工业相机 SDK 二次开发-Sherlock插件

本文介绍了 sherlock 连接相机时的插件使用。通过本套插件可连接海康的工业相机。 一&#xff0e;环境配置 1. 拷贝动态库 在用户安装 MVS 目录下按照如下路径 Development\ThirdPartyPlatformAdapter 找到目 录为 DalsaSherlock 的文件夹&#xff0c;根据 Sherlock 版本找到…

分布式版本控制系统:Git

1 Git概述 Git官网&#xff1a;https://git-scm.com/ Git是一个免费的、开源的分布式版本控制系统&#xff0c;可以快速高效地处理从小型到大型的各种项目Git易于学习&#xff0c;占地面积小&#xff0c;性能极快。它具有廉价的本地库、方便的暂存区域和多个工作流分支等特性…

C语言编程笔记:文件处理的艺术

大家好&#xff0c;这里是小编的博客频道 小编的博客&#xff1a;就爱学编程 很高兴在CSDN这个大家庭与大家相识&#xff0c;希望能在这里与大家共同进步&#xff0c;共同收获更好的自己&#xff01;&#xff01;&#xff01; 本文目录 引言正文一、为什么要用文件二、文件的分…

如何编写一个MyBatis插件?

大家好&#xff0c;我是锋哥。今天分享关于【Redis为什么这么快?】面试题。希望对大家有帮助&#xff1b; 如何编写一个MyBatis插件&#xff1f; 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 编写 MyBatis 插件需要使用 MyBatis 提供的插件接口&#xff0c;MyBa…

C语言初阶牛客网刷题—— HJ34 图片整理【难度:中等】

1. 题目描述 牛客网在线OJ链接 Lily上课时使用字母数字图片教小朋友们学习英语单词&#xff0c;每次都需要把这些图片按照大小&#xff08;ASCII码值从小到大&#xff09;排列收好。请大家给Lily帮忙&#xff0c;通过C语言解决。 输入描述&#xff1a;Lily使用的图片包括 “A…

Golang Gin系列-7:认证和授权

在本章中&#xff0c;我们将探讨Gin框架中身份验证和授权的基本方面。这包括实现基本的和基于令牌的身份验证&#xff0c;使用基于角色的访问控制&#xff0c;应用中间件进行授权&#xff0c;以及使用HTTPS和漏洞防护保护应用程序。 实现身份认证 Basic 认证 Basic 认证是内置…

CVE-2025-0411 7-zip 漏洞复现

文章目录 免责申明漏洞描述影响版本漏洞poc漏洞复现修复建议 免责申明 本文章仅供学习与交流&#xff0c;请勿用于非法用途&#xff0c;均由使用者本人负责&#xff0c;文章作者不为此承担任何责任 漏洞描述 此漏洞 &#xff08;CVSS SCORE 7.0&#xff09; 允许远程攻击者绕…

学习数据结构(1)时间复杂度

1.数据结构和算法 &#xff08;1&#xff09;数据结构是计算机存储、组织数据的方式&#xff0c;指相互之间存在⼀种或多种特定关系的数据元素的集合 &#xff08;2&#xff09;算法就是定义良好的计算过程&#xff0c;取一个或一组的值为输入&#xff0c;并产生出一个或一组…

算法每日双题精讲 —— 二分查找(寻找旋转排序数组中的最小值,点名)

&#x1f31f;快来参与讨论&#x1f4ac;&#xff0c;点赞&#x1f44d;、收藏⭐、分享&#x1f4e4;&#xff0c;共创活力社区。 &#x1f31f; 别再犹豫了&#xff01;快来订阅我们的算法每日双题精讲专栏&#xff0c;一起踏上算法学习的精彩之旅吧&#x1f4aa; 在算法的…

STM32-时钟树

STM32-时钟树 时钟 时钟

算法知识补充2

一部分&#xff1a;Tire树&#xff1a;高效地存储和查找字符串集合的数据结构acwing835 #include<iostream> #include<cstring> using namespace std; const int N100010; int son[N][26],cnt[N],idx; char str[N]; void insert(char str[]){int p0;for(int i0;st…

微信小程序-点餐(美食屋)02开发实践

目录 概要 整体架构流程 &#xff08;一&#xff09;用户注册与登录 &#xff08;二&#xff09;菜品浏览与点餐 &#xff08;三&#xff09;订单管理 &#xff08;四&#xff09;后台管理 部分代码展示 1.index.wxml 2.list.wxml 3.checkout.wxml 4.detail.wxml 小结优点 概要…

WPF基础 | WPF 常用控件实战:Button、TextBox 等的基础应用

WPF基础 | WPF 常用控件实战&#xff1a;Button、TextBox 等的基础应用 一、前言二、Button 控件基础2.1 Button 的基本定义与显示2.2 按钮样式设置2.3 按钮大小与布局 三、Button 的交互功能3.1 点击事件处理3.2 鼠标悬停与离开效果3.3 按钮禁用与启用 四、TextBox 控件基础4.…

CentOS7使用源码安装PHP8教程整理

CentOS7使用源码安装PHP8教程整理 下载安装包解压下载的php tar源码包安装所需的一些依赖扩展库安装前的配置修改配置文件1、进入php8的安装包 配置环境变量开机自启启动服务创建软连接常见问题1、checking for icu-uc > 50.1 icu-io icu-i18n... no2、configure: error: Pa…

08-Elasticsearch

黑马商城作为一个电商项目&#xff0c;商品的搜索肯定是访问频率最高的页面之一。目前搜索功能是基于数据库的模糊搜索来实现的&#xff0c;存在很多问题。 首先&#xff0c;查询效率较低。 由于数据库模糊查询不走索引&#xff0c;在数据量较大的时候&#xff0c;查询性能很…

SQL在DBA手里-改写篇

背景 最近运营需要做月报汇总交易情况&#xff0c;之前一直是他们手工出的数据&#xff0c;他们想做成月初自动发送邮件&#xff0c;从而减轻他们的工作量。于是他们提供SQL我们在邮件服务器配置做定时发送任务。 表介绍&#xff08;表及字段已做脱敏处理&#xff09; trans…

企业财务管理系统的需求设计和实现

该作者的原创文章目录&#xff1a; 生产制造执行MES系统的需求设计和实现 企业后勤管理系统的需求设计和实现 行政办公管理系统的需求设计和实现 人力资源管理HR系统的需求设计和实现 企业财务管理系统的需求设计和实现 董事会办公管理系统的需求设计和实现 公司组织架构…

Couchbase UI: Server

在 Couchbase UI 中的 Server&#xff08;服务器&#xff09;标签页主要用于管理和监控集群中的各个节点。以下是 Server 标签页的主要内容和功能介绍&#xff1a; 1. 节点列表 显示集群中所有节点的列表&#xff0c;每个节点的详细信息包括&#xff1a; 节点地址&#xff1…