ReelCheckCamera.cs 12.6 KB
using AOI;
using OnlineStore.Common;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using System.Text;
using System.Threading;
using System.Windows.Forms;

namespace DeviceLibrary
{
    public class ReelCheckCamera
    {

        public static Dictionary<string, IntPtr> CamerHandleMap { get; set; } = null;

        static object grabLoc = new object();
        static string IPCameraServiceIP = ConfigHelper.Config.Get("IPCamera_ServiceIp", "localhost");
        static int IPCameraServicePort = ConfigHelper.Config.Get("IPCamera_ServicePort", 8088);
        public static bool GrabOneImg(string camerName, out Bitmap bitmap, out string imgPath)
        {
            bitmap = null;
            imgPath = "";
            //   if (Monitor.TryEnter(grabLoc, 500))
            // {
            try
            {
                bitmap = null;
                string url = $"http://{IPCameraServiceIP}:{IPCameraServicePort}/cam/grabOneImg?camName={camerName}";
                string result = HttpHelper.Get(url);
                if (!string.IsNullOrEmpty(result))
                {
                    var res = JsonHelper.DeserializeJsonToObject<Result>(result);

                    if (res != null && res.code == 0)
                    {
                        using (FileStream fs = new FileStream(res.msg, FileMode.Open, FileAccess.Read))
                        {
                            bitmap = (Bitmap)Bitmap.FromStream(fs);
                            imgPath = res.msg;
                            return true;
                        }

                    }
                    else
                    {
                        LogUtil.LOGGER.Error($"{camerName} 图像采集失败");
                    }
                }
                else
                {
                    LogUtil.LOGGER.Error($"{camerName} 图像采集失败");
                }
            }
            finally
            { //Monitor.Exit(grabLoc);
            }

            //}
            //else
            //{
            //    LogUtil.LOGGER.Warn("GrabOneImg 未得到锁");
            //}
            return false;

            //if (!VideoManager.IsOpen(camerName))
            //{
            //    LogUtil.info($"CameraManager  相机{camerName}还未打开,打开相机  ");
            //    VideoManager.Open(CamerHandleMap);
            //}

            //if (!VideoManager.IsOpen(camerName))
            //{

            //    LogUtil.info($"CameraManager  相机{camerName} 打开失败  ");
            //    return false;
            //}

            //return VideoManager.GrabOneImg(camerName, out bitmap);
            return true;
        }

        public static bool CheckIPServiceAlive()
        {
            try
            {
                string url = $"http://{IPCameraServiceIP}:{IPCameraServicePort}/isAlive";
                string result = HttpHelper.Get(url);
                if (!string.IsNullOrEmpty(result))
                {
                    var res = JsonHelper.DeserializeJsonToObject<Result>(result);

                    if (res != null && res.code == 0)
                    {
                        return true;

                    }
                }

            }
            catch (Exception ex)
            {

            }

            return false;

        }
        public static void CloseIPService()
        {
            try
            {
                string url = $"http://{IPCameraServiceIP}:{IPCameraServicePort}/closeApp";
                HttpHelper.Get(url, Encoding.UTF8);

            }
            catch (Exception ex)
            {

            }

        }
        static Stream BitMapToStream(Bitmap bitmap)
        {
            try
            {
                using (MemoryStream ms = new MemoryStream())
                {
                    BinaryFormatter bf = new BinaryFormatter();
                    bf.Serialize(ms, bitmap);
                    return ms;
                }
            }
            catch (Exception e)
            {
                LogUtil.LOGGER.Error("BitMapToStream", e);
            }
            return null;
        }
        public static void Close()
        {
            //VideoManager.Close();
        }
        private static Dictionary<string, AoiProject> aoiProjectMap = new Dictionary<string, AoiProject>();

        private static AoiProject GetAOIProject(string projectName, string machineSide)
        {
            try
            {
                string key = $"{machineSide.ToString()}-{projectName}";
                if (!aoiProjectMap.ContainsKey(key))
                {

                    string path = Application.StartupPath + $"\\Config\\{machineSide}\\{projectName}";
                    AoiProject aoiProject = AoiProject.Load(path, out string msg);

                    if (aoiProject == null || msg != "")
                    {
                        LogUtil.LOGGER.Error("加载 AoiProject  " + path + " 失败:" + msg);

                        return null;
                    }
                    else
                    {
                        LogUtil.LOGGER.Info("加载 AoiProject  " + path);
                        aoiProjectMap.Add(key, aoiProject);
                    }
                }

                return aoiProjectMap[key];

            }
            catch (Exception e)
            {
                LogUtil.LOGGER.Error("GetAOIProject 出错: " + e.ToString());
            }
            return null;
        }

        public static void ClearProject()
        {
            if (aoiProjectMap != null && aoiProjectMap.Count > 0)
            {
                aoiProjectMap.Clear();
                LogUtil.info("重置 AoiProject");
            }
        }
        static bool autoStart = ConfigHelper.Config.Get($"IPCamera_AutoStartIPCamera", true);

        static object aoiLoc = new object();
        /// <summary>
        /// 检测是否有料
        /// </summary>
        /// <param name="cameraName"></param>
        /// <param name="projectName"></param>
        /// <returns>true:有料</returns>
        public static bool AOICheck(string deviceName, string projectName, string machineSide, out string resList)
        {
            resList = "";
            string cameraName= ConfigHelper.Config.Get($"IPCamera_CameraName", "cam1");
            if (!ConfigHelper.Config.Get("IPCamera_EnableAOI", false))
            {
                //无料
                return false;
            }
            if (Monitor.TryEnter(aoiLoc, 3000))
            {
                Bitmap bitmap = null;
                try
                {
                    if (autoStart)
                    {
                        if (!CheckIPServiceAlive())
                        {
                            CloseIPService();
                            Thread.Sleep(1000);
                            string baseDir = Application.StartupPath + @"\Modules\";
                            WindowManager.Start();
                            LogUtil.error("监控相机未启动,启动相机");
                            return true;
                        }
                    }
                    else if (!CheckIPServiceAlive())
                    {
                        //RobotManage.mainMachine.ShowMsg("检测到监控相机未启动", MsgLevel.warning);
                    }
                    bool result = GrabOneImg(cameraName, out _, out string imgPath);
                    if (result && !string.IsNullOrEmpty(imgPath))
                    {
                        AoiProject project = GetAOIProject(projectName, machineSide);
                        if (project != null)
                        {
                            using (FileStream fs = new FileStream(imgPath, FileMode.Open, FileAccess.Read))
                            {
                                bitmap = (Bitmap)Bitmap.FromStream(fs);
                                if (bitmap != null)
                                {
                                    List<ResultBean> resultBean = project.CheckAll(bitmap, out Image outImage);
                                    bool checkResult = true;
                                    string ngList = deviceName + " AOICheck: " + cameraName + $",{machineSide.ToString()}," + projectName + ",结果: ";
                                    foreach (ResultBean bean in resultBean)
                                    {
                                        ngList += GetShowName(bean) + "\r\n";
                                        if (bean.result.Equals(false))
                                        {
                                            checkResult = false;
                                        }
                                    }
                                    resList = ngList;
                                    LogUtil.LOGGER.Info(ngList);
                                    if (!checkResult)//有料
                                    {
                                        SaveImageToFile("", cameraName, bitmap,"有料", true);
                                    }
                                    else
                                    {
                                        SaveImageToFile("", cameraName, bitmap, "无料", true);
                                    }
                                    //检测失败返回有料
                                    return !checkResult;
                                }
                                else
                                {
                                    LogUtil.LOGGER.Error(deviceName + " AOICheck: " + cameraName + "." + projectName + $", 加载[{imgPath}]图片失败");
                                    return true;
                                }
                            }
                        }
                        else
                        {

                            LogUtil.LOGGER.Error(deviceName + " AOICheck: " + cameraName + "." + projectName + ",  获取AOIProject失败");
                        }
                    }
                    else
                    {
                        LogUtil.LOGGER.Error(deviceName + " AOICheck: " + cameraName + "." + projectName + ", 获取图片失败");
                    }
                }
                catch (Exception e)
                {
                    LogUtil.LOGGER.Error(deviceName + " AOICheck", e);
                }
                finally
                {
                    bitmap?.Dispose();
                    Monitor.Exit(aoiLoc);
                }
            }

            return true;
        }
        static string SaveImageToFile(string deviceName, string cameraName, Bitmap bitmap,string result, bool deleteCcnt = false)
        {
            string date = DateTime.Now.ToString("HH-mm-ss-") + DateTime.Now.Millisecond+"-"+result;
            string dire = @"\image\aoi\" + deviceName.Trim().Replace('_', '-') + @"\" + cameraName.Trim().Replace('_', '-').Replace(':', '-') + @"\";
            string iamgeName = date + ".bmp";
            try
            {
                if (Directory.Exists(dire).Equals(false))
                {
                    Directory.CreateDirectory(dire);
                }
                int delCnt = ConfigHelper.Config.Get("IPCamera_aoi检测有料图片保存数量", 300);
                if (Directory.GetFiles(dire).Length > delCnt)
                {
                    if (deleteCcnt)
                        Directory.Delete(dire, true);
                }
                bitmap.Save(dire + iamgeName, ImageFormat.Jpeg);
                //bitmap.Dispose();
                LogUtil.info(deviceName + "  【" + cameraName + "】扫码完成,保存图片到【" + dire + iamgeName + "】成功");

            }
            catch (Exception ex)
            {
                LogUtil.error("保存" + deviceName + "  【" + cameraName + "】的图片到【" + dire + iamgeName + "】出错" + ex.ToString());
            }
            return dire + iamgeName;
        }
        private static string GetShowName(ResultBean bean)
        {
            return (bean.result ? "✔ " : "✘ ") + bean.MethodName + $"({bean.percentValue}%)";
        }
    }

    class Result
    {
        /// <summary>
        /// 状态码,0为正常
        /// </summary>
        public int code { get; set; } = 0;
        /// <summary>
        /// 返回数据
        /// </summary>
        public Dictionary<string, string> data
        {
            get { return _data; }
            set { _data = value; }
        }
        private Dictionary<string, string> _data = new Dictionary<string, string>();
        /// <summary>
        /// 提示信息
        /// </summary>
        public string msg { get; set; } = "ok";
    }
}