CodeManager.cs 14.3 KB
using CodeLibrary;
using OnlineStore.Common;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Runtime.ExceptionServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace OnlineStore.DeviceLibrary
{
    public class CodeManager
    {
        public static List<string> codeTypeList = new List<string>();
        public static List<string> balserNameList = new List<string>();
        public static List<string> hikNameList = new List<string>();

        private static char spiltChar = '#';
        /// <summary>
        /// 初始化摄像机名称和二维码类型
        /// </summary> 
        public static void LoadConfig()
        {
            string codeStr = ConfigAppSettings.GetValue(Setting_Init.CodeType);
            codeTypeList = new List<string>();
            HDLogUtil.LogName = "RollingLogFileAppender";
            try
            {
                string[] codeArray = codeStr.Split(spiltChar);
                foreach (string str in codeArray)
                {
                    if (str.Trim().Equals(""))
                    {
                        continue;
                    }
                    LogUtil.info("加载到配置二维码类型:" + str.Trim());
                    codeTypeList.Add(str.Trim());
                }

                LoadCamera(false);
                CodeLibrary.HDCodeLearnHelper.LoadConfig("", codeStr);
            }
            catch (Exception ex)
            {
                LogUtil.error("解析摄像机配置出错:", ex);
            }
        }
        private static void LoadCamera(bool isReLoad)
        {
            string[] names = null;

            if (isReLoad || Camera._cam == null)
            {
                try
                {
                    if (Camera._cam != null)
                    {
                        Camera._cam.CloseAll();
                    }
                    Camera.Type = CameraType.HIK;
                    Camera._cam.Load();
                    names = Camera._cam.Name;
                }
                catch (Exception ex)
                {
                    LogUtil.error("加载HIK相机出错:", ex);
                }
            }

            //string[] names = Camera._cam.Name;

            if (names != null)
            {
                foreach (string n in names)
                {
                    if (!hikNameList.Contains(n))
                    {
                        hikNameList.Add(n);
                    }
                }
                // hikNameList.AddRange(names);
                foreach (string name in hikNameList)
                {
                    LogUtil.info("加载到HIK相机:" + name);
                }
            }
        }

        public static void CloseCamera(string cameraName)
        {
            Camera._cam.Close(cameraName);
        }
        public static void CloseAllCamera()
        {
            Camera._cam.CloseAll();
        }
        public static List<string> CameraScan(string cameraName, string deviceName, bool findRightCodeBreak = false)
        {
            int timeOut = ConfigAppSettings.GetIntValue(Setting_Init.CodeTimeOut,6000);
            List<string> nameList = new List<string>() { cameraName };
            return CameraScan(nameList, deviceName, findRightCodeBreak, timeOut);
        }
        private static int ScanCount = 0;
        private static int codeCount = ConfigAppSettings.GetIntValue(Setting_Init.CodeCount);
        [HandleProcessCorruptedStateExceptions]
        public static List<string> CameraScan(List<string> cameraList, string deviceName, bool findRightCodeBreak = false, int timeOut = 1500)
        {
            bool isPreScan = deviceName.EndsWith("预扫码");
            isPreScan = false;
            List<string> codeList = new List<string>();
            if (cameraList == null || cameraList.Count <= 0)
            {
                return codeList;
            }
            try
            {
                foreach (string cameraName in cameraList)
                {
                    if (cameraName.Trim().Equals(""))
                    {
                        continue;
                    }
                    ScanCount++;
                    DateTime startTime = DateTime.Now;
                    if (deviceName != "")
                    {
                        LogUtil.debug(deviceName + " 【" + cameraName + "】开始取图片");
                    }
                    Bitmap bmp = null;
                    HalconDotNet.HObject ho_Image = null;
                    bool findRightCode = false;
                    try
                    {
                        ho_Image = Camera._cam.CaptureOnImage(cameraName, out bmp);
                        if (ho_Image == null)
                        {
                            LogUtil.error(deviceName + "  【" + cameraName + "】取图片失败[" + Camera._cam.ErrInfo + "],关闭相机");
                            CloseCamera(cameraName);
                            continue;
                        }

                        LogUtil.debug(deviceName + "  【" + cameraName + "】取图片完成,开始扫码");

                        string r = "";
                        Task eyemtask = Task.Factory.StartNew(delegate
                        {
                            RemoteDecodeHelper.RemoteDecodeParam remoteDecodeParam = new RemoteDecodeHelper.RemoteDecodeParam
                            {
                                codeTypeList = codeTypeList.ToArray(),
                                codeCount = codeCount,
                                timeout = timeOut
                            };
                            List<CodeInfo> tlci = new List<CodeInfo>();

                            tlci = RemoteDecodeHelper.DecodeRequest(bmp, remoteDecodeParam);
                            foreach (CodeInfo code in tlci)
                            {
                                string str = CodeManager.ReplaceCode(code.CodeStr);
                                if (!codeList.Contains(str))
                                {
                                    codeList.Add(str);
                                    r = r + "##remote|" + code.CodeType + "|" + str;
                                    if (!findRightCode)
                                    {
                                        findRightCode = HasRightCode(str);
                                    }
                                }
                            }
                        });
                        //最多等待60秒
                        bool taskResult = eyemtask.Wait(60000);
                        if (!taskResult)
                        {
                            LogUtil.error(deviceName + "  【" + cameraName + "】扫码超时");
                        }

                        if (!findRightCode)
                        {
                            SaveImageToFile(deviceName, cameraName, bmp);
                        }

                        if (deviceName != "" || r != "")
                        {
                            LogUtil.info(deviceName + " 【" + cameraName + "】扫码完成【" + FormUtil.GetSpanStr(DateTime.Now - startTime) + "】[" + findRightCode + "]" + ScanCount + " :" + r);
                        }
                    }
                    catch (AccessViolationException e)
                    {
                        LogUtil.error(deviceName + " 扫码出现AccessViolationException异常,关闭相机【" + cameraName + "】:" + e.ToString());
                        Camera._cam.Close(cameraName);
                        //  GC.Collect();
                    }
                    catch (Exception ex)
                    {
                        LogUtil.error(deviceName + " 扫码出错:" + ex.ToString());
                    }
                    finally
                    {
                        if (ho_Image != null)
                        {
                            ho_Image.Dispose();
                            ho_Image = null;
                        }
                        // GC.Collect();
                        Task.Delay(10);
                    }
                }

            }
            catch (AccessViolationException e)
            {
                LogUtil.error(deviceName + " 扫码出现AccessViolationException异常,关闭所有相机:" + e.ToString());
                Camera._cam.CloseAll();
                //GC.Collect();
            }
            catch (Exception ex)
            {
                LogUtil.error(deviceName + " 扫码出错:" + ex.ToString());
            }
            return codeList;
        }
        private static int SaveErrorImageToFile = ConfigAppSettings.GetIntValue(Setting_Init.SaveErrorImageToFile);

        //private static void SaveImageToFile(string deviceName, string cameraName, HalconDotNet.HObject bitmap)
        //{
        //    string date = deviceName.Trim().Replace('_', '-') + "-" + DateTime.Now.ToString("yyyyMMdd-HHmmss") + "-" + DateTime.Now.Millisecond.ToString().PadLeft(4, '0');
        //    string dire = @"D:\image\" + deviceName.Trim().Replace('_', '-') + @"\" + cameraName.Trim().Replace('_', '-').Replace(':', '-') + @"\";
        //    string imageName = date + ".bmp";
        //    try
        //    {
        //        if (!Directory.Exists(dire))
        //        {
        //            Directory.CreateDirectory(dire);
        //        }

        //        bitmap.WriteObject(dire + imageName);
        //        LogUtil.info(deviceName + "  【" + cameraName + "】扫码失败,保存图片到【" + dire + imageName + "】成功");
        //    }
        //    catch (Exception ex)
        //    {
        //        LogUtil.error("保存" + deviceName + "  【" + cameraName + "】的图片到【" + dire + imageName + "】出错" + ex.ToString());
        //    }
        //}
        private static void SaveImageToFile(string deviceName, string cameraName, Bitmap bitmap)
        {
            string date = deviceName.Trim().Replace('_', '-') + "-" + DateTime.Now.ToString("yyyyMMdd-HHmmss-") + DateTime.Now.Millisecond;
            string dire = @"D:\image\" + deviceName.Trim().Replace('_', '-') + @"\" + cameraName.Trim().Replace('_', '-').Replace(':', '-') + @"\";
            string imageName = date + ".bmp";
            try
            {
                Bitmap bit = (Bitmap)bitmap.Clone();
                if (Directory.Exists(dire).Equals(false))
                {
                    Directory.CreateDirectory(dire);
                }
                bit.Save(dire + imageName, ImageFormat.Bmp);
                LogUtil.info(deviceName + "  【" + cameraName + "】扫码失败,保存图片到【" + dire + imageName + "】成功");
            }
            catch (Exception ex)
            {
                LogUtil.error("保存" + deviceName + "  【" + cameraName + "】的图片到【" + dire + imageName + "】出错" + ex.ToString());
            }
        }

        public static bool HasRightCode(params string[] codes)
        {
            //640104 * 3331001202 * 210417624 * 600 * 0011
            //分号分割后长度=4,L,E,B,R 
            //TJM211030000146 & 10446500228 & 15000 & 2021 - 06 - 28 & 59K0646169 && 10446 && R02472021102600281
            // RI & PN & QTY & 4 & BATCH & 5 & 6 & 7 & 8
            //     RI & PN & QTY & PRODATEyyyy - MM - dd & 5 & 6 & 7 & 8 & 9
            try
            {
                foreach (string code in codes)
                {
                    string[] strarray = code.Split('&');
                    if (strarray.Length >= 5)
                    {
                        try
                        {
                            if (strarray[0].StartsWith("TJM"))
                            {
                                return true;
                            }

                            int QTY = Convert.ToInt32(strarray[2].Trim());
                            if (QTY > 0)
                            {
                                return true;
                            }
                        }
                        catch (Exception ex)
                        {
                            return false;
                        }

                    }
                }
            }
            catch (Exception ex)
            {
            }
            return false;
        }
        static string codeParampath = ConfigAppSettings.GetValue(Setting_Init.CodeParamPath);
        public static string GetCodeParamFilePath(string codePath)
        {
            string appPath = Application.StartupPath;
            string path = appPath + codeParampath;
            string filePath = path + codePath + ".dcm";
            if (File.Exists(filePath))
            {
                return filePath;
            }
            else
            {
                return "";
            }
        }
        /// <summary>
        /// 处理接收后的二维码
        /// </summary>
        /// <param name="message"></param>
        /// <returns></returns>
        public static string ReplaceCode(string message)
        {
            message = message.Trim();
            message = message.Replace("\r", "");
            message = message.Replace("\n", "");
            char a = (char)02;
            message = message.Replace(a.ToString(), "");
            message = message.Trim();
            System.Text.ASCIIEncoding asciiEncoding = new System.Text.ASCIIEncoding();
            byte[] bytes = asciiEncoding.GetBytes(message);
            List<byte> newBytes = new List<byte>();
            foreach (byte by in bytes)
            {
                int value = (int)by;
                if (value.Equals(24) || value.Equals(30) || value.Equals(29) || value.Equals(4))
                {
                    continue;
                }
                if (!value.Equals(24))
                {
                    newBytes.Add(by);
                }
            }
            message = asciiEncoding.GetString(newBytes.ToArray());
            return message;
        }
        public static string ProcessCode(List<string> codeList)
        {
            string code = "";
            foreach (string cc in codeList)
            {
                if (string.IsNullOrEmpty(cc))
                {
                    continue;
                }
                code += cc + "##";
            }
            return ReplaceCode(code);
        }
    }
}